卷积神经网络-基础知识

6,527 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

卷积神经网络

卷积

卷积的过程可以看作两个矩阵之间特殊的乘法,如下图所示:

img

一个是输入张量,另一个是卷积核,卷积核通常为较小尺寸的矩阵,比如3X3,5X5等,卷积核会从输入张量的左上角开始,从左到右,从上到下进行滑动,输入张量部分矩阵与卷积核进行按元素相乘并相加得到一个值。

根据上图所示,输出张量的各个元素计算过程如下:

0×0+1×1+3×2+4×3=19,1×0+2×1+4×2+5×3=25,3×0+4×1+6×2+7×3=37,4×0+5×1+7×2+8×3=43.0\times0+1\times1+3\times2+4\times3=19,\\ 1\times0+2\times1+4\times2+5\times3=25,\\ 3\times0+4\times1+6\times2+7\times3=37,\\ 4\times0+5\times1+7\times2+8\times3=43.

如下动图演示整个过程:

动图

推荐一个网站:pwwang.github.io/cnn-convolu…

上图的卷积计算过程其实是互相关(Cross-Correlation)运算。

在数学中,两个函数的卷积被定义为:

(fg)(x)=f(z)g(xz)dz.(f * g)(\mathbf{x}) = \int f(\mathbf{z}) g(\mathbf{x}-\mathbf{z}) d\mathbf{z}.

可以解释成函数 f 与 g 经过翻转和平移时,计算两个函数之间的重叠面积。当是离散对象时,积分就变成求和运算,公式如下:

(fg)(i)=af(a)g(ia).(f * g)(i) = \sum_a f(a) g(i-a).

该公式应用到二维张量中,对应的就是:

(fg)(i,j)=abf(a,b)g(ia,jb).(f * g)(i, j) = \sum_a\sum_b f(a, b) g(i-a, j-b).

根据这个公式,计算过程如下:

img

和之前讲的不太一样,好像不是一一对应的元素相乘,再相加。因为减号的存在,所以计算过程相当于将核矩阵旋转了180度,再与输入矩阵相乘求和了。

其实在卷积神经网络的应用场景下,更多的是对待图像,图像是否旋转,旋转多少,对于计算机是无区别的,计算机计算的是图像的像素点,不旋转的互相关运算计算起来更方便。因此,很多深度学习框架直接使用互相关运算来表示卷积的过程。

卷积中的卷,指的是函数翻转与滑动,你可以理解成卷毛巾过程,从 g(z) 变成 g(i-z) 的这个过程。

卷积中的积,指的是积分或者求和。

到这里希望你理解了卷积的含义以及在神经网络的含义。

推荐理解文章:

Padding与Stride

假设输入形状为nh×nwn_h\times n_w,卷积核形状为kh×kwk_h\times k_w,那么输出形状将是(nhkh+1)×(nwkw+1)(n_h-k_h+1) \times (n_w-k_w+1)。因此,卷积的输出形状取决于输入形状和卷积核的形状。

填充

在上述图片的计算过程,其实我们丢失了边缘信息,如果希望在输出张量中存在边缘信息,就可以在输入张量进行填充元素,默认是 0 ,这就是 Padding。如下图所示:

img

假设对输入张量进行php_h行填充,pwp_w列填充,那么输出的形状将为(nhkh+ph+1)×(nwkw+pw+1)(n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1)。

在很多情况下,我们希望输入张量与输出张量形状是一致的,那么就需要设置ph=kh1p_h=k_h-1pw=kw1p_w=k_w-1

  • 假设khk_h是奇数,我们将在高度的两侧填充ph/2p_h/2行。
  • khk_h是偶数,则一种可能性是在输入顶部填充ph/2\lceil p_h/2\rceil行,在底部填充ph/2\lfloor p_h/2\rfloor行。

在代码中都是 p/2

卷积神经网络中卷积核的高度和宽度通常为奇数,例如1、3、5或7。

步幅

卷积核会从输入张量的左上方开始,按从左往右、从上往下的顺序,依次在输入矩阵上滑动,那么滑动的行数和列数称为步幅(Stride)。

在之前的例子中都是默认步幅是 1 。如下图所示,使用了纵向步幅为3、横向步幅为2 的计算过程。

img

通常,当垂直步幅为shs_h、水平步幅为sws_w时,输出形状为(nhkh+ph+sh)/sh×(nwkw+pw+sw)/sw.\lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor.

通道

一张彩色的图像,是一个3×h×w3\times h\times w 的高维数组,hhww是图像的高度与宽度,单位是像素,3则是图像的通道,因为RGB(红、绿、蓝)3个颜色通道。

当你的输入张量具有多个通道时,构造的卷积核的通道数需要与输入张量的通道数相同,不同的通道的卷积核与不同通道的输入张量进行计算。

举个例子:

假设输入张量的通道数为cic_{i},那么卷积核的输入通道数也需要为cic_i。我们卷积核的形状为kh×kwk_h\times k_w的张量。将这些cic_i个张量连结在一起可以得到形状为ci×kh×kwc_i\times k_h\times k_w的卷积核。由于输入和卷积核都有cic_i个通道,我们可以对每个通道输入的二维张量和卷积核的二维张量进行互相关运算,再对通道求和(将cic_i的结果相加)得到二维张量。

多输入通道与卷积核进行运算会得到单通道的二维张量。

img

当输出通道为多个,卷积核需要再增加一维,多个通道的卷积核进行相加得到输出张量。

举个例子:

假设输入和输出通道的数目分别表示cic_icoc_o,卷积核的高度和宽度为khk_hkwk_w,当coc_o大于 1 时,每个输出通道都会有一个形状为ci×kh×kwc_i\times k_h\times k_w的卷积核张量,那么整个卷积核形状是co×ci×kh×kwc_o\times c_i\times k_h\times k_w。每个输出通道的输出张量是每个通道的卷积核相加得到结果。

img

建议多理解一下这里!

当多输入通道,卷积核也会有着同样的通道,通道对应的进行互相关计算,最后结果相加得到一个二维张量,当多输出通道,在多输入通道的基础上,增加卷积核的维度,就可以得到多个输出通道结果。

池化层

与卷积层类似,由一个固定窗口构成,叫做pooling。该窗口会根据步幅在输入张量上进行滑动,根据特殊计算得到一个输出,值得注意的是该窗口是没有参数构成,就是设置一个固定形状的窗口。通常计算窗口中所有元素的最大值或平均值,分别称为最大池化层(maximum pooling)和平均池化层(average pooling)。

假设设置一个最大池化层,它的形状为 2X2。窗口就会从输入张量的左上角开始,从左往右、从上往下的在输入张量内滑动,计算覆盖输入张量的子张量的最大值,得出输出结果。

最大池化过程

计算过程如下:

max(0,1,3,4)=4,max(1,2,4,5)=5,max(3,4,6,7)=7,max(4,5,7,8)=8.\max(0, 1, 3, 4)=4,\\ \max(1, 2, 4, 5)=5,\\ \max(3, 4, 6, 7)=7,\\ \max(4, 5, 7, 8)=8.\\

池化层也有步幅与填充,该过程与卷积层是一样的,就不多介绍了。

当涉及的多个通道输入数据时候,池化层会在每个通道进行单独运算,不会对结果进行汇总,相当于处理每一个通道的数据, 所以池化层的输出通道数与输入通道数相同。池化层是没有多个输出通道问题。

为什么会需要池化层?

实际学习过程,我们想要识别图像中某一个物体时候,它在数据集中是不会出现在固定位置,不同图像物体的像素位置也是不同的,我们需要更加关心的是物体的轮廓是否满足我们想要识别的物体,不希望模型对物体像素位置有一定要求的。池化层可以缓解卷积层对位置的过度敏感性,同时降低对空间降采样表示的敏感性。

参考: