Computer Vision中的卷积神经网络(CNN)(基础篇)

引言

计算机视觉是一个飞速发展的一个领域,这多亏了深度学习。深度学习与计算机视觉可以帮助汽车,查明周围的行人和汽车,并帮助汽车避开它们。还使得人脸识别技术变得更加效率和精准,你们即将能够体验到或早已体验过仅仅通过刷脸就能解锁手机或者门锁。当你解锁了手机,我猜手机上一定有很多分享图片的应用。在上面,你能看到美食,酒店或美丽风景的图片。有些公司在这些应用上使用了深度学习技术来向你展示最为生动美丽以及与你最为相关的图片。机器学习甚至还催生了新的艺术类型。

深度学习之所以让我兴奋有下面两个原因:

  • 第一,计算机视觉的高速发展标志着新型应用产生的可能,这是几年前,人们所不敢想象的。通过学习使用这些工具,你也许能够创造出新的产品和应用。
  • 其次,对于计算机视觉的研究衍生出新的神经网络结构与算法,启发人们去创造出计算机视觉与其他领域的交叉成果。

边缘检测

卷积运算是卷积神经网络最基本的组成部分,使用边缘检测作为入门样例。

卷积操作
[ 3 0 1 2 7 4 1 5 8 9 3 1 2 7 2 5 1 3 0 1 3 1 7 8 4 2 1 6 2 8 2 4 5 2 3 9 ] ∗ [ 1 0 − 1 1 0 − 1 1 0 − 1 ] = [ − 5 − 4 0 8 − 10 − 2 2 3 0 − 2 − 4 − 7 − 3 − 2 − 3 − 16 ] \left[\begin{matrix} 3 & 0 & 1 & 2 & 7 & 4 \\ 1 & 5 & 8 & 9 & 3 & 1 \\ 2 & 7 & 2 & 5 & 1 & 3 \\ 0 & 1 & 3 & 1 & 7 & 8 \\ 4 & 2 & 1 & 6 & 2 & 8 \\ 2 & 4 & 5 & 2 & 3 & 9 \\ \end{matrix} \right] * \left[\begin{matrix} 1 & 0 & -1 \\ 1 & 0 & -1 \\ 1 & 0 & -1 \\\end{matrix} \right] = \left[ \begin{matrix} -5 & -4 & 0 & 8\\ -10 & -2 & 2 & 3\\ 0 & -2 & -4 & -7\\-3 & -2 & -3 & -16\\\end{matrix}\right] 312042057124182315295162731723413889111000111=510034222024383716
I n p u t ( 6 ∗ 6 ) → F i l t e r ( 3 ∗ 3 ) → O u t p u t ( 4 ∗ 4 ) Input(6*6) → Filter(3*3) → Output(4*4) Input66Filter33Output44

【Tips】

  • Python :conv_forward
  • Tensorflow : tf.conv2d
  • Keras:Conv2D

Vertical edge detection(垂直边缘检测)



当你用一个 3×3 过滤器进行卷积运算的时候,这个 3×3 的过滤器可视化为下面这个样子,在左边有明亮的像素,然后有一个过渡,0 在中间,然后右边是深色的。卷积运算后,你得到的是右边的矩阵。
如果把最右边的矩阵当成图像,它是这个样子。在中间有段亮一点的区域,对应检查到这个6×6图像中间的垂直边缘。这里的维数似乎有点不正确,检测到的边缘太粗了。因为在这个例子中,图片太小了。如果你用一个 1000×1000的图像,而不是6×6的图片,你会发现其会很好地检测出图像中的垂直边缘。在这个例子中,在输出图像中间的亮处,表示在图像中间有一个特别明显的垂直边缘。
上面的栗子是左边较亮,右边较暗。如果我们互换输入矩阵两端的值,再去做卷积,得到以下结果:

现在这幅图有什么变化呢?它的颜色被翻转了,变成了左边比较暗,而右边比较亮。现在亮度为10 的点跑到了右边,为 0 的点则跑到了左边。如果你用它与相同的过滤器进行卷积,最后得到的图中间会是-30,而不是30。如果你将矩阵转换为图片,就会是该矩阵下面图片的样子。现在中间的过渡部分被翻转了,之前的30 翻转成了-30,表明是由暗向亮过渡,而不是由亮向暗过渡。
如果你不在乎这两者的区别,你可以取出矩阵的绝对值。但这个特定的过滤器确实可以为我们区分这两种明暗变化的区别。

除此以外,我们不光可以检测垂直边缘,也可以检测水平边缘,如下图:
dl3.jpg-18.3kB

举另一个栗子
dl4.jpg-19.2kB

左上方和右下方都是亮度为10的点。如果你将它绘成图片,右上角是比较暗的地方,这边都是亮度为0的点,把这些比较暗的区域都加上阴影。而左上方和右下方都会相对较亮。如果你用这幅图与水平边缘过滤器卷积,就会得到右边这个矩阵。这里的30(右边矩阵中绿色方框标记元素)代表了左边这块3×3的区域(左边矩阵绿色方框标记部分),这块区域确实是上边比较亮,而下边比较暗的,所以它在这里发现了一条正边缘。而这里的-30(右边矩阵中紫色方框标记元素)又代表了左边另一块区域(左边矩阵紫色方框标记部分),这块区域确实是底部比较亮,而上边则比较暗,所以在这里它是一条负边。

再次强调,我们现在所使用的都是相对很小的图片,仅有6×6。但这些中间的数值,比如说这个10(右边矩阵中黄色方框标记元素)代表的是左边这块区域(左边6×6矩阵中黄色方框标记的部分)。这块区域左边两列是正边,右边一列是负边,正边和负边的值加在一起得到了一个中间值。但假如这个一个非常大的1000×1000的类似这样棋盘风格的大图,就不会出现这些亮度为10的过渡带了,因为图片尺寸很大,这些中间值就会变得非常小。

总而言之,通过使用不同的过滤器,你可以找出垂直的或是水平的边缘。但事实上,对于这个3×3的过滤器来说,我们使用了其中的一种数字组合。
比如

  • [ 1 0 − 1 2 0 − 2 1 0 − 1 ] \left[\begin{matrix}1 & 0 & −1\\2 & 0 & −2\\1 & 0 & −1\end{matrix}\right] 121000121叫做Sobel过滤器,它的优点在于增加了中间一行元素的权重,这使得结果的鲁棒性会更高一些。

  • [ 3 0 − 3 10 0 − 10 3 0 − 3 ] \left[\begin{matrix}3 & 0 & −3\\10 & 0 & −10\\3 & 0 & −3 \end{matrix}\right] 31030003103叫做Scharr过滤器,它有着和之前完全不同的特性,实际上也是一种垂直边缘检测,如果你将其翻转90度,你就能得到对应水平边缘检测。

随着深度学习的发展,如果你想要实际检测出复杂图像的边缘,你不一定要去使用那些研究者们所选择的这九个数字,但你可以从中获益匪浅。把这矩阵中的9个数字当成9个参数,并且在之后你可以学习使用反向传播算法,其目标就是去理解这9个参数。
dl4.PNG-49.6kB
把这 9 个数字当成参数的过滤器,通过反向传播,你可以学习刚才提到的垂直边缘过滤器、水平边缘过滤器、Sobel 过滤器和 Scharr 过滤器,也可以学习另外一种可以检测不同角度,比如45°、70°、73°等任何角度的边缘过滤器。

Padding

接着刚才提到的栗子,如果你用一个 3×3 的过滤器卷积一个 6×6 的图像,你最后会得到一个4×4的输出,也就是一个4×4矩阵。那是因为你的 3×3 过滤器在6×6矩阵中,只可能有4×4种可能的位置。这背后的数学解释是,如果我们有一个 n ∗ n n*n nn 的图像,用 f ∗ f f*f ff 的过滤器做卷积,那么输出的维度就是 ( n − f + 1 ) × ( n − f + 1 ) (n-f+1)×(n-f+1) (nf+1)×(nf+1)。在这个例子里是6−3+1=4,因此得到了一个 4×4 的输出。
这样的话会有两个缺点,

  • 第一个缺点:每次做卷积操作,你的图像就会缩小,从 6×6 缩小到 4×4,你可能做了几次之后,你的图像就会变得很小了,可能会缩小到只有1×1的大小。你可不想让你的图像在每次识别边缘或其他特征时都缩小。
  • 第二个缺点:如果你注意角落边缘的像素,这个像素点只被一个输出所触碰或者使用,因为它位于这个 3×3 的区域的一角。但如果是在中间的像素点,就会有许多3×3的区域与之重叠。所以那些在角落或者边缘区域的像素点在输出中采用较少,意味着你丢掉了图像边缘位置的许多信息。

为了解决这些问题,你可以在卷积操作之前填充这幅图像。
在这个案例中,你可以沿着图像边缘再填充一层像素。如果你这样操作了,那么6×6的图像就被你填充成了一个8×8的图像。如果你用3×3的图像对这个8×8的图像卷积,你得到的输出就不是 4×4 的,而是6×6的图像,你就得到了一个尺寸和原始图像6×6的图像。习惯上,你可以用0去填充,如果 p p p是填充的数量,在这个案例中, p = 1 p=1 p=1,因为我们在周围都填充了一个像素点,输出也就变成了 ( n + 2 p − f + 1 ) × ( n + 2 p − f + 1 ) (n+2p−f+1)×(n+2p−f+1) (n+2pf+1)×(n+2pf+1),所以就变成了(6+2×1−3+1)×(6+2×1−3+1)=6×6,和输入的图像一样大。这个涂绿的像素点(左边矩阵)影响了输出中的这些格子(右边矩阵)。这样一来,丢失信息或者更准确来说角落或图像边缘的信息发挥的作用较小的这一缺点就被削弱了。
选择填充多少像素,通常有两个选择,分别叫做 Valid 卷积和 Same 卷积。

  • Valid 卷积:意味着不填充。

这样的话,如果你有一个 n ∗ n n*n nn的图像,用一个 f ∗ f f*f ff的过滤器卷积,它将会给你一个** ( n − f + 1 ) × ( n − f + 1 ) (n-f+1)×(n-f+1) (nf+1)×(nf+1)**维的输出。这类似于我们在前面的视频中展示的例子,有一个6×6的图像,通过一个 3×3 的过滤器,得到一个 4×4 的输出。

  • Same 卷积:那意味你填充后,你的输出大小和输入大小是一样的。

根据这个公式 n − f + 1 n-f+1 nf+1,当你填充 p p p个像素点, n n n就变成了 n + 2 p n+2p n+2p,最后公式变为 n + 2 p − f + 1 n+2p−f+1 n+2pf+1。因此如果你有一个 n ∗ n n*n nn的图像,用 p p p个像素填充边缘,输出的大小是这样的 ( n + 2 p − f + 1 ) × ( n + 2 p − f + 1 ) (n+2p−f+1)×(n+2p−f+1) (n+2pf+1)×(n+2pf+1)。如果你想让 n + 2 p − f + 1 = n n+2p−f+1=n n+2pf+1=n的话,使得输出和输入大小相等,如果你用这个等式求解 p p p,那么 p = ( f − 1 ) / 2 p=(f-1)/2 p=(f1)/2。所以当 f f f是一个奇数的时候,只要选择相应的填充尺寸,你就能确保得到和输入相同尺寸的输出。当过滤器是3×3时,使得输出尺寸等于输入尺寸,所需要的填充是(3-1)/2,也就是1层像素。当你的过滤器是5×5,使得输出尺寸等于输入尺寸,所需要的填充是(5-1)/2,也就是2层像素。

习惯上,计算机视觉中, f f f通常是奇数,甚至可能都是这样。你很少看到一个偶数的过滤器在计算机视觉里使用,可能有以下两个原因。

  • 如果 f f f 是一个偶数,那么你只能使用一些不对称填充。只有 f f f是奇数的情况下,Same卷积才会有自然的填充,我们可以以同样的数量填充四周,而不是左边填充多一点,右边填充少一点,这样不对称的填充。
  • 当你有一个奇数维过滤器,比如 3×3 或者 5×5 的,它就有一个中心点。有时在计算机视觉里,如果有一个中心像素点会更方便,便于指出过滤器的位置。

卷积步长(Strided Convolutions)

在之前的讲的例子中,我们的步长都设置为1,在没有padding的情况下,7x7的输入经过3x3的卷积核之后输出应该为(7-3+1)x(7-3+1),即5x5。
dl5.PNG-132.2kB

当我们把步长s设为2时,我们用 3×3 的矩阵卷积一个 7×7 的矩阵,得到一个 3×3 的输出。
【Tips】如果用一个 f ∗ f f*f ff的过滤器跟一个 n ∗ n n*n nn 的图像做卷积,padding为 p p p,步长为 s s s,那么输出变为 ( n + 2 p − f s + 1 ) ∗ ( n + 2 p − f s + 1 ) (\frac{n+2p-f}{s}+1)*(\frac{n+2p-f}{s}+1) (sn+2pf+1)(sn+2pf+1)
在本例中, n = 7 , f = 3 , p = 0 , s = 2 n=7,f=3,p=0,s=2 n=7,f=3,p=0,s=2,因此输出为3x3。

Question:如果商不是一个整数怎么办?

在这种情况下,我们向下取整。⌊z⌋这是向下取整的符号,这也叫做对z进行地板除(floor),这意味着z向下取整到最近的整数。这个原则实现的方式是,你只在蓝框完全包括在图像或填充完的图像内部时,才对它进行运算。如果有任意一个蓝框移动到了外面,那你就不要进行相乘操作,你的3×3的过滤器必须完全处于图像中或者填充之后的图像区域内才输出相应结果,这是一个惯例。

【注】Technical note on cross-correlation v.s. convolution
如果你看的是一本典型的数学教科书,那么卷积的定义是做元素乘积求和,实际上还有一个步骤是你首先要做的,也就是在把这个 6×6 的矩阵和 3×3的过滤器卷积之前,首先你将3×3的过滤器沿水平和垂直轴翻转,所以 [ 3 4 4 1 0 2 − 1 0 3 ] \left[ \begin{matrix}3 & 4 & 4\\1 & 0 & 2\\-1 & 0 & 3\end{matrix}\right] 311400423变为 [ 3 2 4 0 0 4 − 1 1 3 ] \left[\begin{matrix}3 & 2 & 4\\0 & 0 & 4\\-1 & 1 & 3\end{matrix}\right] 301201443这相当于将 3×3 的过滤器做了个镜像,在水平和垂直轴上。然后你再把这个翻转后的矩阵元素相乘来计算输出的3x3矩阵。

所以我们在这些视频中定义卷积运算时,我们跳过了这个镜像操作。从技术上讲,我们实际上做的,我们在前面视频中使用的操作,有时被称为互相关(cross-correlation)而不是卷积(convolution)。但在深度学习文献中,按照惯例,我们将这(不进行翻转操作)叫做卷积操作。

总结来说,按照机器学习的惯例,我们通常不进行翻转操作。从技术上说,这个操作可能叫做互相关更好。但在大部分的深度学习文献中都把它叫做卷积运算,因此我们将在这些视频中使用这个约定。如果你读了很多机器学习文献的话,你会发现许多人都把它叫做卷积运算,不需要用到这些翻转。事实证明在信号处理中或某些数学分支中,在卷积的定义包含翻转,使得卷积运算符拥有这个性质,即 ( A ∗ B ) ∗ C = A ∗ ( B ∗ C ) (A*B)*C=A*(B*C) (AB)C=A(BC),这在数学中被称为结合律。这对于一些信号处理应用来说很好,但对于深度神经网络来说它真的不重要,因此省略了这个双重镜像操作,就简化了代码,并使神经网络也能正常工作。

三维卷积

通过上面的学习,我们已经初步了解了二维图像的卷积,但是生活中我们遇到的都是彩色的图像,有RGB三个channel,在三维空间我们如何去做卷积呢?
接着举个栗子
假如说你不仅想检测灰度图像的特征,也想检测 RGB 彩色图像的特征。彩色图像如果是 6×6×3,这里的 3 指的是三个颜色通道,你可以把它想象成三个6×6图像的堆叠。为了检测图像的边缘或者其他的特征,不是把它跟原来的3×3的过滤器做卷积,而是跟一个三维的过滤器,它的维度是 3×3×3,这样这个过滤器也有三层,对应红、绿、蓝三个通道。
dl6.PNG-86.3kB
先看输入的6x6x3,这里的第一个6代表图像高度(height),第二个6代表宽度(width),这个3代表通道的数目(channel)。同样你的过滤器也有高、宽和通道数,并且图像的通道数必须和过滤器的通道数匹配,所以这两个数必须相等。这个卷积操作完之后的输出是一个 4×4 的图像,注意是 4×4×1,最后一个数不是3了。

Question: 为什么输出是4x4x1,而不是4x4x3 ?

为了计算这个卷积操作的输出,你要做的就是把这个3×3×3的过滤器先放到最左上角的位置,这个 3×3×3 的过滤器有27个数,27个参数就是 3 的立方。依次取这27个数,然后乘以相应的红绿蓝通道中的数字。先取红色通道的前9个数字,然后是绿色通道,然后再是蓝色通道,乘以左边黄色立方体覆盖的对应的27个数,然后把这些数都加起来,就得到了输出的第一个数字。如果要计算下一个输出,你把这个立方体滑动一个单位,再与这27个数相乘,把它们都加起来,就得到了下一个输出,以此类推。
dl6.jpg-26.5kB

  • 我们还可以利用这个3x3x3的过滤器来检测图像红色通道的边缘,那么你可以将第一个过滤器设为 [ 1 0 − 1 1 0 − 1 1 0 − 1 ] \left[ \begin{matrix}1 & 0 & -1 \\1 & 0 & -1 \\1 & 0 & -1\\\end{matrix}\right] 111000111,而绿色通道全为0,蓝色也全为0。如果你把这三个堆叠在一起形成一个3×3×3的过滤器,那么这就是一个检测垂直边界的过滤器,但只对红色通道有用。

  • 如果你不关心垂直边界在哪个颜色通道里,那么你可以用一个这样的过滤器, [ 1 0 − 1 1 0 − 1 1 0 − 1 ] , [ 1 0 − 1 1 0 − 1 1 0 − 1 ] , [ 1 0 − 1 1 0 − 1 1 0 − 1 ] \left[ \begin{matrix}1 & 0 & -1 \\1 & 0 & -1 \\1 & 0 & -1\\\end{matrix}\right],\left[ \begin{matrix}1 & 0 & -1 \\1 & 0 & -1 \\1 & 0 & -1\\\end{matrix}\right],\left[ \begin{matrix}1 & 0 & -1 \\1 & 0 & -1 \\1 & 0 & -1\\\end{matrix}\right] 111000111,111000111,111000111所有三个通道都是这样。所以通过设置第二个过滤器参数,你就有了一个边界检测器,3×3×3的边界检测器,用来检测任意颜色通道里的边界。参数的选择不同,你就可以得到不同的特征检测器,所有的都是 3×3×3 的过滤器。
    按照计算机视觉的惯例,当你的输入有特定的高宽和通道数时,你的过滤器可以有不同的高,不同的宽,但是必须一样的通道数。理论上,我们的过滤器只关注红色通道,或者只关注绿色或者蓝色通道也是可行的。

  • Multiple filters

  • 如果我们不仅仅想要检测垂直边缘怎么办?

  • 如果我们同时检测垂直边缘和水平边缘,还有45°倾斜的边缘,还有70°倾斜的边缘怎么做?

  • 如果你想同时用多个过滤器怎么办?
    dl7.PNG-106.8kB

第一个过滤器(黄色)是一个垂直边界检测器或者是学习检测其他的特征,第二个过滤器(橘色)是一个水平边缘检测器。和第一个过滤器卷积,可以得到第一个4×4x1的输出,然后卷积第二个过滤器,得到一个不同的4×4x1的输出。然后把这两个输出堆叠在一起,这样你就得到了一个4×4×2的输出立方体。换句话说我们对于一个6×6×3的图像,分别用两个不同的3×3的过滤器做卷积,得到两个不同的4×4x1输出,再它们堆叠在一起,形成一个4×4×2的立方体。

总结一下,如果你有一个 n ∗ n ∗ n c n*n*n_c nnnc(通道数)的输入图像,在这个例子中就是 6×6×3,这里的 n c n_c nc就是通道数目,然后卷积上一个 f ∗ f ∗ n c f*f*n_c ffnc,这个例子中是3x3x3,按照惯例,前一个 n c n_c nc 和后一个 n c n_c nc 要数值相等,然后得到了 ( n − f + 1 ) ∗ ( n − f + 1 ) ∗ n c ′ (n-f+1)*(n-f+1)*n_c' (nf+1)(nf+1)nc,这里的 n c ′ n_c' nc 其实就是下一层的通道数,它就是你用的过滤器的个数,在本例中,那就是4×4×2。我写下这个假设时,用的步幅为 1,并且没有padding。

单层卷积网络(One layer of a convolutional network)

刚才我们我们已经通过两个过滤器卷积处理一个三维图像,并输出两个不同的4×4矩阵。假设使用第一个过滤器进行卷积,得到第一个4×4 矩阵。使用第二个过滤器进行卷积得到另外一个4×4 矩阵。最终各自形成一个卷积神经网络层,然后增加偏差,它是一个实数,通过Python的广播机制给第一个4x4矩阵的16个元素都加上同一偏差。然后应用非线性函数,为了说明,它是一个非线性激活函数ReLU,输出结果是一个4×4矩阵。对于第二个4x4矩阵添加上不同的偏差,它也是一个实数,16个数字都加上同一个实数,然后应用非线性函数,也就是一个非线性激活函数ReLU,最终得到另一个 4×4矩阵。然后重复我们之前的步骤,把这两个矩阵堆叠起来,最终得到一个4×4×2 的矩阵。
dl7.jpg-18kB
由此,我们通过计算,就把从6×6×3 的输入推导出一个4×4×2 矩阵,它是卷积神经网络的一层,把它映射到标准神经网络中四个卷积层中的某一层或者一个非卷积神经网络中。

前向传播中 z [ 1 ] = W [ 1 ] a [ 0 ] + b [ 1 ] z^{[1]}=W^{[1]}a^{[0]}+b^{[1]} z[1]=W[1]a[0]+b[1],其中 a [ 0 ] = x a^{[0]}=x a[0]=x,通过非线性函数g得到 a [ 1 ] a^{[1]} a[1],即 a [ 1 ] = g ( z [ 1 ] ) a^{[1]}=g(z^{[1]}) a[1]=g(z[1])
a [ 0 ] a^{[0]} a[0] a [ 1 ] a^{[1]} a[1]的演变过程,首先执行线性函数,然后所有元素相乘做卷积,具体做法是运用线性函数再加上偏差,再应用激活函数如ReLU。这样就通过神经网络的一层把一个6×6×3 的维度 a [ 0 ] a^{[0]} a[0]演化为一个4×4×2维度的 a [ 1 ] a^{[1]} a[1],这就是卷积神经网络的一层。
示例中我们有两个过滤器,也就是有两个特征,因此我们才最终得到一个 4×4×2 的输出。但如果我们用了 10 个过滤器,而不是 2 个,我们最后会得到一个4×4×10维度的输出图像,因为我们选取了其中 10 个特征映射,而不仅仅是2个,将它们堆叠在一起,形成一个4×4×10 的输出图像,也就是 a [ 1 ] a^{[1]} a[1]

Question:假设你有10个过滤器,每一个都是 3×3×3,那么,这一层有多少个参数呢?

每个过滤器有3x3x3=27个参数,然后加上一个偏差,用参数b表示,现在参数增加到28个。现在我们有10个过滤器,加在一起是28×10,也就是 280 个参数。请注意一点,不论输入图片有多大,1000×1000也好,5000×5000也好,参数始终都是280个。用这10个过滤器来提取特征,如垂直边缘,水平边缘和其它特征。即使这些图片很大,参数却很少,这就是卷积神经网络的一个特征,叫作“避免过拟合”。

Summary of Notation
描述卷积神经网络中的一层(以 l l l层为例),也就是卷积层的各种标记。

  • f [ l ] = f i l t e r s i z e f^{[l]}=filter size f[l]=filtersize

  • p [ l ] = p a d d i n g p^{[l]}=padding p[l]=padding

  • s [ l ] = s t r i d e s^{[l]}=stride s[l]=stride

  • I n p u t : n H [ l − 1 ] ∗ n W [ l − 1 ] ∗ n C [ l − 1 ] Input:n^{[l-1]}_H*n^{[l-1]}_W*n^{[l-1]}_C InputnH[l1]nW[l1]nC[l1] ( l l l层的输入就是上一层的输出,所以用 [ l − 1 ] [l-1] [l1])
    O u t p u t : n H [ l ] ∗ n W [ l ] ∗ n C [ l ] Output:n^{[l]}_H*n^{[l]}_W*n^{[l]}_C OutputnH[l]nW[l]nC[l]

    • 根据之前提到的公式得到由 n H [ l − 1 ] n^{[l-1]}_H nH[l1]推导 n H [ l ] n^{[l]}_H nH[l]以及 n W [ l − 1 ] n^{[l-1]}_W nW[l1]推导 n W [ l ] n^{[l]}_W nW[l]的过程。
      • n H [ l ] = ⌊ n H [ l − 1 ] + 2 p [ l ] − f [ l ] s [ l ] + 1 ⌋ n^{[l]}_H=⌊\frac{n^{[l-1]}_H+2p^{[l]}-f^{[l]}}{s^{[l]}}+1 ⌋ nH[l]=s[l]nH[l1]+2p[l]f[l]+1
      • n W [ l ] = ⌊ n W [ l − 1 ] + 2 p [ l ] − f [ l ] s [ l ] + 1 ⌋ n^{[l]}_W=⌊\frac{n^{[l-1]}_W+2p^{[l]}-f^{[l]}}{s^{[l]}}+1 ⌋ nW[l]=s[l]nW[l1]+2p[l]f[l]+1
  • n C [ l ] = n u m b e r   o f   f i l t e r s n^{[l]}_C = number\ of\ filters nC[l]=number of filters

  • E a c h   f i l t e r   i s : f [ l ] ∗ f [ l ] ∗ n C [ l − 1 ] Each\ filter\ is :f^{[l]}*f^{[l]}*n^{[l-1]}_C Each filter is:f[l]f[l]nC[l1] (过滤器中输出通道的数量必须与输入通道的数量一致)

  • A c t i v a t i o n s : a [ l ] → n H [ l ] ∗ n W [ l ] ∗ n C [ l ] Activations :a^{[l]} →n^{[l]}_H*n^{[l]}_W*n^{[l]}_C Activationsa[l]nH[l]nW[l]nC[l]

当你执行批量梯度下降或小批量梯度下降时,如果有 m m m个例子,就是有 m m m个激活值的集合,那么输出 A [ l ] = m ∗ n H [ l ] ∗ n W [ l ] ∗ n C [ l ] A^{[l]}= m*n^{[l]}_H*n^{[l]}_W*n^{[l]}_C A[l]=mnH[l]nW[l]nC[l]

  • W e i g h t s : f [ l ] ∗ f [ l ] ∗ n C [ l − 1 ] ∗ n C [ l ] Weights:f^{[l]}*f^{[l]}*n^{[l-1]}_C*n^{[l]}_C Weightsf[l]f[l]nC[l1]nC[l]
  • B i a s : 1 ∗ 1 ∗ 1 ∗ n C [ l ] Bias:1*1*1* n^{[l]}_C Bias111nC[l]

小测试:一个简单卷积网络参数的计算

EXERCISE
根据下图给出的参数自己计算每一层的输出

dl8.PNG-10.4kB

正确的输出结果见下图

dl9.PNG-18.4kB

池化层(Pooling Layers)

除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性.

  • Max Pooling
    dl10.PNG-29.2kB
    假如输入是一个 4×4 矩阵,用到的池化类型是最大池化(max pooling)。最大池化只是计算神经网络某一层的静态属性,执行最大池化的树池是一个2×2矩阵。执行过程非常简单,把4×4的输入拆分成不同的区域,每个区域用不同颜色来标记。对于2×2的输出,输出的每个元素都是其对应颜色区域中的最大元素值。这就像是应用了一个规模为2的过滤器,因为我们选用的是2×2区域,步幅是2,这些就是最大池化的超参数。

dl11.PNG-43.4kB

人们使用最大池化的主要原因是此方法在很多实验中效果都很好,其中一个有意思的特点就是,它有一组超参数,但并没有参数需要学习。实际上,梯度下降没有什么可学的,一旦确定了?和?,它就是一个固定运算,梯度下降无需改变任何值。

再看一个输入时5x5矩阵的Max pooling的例子,过滤器参数为3x3,步长为1,即f=3,s=1,输出为3x3。
dl10.jpg-33.3kB

以上就是一个二维输入的最大池化的演示,如果输入是三维的,那么输出也是三维的。例如,输入是 5×5×2,那么输出是 3×3×2。

  • Average Pooling
    dl10.PNG-29.2kB
    对于刚才4x4的矩阵来说,我们换一种pooling方式,改求Average Pooling。
    选取的不是每个过滤器的最大值,而是平均值。示例中,紫色区域的平均值是 3.75,后面依次是 1.25、4和2。这个平均池化的超级参数f=2,s=2,我们也可以选择其它超级参数.
    dl12.PNG-37.1kB
    目前来说,最大池化比平均池化更常用。但也有例外,就是深度很深的神经网络,你可以用平均池化来分解规模为7×7×1000的网络的表示层,在整个空间内求平均值,得到1×1×1000。但在神经网络中,最大池化要比平均池化用得更多。

  • 总结一下,池化的超级参数包括过滤器大小 f f f 和步幅 s s s,常用的参数值为 f = 2 , s = 2 f=2,s=2 f=2s=2,应用频率非常高,其效果相当于高度和宽度缩减一半。也有使用 f = 3 , s = 2 f=3,s=2 f=3s=2 的情况。至于其它超级参数就要看你用的是最大池化还是平均池化了。你也可以根据自己意愿增加表示padding的其他超级参数,虽然很少这么用。大部分情况下,最大池化很少用padding。需要注意的一点是,池化过程中没有需要学习的参数。执行反向传播时,反向传播没有参数适用于最大池化。只有这些设置过的超参数,可能是手动设置的,也可能是通过交叉验证设置的。

卷积神经网络示例 (Convolutional neural network example)

假设,有一张大小为32×32×3的输入图片,这是一张RGB模式的图片,你想做手写体数字识别。32×32×3的 RGB 图片中含有某个数字,比如 7,你想识别它是从 0-9 这 10 个数字中的哪一个,我们构建一个神经网络来实现这个功能。
构造这个网络模型和经典网络 LeNet-5 非常相似,灵感也来源于此。LeNet-5 是很多年前 Yann LeCun创建的,在这里所采用的模型并不是LeNet-5,但是受它启发,许多参数选择都与LeNet-5 相似。

dl13.PNG-31kB

  • 输入是 32×32×3 的矩阵,假设第一层使用过滤器大小为 5×5,步幅是 1,padding
    是 0,过滤器个数为 6,那么输出为 28×28×6。将这层标记为 CONV1,它用了 6 个过滤器,增加了偏差,应用了非线性函数,可能是 ReLU 非线性函数,最后输出 CONV1 的结果。
  • 然后构建一个池化层,这里选择用最大池化,参数 f = 2 , s = 2 f=2,s=2 f=2s=2,因为padding为 0,我就不写出来了。现在开始构建池化层,最大池化使用的过滤器为2×2,步幅为 2,表示层的高度和宽度会减少一半。因此,28×28变成了14×14,通道数量保持不变,所以最终输出为 14×14×6,将该输出标记为 POOL1。

我们发现在卷积神经网络文献中,卷积有两种分类,这与所谓层的划分存在一致性。
- 一类卷积是一个卷积层和一个池化层一起作为一层,这就是神经网络的Layer1。
- 另一类卷积是把卷积层作为一层,而池化层单独作为一层。
一般情况下,人们在计算神经网络有多少层时,通常只统计具有权重和参数的层。因为池化层没有权重和参数,只有一些超参数。这里,我们把CONV1和POOL1共同作为一个卷积,并标记为 Layer1。

  • 对 Layer1 应用另一个卷积层,过滤器为 5×5,即 f = 5 f=5 f=5,步幅 s = 1 s=1 s=1,padding 为 0,所以这里省略了,过滤器 16 个,所以 CONV2 输出为 10×10×16。
  • 继续执行做大池化计算,参数 f = 2 , s = 2 f=2,s=2 f=2s=2,输入为10×10×16,高度和宽度减半,结果为 5×5×16,通道数和之前一样,标记为 POOL2。这是一个卷积,即 Layer2,因为它只有一个权重集和一个卷积层 CONV2。
  • 5×5×16 矩阵包含 400个元素,现在将POOL2平整化为一个大小为400的一维向量。我们可以把平整化结果想象成这样的一个神经元集合,然后利用这 400 个单元构建下一层。
  • 下一层含有 120 个单元,这就是我们第一个全连接层,标记为 FC3。这 400 个单元与 120 个单元紧密相连,这就是全连接层。它的权重矩阵为 W [ 3 ] W^{[3]} W[3],维度为 120×400。这就是所谓的“全连接”,因为这400个单元与这120个单元的每一项连接,还有一个偏差参数。最后输出 120 个维度,因为有 120 个输出。
  • 然后我们对这个 120 个单元再添加一个全连接层,这层更小,只含有 84 个单元,标记为 FC4。
  • 最后,用这 84 个单元填充一个softmax单元。如果我们想通过手写数字识别来识别手写 0-9 这 10 个数字,这个 softmax 就会有 10 个输出。

随着神经网络深度的加深,高度 n H n_H nH和宽度 n W n_W nW通常都会减少,从 32×32 到 28×28,到 14×14,到10×10,再到5×5。所以随着层数增加,高度和宽度都会减小,而通道数量会增加,从3到6到16不断增加,然后得到一个全连接层。

在神经网络中,另一种常见模式就是一个或多个卷积后面跟随一个池化层,然后一个或多个卷积层后面再跟一个池化层,然后是几个全连接层,最后是一个softmax。这是神经网络的另一种常见模式。

下面来看下上述神经网络结构的激活值形状,激活值大小和参数数量。

dl14.PNG-96kB

有几点要注意,**第一,池化层没有参数;第二,卷积层的参数相对较少,其实许多参数都存在于神经网络的全连接层。**观察可发现,随着神经网络的加深,激活值尺寸会逐渐变小,如果激活值尺寸下降太快,也会影响神经网络性能。示例中,激活值尺寸在第一层为6000,然后减少到1600,慢慢减少到84,最后输出softmax结果。我们发现,许多卷积网络都具有这些属性,模式上也相似。

为什么使用卷积?(Why convolutions?)

接着使用刚才的例子,输入一张 32×32×3 维度的图片,假设用了6个大小为 5×5 的过滤器,输出维度为28×28×6。32×32×3=3072,28×28×6=4704。我们构建一个神经网络,其中一层含有 3072个单元,下一层含有4074个单元,两层中的每个神经元彼此相连,然后计算权重矩阵,它等于4074×3072≈1400万,所以要训练的参数很多。虽然以现在的技术,我们可以用 1400 多万个参数来训练网络,因为这张 32×32×3 的图片非常小,训练这么多参数没有问题。如果这是一张1000×1000的图片,权重矩阵会变得非常大。我们看看这个卷积层的参数数量,每个过滤器都是5×5,一个过滤器有 25 个参数,再加上偏差参数,那么每个过滤器就有 26 个参数,一共有 6 个过滤器,所以参数共计 156 个,参数数量还是很少。
卷积网络映射这么少参数有两个原因:

  • 一是参数共享

dl15.PNG-195kB
观察发现,特征检测如垂直边缘检测如果适用于图片的某个区域,那么它也可能适用于图片的其他区域。也就是说,如果你用一个3×3的过滤器检测垂直边缘,那么图片的左上角区域,以及旁边的各个区域都可以使用这个3×3的过滤器。每个特征检测器以及输出都可以在输入图片的不同区域中使用同样的参数,以便提取垂直边缘或其它特征。它不仅适用于边缘特征这样的低阶特征,同样适用于高阶特征,例如提取脸上的眼睛,猫或者其他特征对象。即使减少参数个数,这9个参数同样能计算出16个输出。直观感觉是,一个特征检测器,如垂直边缘检测器用于检测图片左上角区域的特征,这个特征很可能也适用于图片的右下角区域。因此在计算图片左上角和右下角区域时,你不需要添加其它特征检测器。假如有一个这样的数据集,其左上角和右下角可能有不同分布,也有可能稍有不同,但很相似,整张图片共享特征检测器,提取效果也很好。

  • 二是使用稀疏连接。
    dl16.PNG-192.3kB

比如,这个0(绿色圈出)是通过3×3的卷积计算得到的,它只依赖于这个 3×3(绿色斜线标出) 的输入的单元格,右边这个输出单元(元素0)仅与36个输入特征中9个相连接。而且其它像素值都不会对输出产生任影响,这就是稀疏连接的概念。再举个例子,这个输出(右边矩阵中红色标记的元素30)仅仅依赖于这9个特征(左边矩阵红色方框标记的区域),看上去只有这9个输入特征与输出相连接,其它像素对输出没有任何影响。

神经网络可以通过这两种机制减少参数,以便我们用更小的训练集来训练它,从而预防过度拟合。你们也可能听过,卷积神经网络善于捕捉平移不变。通过观察可以发现,向右移动两个像素,图片中的猫依然清晰可见,因为神经网络的卷积结构使得即使移动几个像素,这张图片依然具有非常相似的特征,应该属于同样的输出标记。实际上,我们用同一个过滤器生成各层中,图片的所有像素值,希望网络通过自动学习变得更加健壮,以便更好地取得所期望的平移不变性(translation invariance)
这就是卷积或卷积网络在计算机视觉任务中表现良好的原因。

Reference:

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值