1.视频网站:mooc慕课https://mooc.study.163.com/university/deeplearning_ai#/c
2.详细笔记网站(中文):http://www.ai-start.com/dl2017/
3.github课件+作业+答案:https://github.com/stormstone/deeplearning.ai
1.3 更多边缘检测内容 More edge detection
上节课你已经见识到用卷积运算实现垂直边缘检测。
在本节课中,你将学习如何区分正边和负边,这实际就是由亮到暗与由暗到亮的区别,也就是边缘的过渡
。你还能了解到其他类型的边缘检测以及如何去实现这些算法,而不要总想着去自己编写一个边缘检测程序,让我们开始吧。
上图还是上节课的例子。左边这张6×6的图片,左边较亮,而右边较暗,将它与中间的垂直边缘检测滤波器进行卷积,检测结果就显示在了右边这幅图的中间部分。
观察上图,现在这幅图有什么变化呢?
它的颜色被翻转了,变成了左边比较暗,而右边比较亮。现在亮度为10的点跑到了右边,为0的点则跑到了左边。如果你用它与相同的过滤器进行卷积,最后得到的图中间会是-30,而不是30。
如果你将矩阵转换为图片,就会是该矩阵下面图片的样子。现在中间的过渡部分被翻转了,之前的30翻转成了-30,表明是由暗向亮过渡,而不是由亮向暗过渡。
如果你不在乎这两者的区别,你可以取出右边矩阵的绝对值。但这个特定的过滤器确实可以为我们区分这两种明暗变化的区别。
再来看看更多的边缘检测的例子。
我们已经见过上图左边这个3×3的过滤器,它可以检测出垂直的边缘。所以,看到右边这个过滤器,我想你应该猜出来了,它能让你检测出水平的边缘。提醒一下,一个垂直边缘过滤器是一个3×3的区域,它的左边相对较亮,而右边相对较暗。相似的,右边这个水平边缘过滤器也是一个3×3的区域,它的上边相对较亮,而下方相对较暗。
观察上图,这里还有个更复杂的例子。左上方和右下方都是亮度为10的点。如果你将它绘成图片,右上角和左下角是比较暗的地方,这边都是亮度为0的点,我把这些比较暗的区域都加上阴影。而左上方和右下方都会相对较亮。如果你用这幅图与水平边缘过滤器卷积,就会得到右边这个矩阵。
再举个例子。
上图右边矩阵中绿色方框标记元素是30(第二行第一列),代表了左边这块3×3的区域(左边矩阵绿色方框标记部分
[
10
10
10
10
10
10
0
0
0
]
\begin{bmatrix} 10 & 10 & 10\\ 10 & 10 & 10\\ 0 & 0 & 0\\ \end{bmatrix}
⎣⎡101001010010100⎦⎤)。
这块区域(绿色框)确实是上边比较亮,而下边比较暗的,所以它在这里发现了一条正边缘。
而右边矩阵中紫色方框标记元素里的-30(第二行第四列),又代表了左边另一块区域(左边矩阵紫色方框标记部分
[
0
0
0
0
0
0
10
10
10
]
\begin{bmatrix} 0 & 0 & 0\\ 0 & 0 & 0\\ 10 & 10 & 10\\ \end{bmatrix}
⎣⎡001000100010⎦⎤),这块区域确实是底部比较亮,而上边则比较暗,所以在这里它是一条负边。
再次强调,我们现在所使用的都是相对很小的图片,仅有6×6。但上图右边矩阵中间这些数值,比如说这个10(右边矩阵中黄色方框标记元素,第二行第二列),代表的是左边矩阵这块区域(左边6×6矩阵中黄色方框标记的部分 [ 10 10 0 10 10 0 0 0 10 ] \begin{bmatrix} 10 & 10 & 0\\ 10 & 10 & 0\\ 0 & 0 & 10\\ \end{bmatrix} ⎣⎡10100101000010⎦⎤)。这块区域左边两列是正边,右边一列是负边,正边和负边的值加在一起得到了一个中间值。但假如这个一个非常大的1000×1000的类似这样棋盘风格的大图,就不会出现这些亮度为10的过渡带了,因为图片尺寸很大,这些中间值就会变得非常小。
总而言之,通过使用不同的过滤器,你可以找出垂直的或是水平的边缘。但事实上,对于这个3×3的过滤器来说,我们使用了其中的一种数字组合。
但在历史上,在计算机视觉的文献中,曾公平地争论过怎样的数字组合才是最好的,所以你还可以使用这种: [ 1 0 − 1 2 0 − 2 1 0 − 1 ] \begin{bmatrix} 1 & 0 & -1\\ 2 & 0 & -2\\ 1 & 0 & -1\\ \end{bmatrix} ⎣⎡121000−1−2−1⎦⎤,叫做Sobel的过滤器,它的优点在于增加了中间一行元素的权重,也就是处于图像中央的像素点,这使得结果的鲁棒性会更高一些。
计算机视觉的研究者们也会经常使用其他的数字组合,比如这种: [ 3 0 − 3 10 0 − 10 3 0 − 3 ] \begin{bmatrix} 3 & 0 & -3\\ 10 & 0 & -10\\ 3 & 0 & -3\\ \end{bmatrix} ⎣⎡3103000−3−10−3⎦⎤,这叫做Scharr过滤器。它有着和之前完全不同的特性,实际上也是一种垂直边缘检测,如果你将其翻转90度,你就能得到对应水平边缘检测。
随着深度学习的发展,我们学习的其中一件事就是当你真正想去检测出复杂图像的边缘,你不一定要去使用那些研究者们所选择的这九个数字,但你可以从中获益匪浅。把这矩阵中的9个数字当成9个参数,并且在之后你可以学习使用反向传播算法,其目标就是去理解这9个参数。
当你得到上图左边这个6×6的图片,将其与这个3×3的过滤器进行卷积,将会得到一个出色的边缘检测。
在下节课中将会看到的,把这9个数字当成参数的过滤器,通过反向传播,你可以学习 [ 1 0 − 1 1 0 − 1 1 0 − 1 ] \begin{bmatrix} 1 & 0 & -1\\ 1 & 0 & -1\\ 1 & 0 & -1\\ \end{bmatrix} ⎣⎡111000−1−1−1⎦⎤这种的过滤器,或者Sobel过滤器和Scharr过滤器。
还有另一种过滤器,这种过滤器对于数据的捕捉能力甚至可以胜过任何之前这些手写的过滤器。相比这种单纯的垂直边缘和水平边缘,它可以检测出45°或70°或73°,甚至是任何角度的边缘。
所以将矩阵的所有数字都设置为参数,通过数据反馈,让NN自动去学习它们,我们会发现NN可以学习一些低级的特征,例如这些边缘的特征。尽管比起那些研究者们,我们要更费劲一些,但确实可以动手写出这些东西。
不过构成这些计算的基础依然是卷积运算,使得反向传播算法能够让NN学习任何它所需要的3×3的过滤器,并在整幅图片上去应用它。例如上图左边矩阵每一个蓝色方框标记部分,去输出到右边矩阵,任何它所检测到的特征,不管是垂直的边缘,水平的边缘,还有其他奇怪角度的边缘,甚至是其它的连名字都没有的过滤器。
这种将这9个数字当成参数的思想,已经成为计算机视觉中最为有效的思想之一。