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.6 卷积为何有效 Convolutions over volumes
你已经知道如何对二维图像做卷积了,现在看看如何执行卷积不仅仅在二维图像上,而是三维立体上。
我们从一个例子开始。
如上图。假如你不仅想检测灰度图像的特征,也想检测RGB彩色图像的特征。彩色图像如果是6×6×3,这里的3指的是三个颜色通道,你可以把它想象成三个6×6图像的堆叠。为了检测图像的边缘或者其他的特征,不是把它跟原来的3×3的过滤器做卷积,而是跟一个三维的过滤器,它的维度是3×3×3,这个过滤器也有三层,对应红绿、蓝三个通道。
给这些图像起个名字,第一个6代表图像高度height,第二个6代表宽度width,这个3代表通道的数目channels。同样你的过滤器也有一个高,宽和通道数,并且图像的通道数必须和过滤器的通道数匹配,所以这两个数(上图中紫色方框标记的两个数)必须相等。
最后的输出会是一个4×4的图像,注意是4×4×1,最后一个数不是3了。
我们研究下这背后的细节。
如上图,首先先换一张好看的图片。左边是6×6×3的图像,中间是3×3×3的过滤器,最后一个数字通道数必须和过滤器中的通道数相匹配。为了简化这个3×3×3过滤器的图像,我们不把它画成3个矩阵的堆叠,而画成一个三维的立方体。
为了计算这个卷积操作的输出,你要做的就是把这个3×3×3的过滤器先放到最左上角的位置,如上图那样,这个3×3×3的过滤器有27个数,27个参数就是3的立方。依次取这27个数,然后乘以相应的红绿蓝通道中的数字。先取红色通道的前9个数字,然后是绿色通道,然后再是蓝色通道,乘以左边黄色立方体覆盖的对应的27个数,然后把这些数都加起来,就得到了输出的第一个数字。
如果要计算下一个输出,你把这个立方体滑动一个单位,再与这27个数相乘,把它们都加起来,就得到了下一个输出,以此类推。
那么,这个能干什么呢?
举个例子,如果你想检测图像红色通道的边缘,那么你可以将第一个过滤器设为
[
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⎦⎤,和之前一样,而绿色和蓝色通道全为0,
[
0
0
0
0
0
0
0
0
0
]
\begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & 0 \\0 & 0 & 0 \\ \end{bmatrix}
⎣⎡000000000⎦⎤。如果你把这三个堆叠在一起形成一个3×3×3的过滤器,那么这就是一个检测垂直边界的过滤器,但只对红色通道有用。
或者如果你不关心垂直边界在哪个颜色通道里,那么你可以用一个这样的过滤器, [ 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⎦⎤, [ 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⎦⎤, [ 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⎦⎤,所有三个通道都是这样。通过设置第二个过滤器参数,你就有了一个边界检测器,3×3×3的边界检测器,用来检测任意颜色通道里的边界。参数的选择不同,你就可以得到不同的特征检测器,所有的都是3×3×3的过滤器。
按照计算机视觉的惯例,当你的输入有特定的高宽和通道数时,你的过滤器可以有不同的高,不同的宽,但是必须一样的通道数。理论上,我们的过滤器只关注红色通道,或者只关注绿色或者蓝色通道也是可行的。
再来总结一下,一个6×6×6的输入图像卷积上一个3×3×3的过滤器,得到一个4×4的二维输出。
同时使用多个过滤器
现在你已经了解了如何对立方体卷积,还有最后一个概念,对建立CNN至关重要。就是,如果我们不仅仅想要检测垂直边缘怎么办?如果我们同时检测垂直边缘和水平边缘,还有45°倾斜的边缘,还有70°倾斜的边缘怎么做?换句话说,如果你想同时用多个过滤器怎么办?
观察上图。
step1:让这个6×6×3的图像和黄色3×3×3的过滤器卷积(例如垂直边缘检测器),得到第一个4×4的输出。
step2:然后和橘色3×3×3的过滤器卷积(例如水平边缘检测器),得到第二个不同的4×4的输出。
step3:接着把这两个4×4的输出,取第一个把它放到前面,然后取第二个过滤器输出,放到后面。把这两个输出堆叠在一起,这样你就都得到了一个4×4×2的输出立方体。这里的2来源于我们用了两个不同的过滤器。
我们总结一下维度。
如果你有一个 n n n x n n n x n c n_c nc(通道数)的输入图像,在上面例子中就是6×6×3,然后卷积上一个 f f f x f f f x n c n_c nc的过滤器,上面例子中是3×3×3,按照惯例,2个 n c n_c nc必须数值相同。然后你就得到了 ( n − f + 1 ) (n - f +1) (n−f+1) x ( n − f + 1 ) (n - f +1) (n−f+1) x n c n_c nc’ ,这里 n c n_c nc’ 其实就是下一层的通道数,它就是你用的过滤器的个数。在我们的例子中,卷积结果就是4×4×2。上例中假设用的步幅为1,并且没有padding。如果你用了不同的步幅或者padding,那么 ( n − f + 1 ) (n - f +1) (n−f+1) 这个数值会变化,正如前面的课程演示的那样。
这个对立方体卷积的概念真的很有用,你现在可以用它的一小部分直接在三个通道的RGB图像上进行操作。更重要的是,你可以检测两个特征,比如垂直和水平边缘或者10个或者128个或者几百个不同的特征,并且输出的通道数会等于你要检测的特征数。
对于这里的符号,我一直用通道数( n c n_c nc)来表示最后一个维度,在文献里大家也把它叫做3维立方体的深度。
这两个术语,即通道
或者深度
,经常被用在文献中。但我觉得深度容易让人混淆,因为你通常也会说NN的深度。所以,在课程里我会用通道这个术语来表示过滤器的第三个维度的大小。