卷积神经网络常用于计算机视觉当中, 应用在计算机视觉当中, 就要面临一个挑战, 那就是输入数据非常的大, 假如输入图片一个1000 * 1000的, 那么他就有1000 * 1000 * 3(图片的RGB三通道)个数据, 对于300w的数据量, 那么当我们第一个隐藏层有1000个神经元进行全连接时, 那么将会有300w * 1000个参数, 要训练30亿的参数, 不仅仅需要大量的图片, 还需要很好的计算平台来运算, 因此, 提出了卷积这一概念。
1. 卷积计算
这是在网上down的一张动图, 他形象的表达了卷积的过程。
- 左边 6 * 6
的矩阵, 代表图片原始数据
- 中间橙色的3 * 3
的矩阵, 叫做卷积核,很多人也叫它滤波器或者过滤器
- 右边4 * 4
的矩阵, 就是卷积处理后的结果。
计算过程,取原始图像左上3 * 3
的矩阵和卷积核进行点乘计算,计算结果再累加求和, 18 * 1 + 54 * 0 + 51 * 1 + 55 * 0 + 121 * 1 + 75 * 0 + 35 * 1 + 24 * 0 + 204 * 1 = 429
。然后, 原始图像上的3 * 3
矩阵向右滑动一格, 同样和卷积核进行点乘累加求和操作, 得到505, 依次类推。
2. Padding
由上图的计算可知, 6 * 6
的图像, 在使用3 * 3
的卷积核进行卷积运算之后, 得到了一个4 * 4
的输出, 当然, 我们可以把4 * 4
的矩阵, 看作是一张图像, 那是因为你的3 * 3
过滤器在6 * 6
矩阵中,只可能有4 * 4
种可能的位置。因此,如果我们有一个n * n
的图像,用f * f
的卷积核做卷积,那么输出的维度就是(n - f + 1) * (n - f + 1)
。在这个例子里是6 - 3 + 1 = 4
,因此得到了一个4 * 4
的输出。
我们这样做其实并不好, 这样做有2个缺点。
- 每次进行卷积操作, 图像都会缩小
- 图像边缘数据(矩阵最外层的数据),只被使用过一次, 而中间的数据, 会多次和卷积核进行计算, 从而影响输出矩阵当中的多个值。 这样一来, 边缘数据的在输出中采用的较少, 也就意味着丢失了很多边缘数据信息。
那么, 我们怎么来避免这种事情的发生呢? 于是, 我们采用原始数据边缘补零操作, 也就是说在原始矩阵的外围补上一圈0, 那么 6 * 6
的矩阵, 就被补成了 8 * 8
的, 然后再进行卷积运算, 经过3 * 3
的卷积核之后, 结果仍然为 6 * 6
的, 和原始矩阵的大小一样, 并且, 原始数据的边缘数据也进行了多次使用, 虽然并不能完全和中间的数据一样进行多次使用, 但是却也在一定程度上降低了丢失数据的问题。
接下来, 我们定义一下:
- 原始数据大小: n * n
- 卷积核大小: f * f
- 周围补零的圈数: p
对于补零操作, 有两种选择, 当 p = 0
时(不进行补零), 我们叫它Valid卷积, 当 p > 0
时, 我们叫它Same卷积。
因此:
- Valid卷积: 已知输入 n * n
, 卷积核 f * f
, p = 0
, 那么输出: (n - f + 1) × (n - f + 1)
- Same卷积: 已知输入n * n
, 卷积核 f * f
, 输出 n * n
, 那么 p = (f - 1) / 2
卷积核的f为啥总是奇数?
其实, 卷积核的大小, 并不是说不能为偶数, 但是更多情况下我们选择奇数更为合适。
- f为偶数时, 在进行补零填充时, 左右两边不对等, 而不是左边填充多一些 , 右边填充少一些。
- f为奇数时, 卷积核有一个中心像素点, 方便我们指出卷积核的位置。
3. 卷积步长(Strided convolutions)
卷积步长,就是说, 原始图像上的黄色矩阵每次向右移动的距离, 如下图所示, 步长为2. 此时 5 * 5
的矩阵, 进过 3 * 3
的卷积核进行卷积之后, 输出结果为 2* 2
的矩阵。
如果你用一个f×f的过滤器卷积一个 n * n
的图像,你的padding为p,步幅为s,在这个例子中p = 0, s=2,你会得到一个输出,因为现在你不是一次移动一个步子,而是一次移动s个步子,输出于是变为 ((n + 2p − f) / s + 1) * ((n + 2p − f) / s + 1)
当步长大于1时, 会出现一个问题, 那就是(n + 2p − f) / s的商可能不是整数, 那么这种情况下, 我们一般进行向下取整操作, 也就是说, 你的 3 * 3
的卷积核必须完全处于图像中或者填充之后的图像区域内才输出相应结果。
4. 三维卷积
上面我们介绍了对2维图像进行卷积, 接下来我们看一下如何对三维图像进行卷积操作。
对于一张彩图来说, 他有rgb三通道, 因此, 他的大小是 n * n * 3
, 因此我们要对它进行卷积时, 卷积核就不能再选用 f * f
的二维卷积核了, 我们需要选用 f * f * 3
的三维卷积核, 3分别对应RGB三个通道。
假如, 我们的原始图像是一个 6 * 6 * 3
的, 我们的卷积核采用 3 * 3 * 3
的, 如下图所示:
输入图像的的左上角的第一个 3 * 3 * 3
的立方体,和卷积核进行计算之后, 得到的结果, 就是 4 * 4
矩阵里面的第一个值, 依次类推, 此处应该注意的是, 经过卷积计算之后的结果, 是一个 4 * 4
的二维矩阵, 并不是三维。
5. 单层卷积
上面我们看到了, 当我们有一个 6 * 6 * 3
的矩阵时, 经过一个3 * 3 * 3
的卷积核进行卷积计算之后, 得到了一个4 * 4
的二维矩阵, 一个卷积核就相当于一个神经元, 那么一个卷积层会有多个神经元, 也就是有多个卷积核, 那么我有多个不同的3 * 3 * 3
的卷积核 我就能计算得到多个不同的 4 * 4
的矩阵.
总结一下: 假如我有一张 n * n * d(通道数)
的输入数据, 然后和一个 f * f * d
的卷积核进行same卷积,输出是一个n * n
的二维矩阵, 当我和 d2
个 f * f * d
的卷积核进行same卷积, 输出是d2
个n * n
的二维矩阵, 此时我们可以把这d2
个n * n
的二维矩阵进行叠放, 那么就得到一个n * n * d2
的矩阵, 因此, 每一层卷积神经网络的卷积核的个数, 也就是输出图像的通道数。