深度学习入门笔记(十八):卷积神经网络(一)

专栏——深度学习入门笔记

声明

1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献。
2)本文仅供学术交流,非商用。因此每一部分具体的参考资料并无详细对应。若是某部分不当心侵犯了你们的利益,还望海涵,并联系博主删除。
3)博主才疏学浅,文中若有不当之处,请各位指出,共同进步,谢谢。
4)此属于初版本,如有错误,还需继续修正与增删。还望你们多多指点。你们都共享一点点,一块儿为祖国科研的推动添砖加瓦。html

深度学习入门笔记(十八):卷积神经网络(一)

推荐博客:大话卷积神经网络CNN(干货满满)web

一、Padding填充

为了构建深度神经网络,须要学习不少东西,除了前面讲过的最基本的卷积,还须要学会使用的一个基本的卷积操做就是 padding,一块儿来看看它是如何工做的。编程

咱们在 深度学习入门笔记(十六):计算机视觉之边缘检测 中讲过卷积这个例子,若是用一个3×3的过滤器卷积一个6×6的图像,那么最后会获得一个4×4的输出(也就是一个4×4矩阵)。这背后的数学解释是,若是有一个 n × n n×n 的图像,用 f × f f×f 的过滤器作卷积,步长是1,那么输出的维度就是 ( n f + 1 ) × ( n f + 1 ) (n-f+1)×(n-f+1) ,即 6 3 + 1 = 4 6-3+1=4 网络

这样的话会有两个缺点:app

  • 第一个缺点是,每次卷积,图像就会缩小,从6×6缩小到4×4,再多作几回以后,好比当一个100层的深层网络,每通过一层图像都缩小,通过100层网络后,就会获得一个很小很小的图像,多是1×1,多是别的,但咱们不想让图像在每次识别边缘或其余特征时都缩小。
  • 第二个缺点是,若是是在角落边缘的像素,这个绿色阴影标记只被一个输出所触碰或者使用,由于它位于这个3×3的区域的一角;但若是是在中间的像素点,好比红色方框标记,就会有许多个3×3的区域与之重叠,因此那些在角落或者边缘区域的像素点在输出中采用较少,意味着丢失了图像边缘位置的许多信息。

在这里插入图片描述
为了解决问题,在卷积操做以前能够填充这幅图像。框架

好比在这个案例中,能够沿着图像边缘再填充一层像素,这样6×6的图像就被填充成了8×8。若是用3×3的图像对这个8×8的图像卷积,获得的输出就不是4×4而是6×6,这样就获得了一个尺寸和原始图像相同的图像。机器学习

习惯上是用0去填充!若是 p p 是填充的数量,在这个案例中 p = 1 p=1 ,由于在原始图像周围填充了一个像素点,输出也就变成了 ( n + 2 p f + 1 ) × ( n + 2 p f + 1 ) (n+2p-f+1)×(n+2p-f+1) ,因此就变成了 ( 6 + 2 × 1 3 + 1 ) × ( 6 + 2 × 1 3 + 1 ) (6+2×1-3+1)×(6+2×1-3+1) ,即 6 × 6 6×6 ,和输入的图像同样大。这样的话,涂绿的像素点(左边矩阵)影响了输出中的这些格子(右边矩阵)。这样一来,丢失信息或者更准确来讲角落或图像边缘的信息发挥的做用较小的这一缺点就被削弱了。svg

填充像素一般有两个选择,分别叫作 Valid 卷积和 Same 卷积:函数

  • Valid 卷积意味着不填充,这样的话, p = 0 p=0
  • Same 卷积意味着填充,且输出大小和输入大小是同样的。

习惯上,计算机视觉中滤波器大小 f f 是奇数,甚至可能都是这样,好比1,3,5,为何不多能看到偶数的过滤器,大概有两个缘由:学习

  • 第二个缘由是,若是 f f 是一个偶数,那么只能使用一些不对称填充,而只有 f f 是奇数的状况下,Same 卷积才会有天然的填充,而不是左边填充多一点,右边填充少一点,这样不对称的填充。
  • 第二个缘由是,当有一个奇数维过滤器,好比3×3或者5×5的,它就有一个中心点。有时在计算机视觉里,若是有一个中心像素点会更方便,便于指出过滤器的位置。

看起来,也许这些都不是为何 f f 一般是奇数的充分缘由,但若是看了卷积的文献,你就会常常会看到3×3的过滤器,也可能会看到一些5×5,7×7的过滤器,甚至有些时候会是1×1的,后面会谈到它以及何时它是有意义的。

二、卷积步长

卷积中的步幅是另外一个构建卷积神经网络的基本操做,来看一个例子。
在这里插入图片描述
若是也想用3×3的过滤器卷积这个7×7的图像,和以前不一样的是,如今步幅设置成了2。第一个位置仍是和以前同样取左上方的3×3区域的元素的乘积,再加起来,最后结果为91,而后向右移动两个空格,以此类推。

因此这个例子中是用3×3的矩阵卷积一个7×7的矩阵,获得一个3×3的输出,计算公式仍是和以前同样,过程以下:

若是用一个 f × f f×f 的过滤器卷积一个 n × n n×n 的图像,padding p p ,步幅为 s s ,在这个例子中 s = 2 s=2 ,那么输出变为 ( n + 2 p f s + 1 ) × ( n + 2 p f s + 1 ) (\frac{n+2p - f}{s} + 1) \times (\frac{n+2p - f}{s} + 1) ,其实以前的例子也是同样,只不过 s = 1 s=1 ,而在如今这个例子里 n = 7 n=7 p = 0 p=0 f = 3 f=3 s = 2 s=2   7 + 0 3 2 + 1 = 3 \ \frac{7 + 0 - 3}{2} + 1 =3 ,即3×3的输出。
在这里插入图片描述
如今只剩下最后的一个细节了,若是商不是一个整数怎么办?在这种状况下是会向下取整的, ⌊ ⌋ 就是向下取整的符号,也叫作对 z z 进行地板除(floor),这意味着 z z 向下取整到最近的整数。这个原则具体实现的方式是,只在蓝框彻底包括在图像或填充完的图像内部时,才对它进行运算;若是有任意一个蓝框移动到了外面,那就不要进行相乘操做,这是一个惯例。

三、三维卷积

卷积不只仅能够发生在二维图像上,也能够发生在三维立体上。

来看一个例子,假如说不只想检测灰度图像的特征,也想检测 RGB 彩色图像的特征。若是彩色图像是6×6×3,这里的3指的是三个颜色通道,能够想象成3个6×6图像的堆叠,为了检测图像的边缘或者其余的特征,不是把它跟原来的3×3的过滤器作卷积,而是跟一个三维的3×3×3的过滤器卷积,这样这个过滤器也有三层,对应红绿、蓝三个通道。

给这些起个名字(原图像),这里的第一个6表明图像高度,第二个6表明宽度,这个3表明通道的数目。一样地,过滤器也有一个高,宽和通道数,而且图像的通道数必须和过滤器的通道数匹配,因此这两个数(紫色方框标记的两个数,3)必须相等。
在这里插入图片描述
仍是卷积的过程,最后一个数字通道数必须和过滤器中的通道数相匹配。
在这里插入图片描述
把过滤器先放到最左上角的位置,这个3×3×3的过滤器有27个数,27个参数就是3的立方,依次取这27个数,而后乘以相应的红绿蓝通道中的数字:

  • 先取红色通道的前9个数字,
  • 而后是绿色通道,
  • 而后再是蓝色通道,
  • 乘以左边黄色立方体覆盖的对应的27个数,
  • 而后把这些数都加起来,就获得了输出的第一个数字。

若是要计算下一个输出,就把这个立方体滑动一个单位,执行上面的操做,以此类推。
在这里插入图片描述
那么,这个能干什么呢?

举个例子,这个过滤器是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} ,和以前同样,而绿色通道全为0( [ 0 0 0 0 0 0 0 0 0 ] \begin{bmatrix} 0& 0 & 0 \\ 0 &0 & 0 \\ 0 & 0 & 0 \\\end{bmatrix} ),蓝色也全为0。这样的三个矩阵堆叠在一块儿造成一个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} [ 1 0 1 1 0 1 1 0 1 ] \begin{bmatrix}1 & 0 & - 1 \\ 1 & 0 & - 1 \\ 1 & 0 & - 1 \\ \end{bmatrix} [ 1 0 1 1 0 1 1 0 1 ] \begin{bmatrix}1 & 0 & - 1 \\ 1 & 0 & - 1 \\ 1 & 0 & - 1 \\\end{bmatrix} ,三个通道都是这样的。按照计算机视觉的惯例,过滤器能够有不一样的高,不一样的宽,可是必须同样的通道数。

如今咱们已经了解了如何对立方体卷积,还有最后一个概念就是,若是不只仅想要检测垂直边缘怎么办?若是同时检测垂直边缘和水平边缘,还有45°倾斜的边缘,还有70°倾斜的边缘怎么作?换句话说,若是想同时用多个过滤器怎么办?

一个6×6×3的图像和这个3×3×3的过滤器卷积,获得4×4的输出:

  • 第一个过滤器多是一个垂直边界检测器或者是学习检测其余的特征;
  • 第二个过滤器能够是一个水平边缘检测器。

在这里插入图片描述
因此和第一个过滤器卷积,能够获得第一个4×4的输出,而后卷积第二个过滤器,获得另外一个不一样的4×4的输出,待作完卷积以后把这两个4×4的输出,把两个输出堆叠在一块儿获得了一个4×4×2的输出立方体。

小结一下 维度问题,若是有一个 n × n × n c n \times n \times n_{c} 的输入图像,在上面是6×6×3, n c n_{c} 是通道(或者深度)数目,而后卷积上一个 f × f × n c f×f×n_{c} ,在上面是3×3×3,按照惯例,这个(前一个 n c n_{c} )和这个(后一个 n c n_{c} )必须数值相同,而后就获得了 n f + 1 × n f + 1 × n c (n-f+1)×(n-f+1)×n_{c^{'}} ,这里 n c n_{c^{'}} 其实就是下一层的通道数,就是用的过滤器的个数,在上面就是4×4×2。这对立方体卷积的概念真的颇有用!用它的一小部分直接在三个通道的 RGB 图像上进行操做,更重要的是,能够检测两个特征,好比垂直和水平边缘或者10个或者128个或者几百个不一样的特征,而且输出的通道数会等于准备要检测的特征数。

四、单层卷积网络

作了这么多准备以后,终于能够开始构建卷积神经网络的卷积层,下面来看个例子。

经过两个过滤器卷积处理一个三维图像,并输出两个不一样的矩阵:
在这里插入图片描述
最终各自造成一个卷积神经网络层,而后增长误差(实数),经过 Python 的广播机制给这16个元素都加上同一误差,而后应用非线性激活函数 ReLU,输出结果是一个4×4矩阵。对于第二个4×4矩阵,是加上了不一样的误差(实数),而后应用非线性函数,最终获得另外一个4×4矩阵。而后重复以前的步骤,把这两个矩阵堆叠起来,获得一个4×4×2的矩阵。

广播机制看这里:深度学习入门笔记(五):神经网络的编程基础

经过计算,从6×6×3的输入推导出一个4×4×2矩阵,它是卷积神经网络的一层,把它映射到标准神经网络中四个卷积层中的某一层或者一个非卷积神经网络中。

注意,前向传播中一个操做就是 z [ 1 ] = W [ 1 ] a [ 0 ] + b [ 1 ] z^{[1]} = W^{[1]}a^{[0]} + b^{[1]} ,其中 a [ 0 ] = x a^{[0]} =x ,执行非线性函数获得 a [ 1 ] a^{[1]} ,即 a [ 1 ] = g ( z [ 1 ] ) a^{[1]} = g(z^{[1]}) ,输入是 a [ 0 ] a^{\left\lbrack 0\right\rbrack} ,也就是 x x ,过滤器用变量 W [ 1 ] W^{[1]} 表示。在整个卷积过程当中,对这3×3×3=27个数进行操做,实际上是27×2(由于用了两个过滤器),取这些数作乘法,实际执行了一个线性函数,获得一个4×4的矩阵,卷积操做的输出结果是一个4×4的矩阵,它的做用相似于 W [ 1 ] a [ 0 ] W^{[1]}a^{[0]} ,也就是这两个4×4矩阵的输出结果,而后加上误差。
在这里插入图片描述
这一部分(图中蓝色边框标记的部分)就是应用激活函数 ReLU 以前的值,它的做用相似于 z [ 1 ] z^{[1]} ,最后应用非线性函数,获得的这个4×4×2矩阵,成为神经网络的下一层,也就是激活层,这就是 a [ 0 ] a^{[0]} a [ 1 ] a^{[1]} 的演变过程。

示例中有两个过滤器,也就是有两个特征,所以最终才获得一个4×4×2的输出,但若是用了10个过滤器,而不是2个,最后会获得一个4×4×10维度的输出图像,由于咱们选取了其中10个特征映射(而不只仅是2个)将它们堆叠在一块儿,造成一个4×4×10的输出图像,也就是 a [ 1 ] a^{\left\lbrack1 \right\rbrack}

为了加深理解,来作一个练习。

假设如今有10个过滤器,而不是2个,神经网络的一层是3×3×3,那么,这一层有多少个参数呢???

来一块儿计算一下,每一层都是一个3×3×3的矩阵,所以每一个过滤器有27个参数,也就是27个数,而后加上一个误差,用参数 b b 表示,如今参数增长到28个,有10个过滤器,即28×10,也就是280个参数。不过,请注意一点,不论输入图片有多大,1000×1000也好,5000×5000也好,参数始终都是280个,即便这些图片很大,参数却不多,这就是卷积神经网络的一个特征,叫做 避免过拟合

避免过拟合的方式看这里:深度学习入门笔记(十):正则化

五、总结

最后总结一下用于描述卷积神经网络中的一层(以 l l 层为例),也就是卷积层的各类标记:

这一层是卷积层,用 f [ l ] f^{[l]} 表示过滤器大小,上标 [ l ] \lbrack l\rbrack 用来标记 l l 层,上标 [ l ] \lbrack l\rbrack 表示 l l 层中过滤器大小为 f × f f×f ;用 p [ l ] p^{[l]} 来标记 padding 的数量,valid 卷积,即无 paddingsame 卷积,即选定 padding;用 s [ l ] s^{[l]} 标记步幅。

这一层的输入会是某个维度的数据,表示为 n × n × n c n \times n \times n_{c} n c n_{c} 表示某层上的颜色通道数。只要稍做修改,增长上标 [ l 1 ] \lbrack l -1\rbrack ,即 n [ l 1 ] × n [ l 1 ] × n c [ l 1 ] n^{\left\lbrack l - 1 \right\rbrack} \times n^{\left\lbrack l -1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack} ,就变成了上一层的激活值。

使用图片的高度和宽度能够都同样,但也有可能不一样,因此分别用上下标 H H W W 来标记,即 n H [ l 1 ] × n W [ l 1 ] × n c [ l 1 ] n_{H}^{\left\lbrack l - 1 \right\rbrack} \times n_{W}^{\left\lbrack l - 1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack} l l 层的输入就是上一层的输出,所以上标是 [ l 1 ] \lbrack l - 1\rbrack ,这一层中会有输出(图像),其大小为 n H [ l ] × n W [ l ] × n c [ l ] n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]} 。计算方式前面提到过,至少给出了高度和宽度, n + 2 p f s + 1 \lfloor\frac{n+2p - f}{s} + 1\rfloor (注意: n + 2 p f s + 1 \frac{n + 2p - f}{s} +1 直接用这个运算结果,也能够向下取整)。

那么通道数量又是什么?这些数字从哪儿来的?

输出图像也具备深度,等于该层中过滤器的数量,就是输入通道数量,因此过滤器维度等于 f [ l ] × f [ l ] × n c [ l 1 ] f^{[l]} \times f^{[l]} \times n_{c}^{\left\lbrack l - 1 \right\rbrack} 。应用误差和非线性函数以后,这一层的输出等于它的激活值 a [ l ] a^{[l]} (三维体),即 n H [ l ] × n W [ l ] × n c [ l ] n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]} 。当执行批量梯度降低或小批量梯度降低时,若是有 m m 个例子,就是有 m m 个激活值的集合,那么输出 A [ l ] = m × n H [ l ] × n W [ l ] × n c [ l ] A^{[l]} = m \times n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}

该如何肯定权重参数,即参数W呢?

过滤器的维度已知,为 f [ l ] × f [ l ] × n c [ l 1 ] f^{[l]} \times f^{[l]} \times n_{c}^{[l - 1]} ,这只是一个过滤器的维度,若是是多个, n c [ l ] n_{c}^{[l]} 是过滤器的数量,权重也就是全部过滤器的集合再乘以过滤器的总数量,即 f [ l ] × f [ l ] × n c [ l 1 ] × n c [ l ] f^{[l]} \times f^{[l]} \times n_{c}^{[l - 1]} \times n_{c}^{[l]}

最后看看误差参数,每一个过滤器都有一个误差参数(实数),它是某维度上的一个向量,为了方便,在代码中经常表示为一个1×1×1× n c [ l ] n_{c}^{[l]} 的四维向量或四维张量。

推荐阅读

参考文章

  • 吴恩达——《神经网络和深度学习》视频课程