机器学习是无数应用的基础,包括网页搜索,对抗垃圾邮件,语音识别,产品推荐及许多其它应用。假设你或者你的团队正在使用机器学习,并且希望快速取得进展。这本书将会帮助到你。
假设你正在成立一家创业公司给爱猫人士提供无穷无尽的猫咪图片。你使用神经网络来建立一个计算机视觉系统用于检测图片种的猫。
但是悲剧的是你的学习算法准确度不够高。你面临着很大的压力来改善猫咪检测准确度。你应该怎么做?
你的团队提出了很多想法,比如:
如果你能从这些方向中做出正确的选择,你的公司会成为一家领先的猫咪图片平台并走向成功。如果你选择错误,可能浪费了公司几个月的时间。你应该怎么做?
这本书会告诉你怎么做。大部分的机器学习问题都有一些线索告诉你哪些尝试是游泳的,哪些是没用的。学会阅读这些线索会节省你几个月甚至几年的开发时间。
Until recently, machine learning (ML) or neural networks (NN) are mainly used in high level vision tasks, such as image segmentation, object recognition and detection. Low level image processing such as denoising, demosaicing, white balance still mainly rely on signal processing based methods which uses expert designed filters. There are usually a long list of filters in the whole processing pipeline which is run on a dedicated ISP chip. In the past one or two years, there are two new trends. One trend is that more and more researchers propose to apply NN for low level image processing and achieved fascinating performance in term of image quality and processing speed. The other trend is that neural network chip becomes more and more popular at various mobile platform, such as the latest Apple A11 Bionic chip and Huawei Kirin 970 chip. I believe in the near further, NN based methods will play important roles at some low level image processing tasks also some ISP chip may include some NN computing units.
This is a personal collection of works using neural networks for low level image processing. The list will be regularly updated. You are welcome to contribute. Papers of significance are marked in bold. My comments are marked in italic.
For a up-to-date list, please follow this github repository.
From the publications, we can find that Adobe has done a lot of work pushing the usage of machine learning in low-level image processing especially automatic photo adjustment.
Super-resolution is one of the areas that NN has been applied extensively and achieved great success.
TODO:
// Quick sort
void exch(int arr[], int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
int partition(int arr[], int left, int right)
{
// partition
int i = left;
int j = right + 1;
int pivot = arr[left];
while (true)
{
// scan from left to right
while (arr[++i] < pivot)
if (i == right) break;
// scan from right to left
while (arr[--j] > pivot)
if (j == left) break;
if (i > = j) break;
exch(arr, i, j);
}
exch(arr, left, j);
return j;
}
void quickSort(int arr[], int left, int right)
{
if (left >= right) return;
int j = partition(arr, left, right); // partition
quickSort(arr, left, j - 1); // sort left part a[left,...,j -1]
quickSort(arr, j + 1, right); // sort right part a[j+1,...,right]
}
void sort(int arr[], const int len)
{
shuffle(arr); // random shuffle the input
quickSort(arr, 0, len - 1);
}
TODO:
// merge two sorted array
void mergearray(int a[], int n, int b[], int m, int c[])
{
int i = 0;
int j = 0;
int k = 0;
while (i < n && j < m)
{
if (a[i] < b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
}
while (i < n)
c[k++] = a[i++];
while (j < m)
c[k++] = b[j++];
}
The space complexity is O(N), and the time complexity is also O(N).
Top-down recursive based method
// Top-down recursive based method
void merge_sort(int arr[], const int len)
{
int aux[len];
merge_sort_recursive(int arr[], int aux[], 0, len - 1);
}
void merge_sort_recursive(int arr[], int aux[], int begin, int end)
{
int len = end - begin + 1;
int begin1 = begin;
int middle = begin1 + (len>>1) -1;
int end1 = middle;
int start2 = middle + 1;
int end2 = end;
merge_sort_recursive(int a[], int aux[], int begin1, int end1);
merge_sort_recursive(int a[], int aux[], int begin2, int end2);
int k = begin;
while (begin1 <= end1 && begin2 <= end2)
aux[k++] = arr[begin1] < arr[begin2] ? arr[begin1++] : arr[begin2++];
while (begin1 <= end1)
aux[k++] = arr[begin1++];
while (begin2 <= end2)
aux[k++] = arr[begin2++];
for (k = begin; k <= end; k++)
arr[k] = aux[k];
}
Bottom-up iterative based method
// Bottom-up iterative based method
void merge_sort_iterative(int arr[], const int len)
{
int aux = new int[len];
for (int seq = 1; seq < len; seq += seq)
{
for (int begin = 0; begin < len; begin + = seq + seq)
{
int begin1 = begin;
int middle = min(begin0 + seq, len);
int end1 = middle - 1;
int begin2 = middle;
int end2 = begin1 + seq + seq -1;
int k = begin;
while (begin1 < end1 && begin2 < end2)
aux[k++] = arr[begin1] < arr[begin2] ? arr[begin1++] : arr[begin2++];
while (begin1 < end1)
aux[k++] = arr[begin1++];
while (begin2 < end2)
aux[k++] = arr[begin2++];
}
for (int j = 0; j < len; j++)
arr[j] = aux[j];
}
}