1. 二维卷积层
卷积神经网络(convolutional neural network)是含有卷积层的神经网络。二维卷积层是卷积神经网络使用最常见的卷积神经网络,常用来处理图像数据。
1.1. 互相关运算
虽然卷积层得名于卷积(convolution)运算,但我们通常在卷积层中使用更加直观的互相关(cross-correlation)运算。在二维卷积层中,一个二维输入数组和一个二维核(kernel)数组通过互相关运算输出一个二维数组。如下图所示,输入是一个高和宽均为 3 的二维数组。我们将该数组的形状记为 3×3 或 (3,3) 。核数组的高和宽分别为 2 。该数组在卷积计算中又称卷积核或过滤器 (filter)。卷积核窗口(又称卷积窗口)的形状取决于卷积核的高和宽,即 2×2 。下图中的阴影部分为第一个输出元素及其计算所使用的输入和核数组元素: 0×0+1×1+3×2+4×3=19 。
在二维互相关运算中,卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当卷积窗口滑动到某一位置时,窗口中的输入子数组与核数组按元素相乘并求和,得到输出数组中相应位置的元素。
1.2. 二维卷积层
二维卷积层将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出。卷积层的模型参数包括了卷积核和标量偏差。在训练模型的时候,通常我们先对卷积核随机初始化,然后不断迭代卷积核和偏差。
1.3. 图像中的物体边缘检测
检测图像中物体的边缘,即找到像素变化的位置。首先我们构造一张 6×8 的图像(即高和宽分别为6像素和8像素的图像)。它中间 4 列为黑 (0),其余为白 (1)。
1.4. 特征图和感受野
二维卷积层输出的二维数组可以看作是输入在空间维度(宽和高)上某一级的表征,也叫特征图(feature map)。影响元素 𝑥 的前向计算的所有可能输入区域(可能大于输入的实际尺寸)叫做 𝑥 的感受野(receptive field)。以上图为例,输入中阴影部分的四个元素是输出中阴影部分元素的感受野。我们将上图中形状为 2×2 的输出记为 𝑌 ,并考虑一个更深的卷积神经网络:将 𝑌 与另一个形状为 2×2 的核数组做互相关运算,输出单个元素 𝑧 。那么, 𝑧 在 𝑌 上的感受野包括 𝑌 的全部四个元素,在输入上的感受野包括其中全部9个元素。可见,我们可以通过更深的卷积神经网络使特征图中单个元素的感受野变得更加广阔,从而捕捉输入上更大尺寸的特征。
2. 填充与步幅
假设输入形状是 𝑛ℎ×𝑛𝑤 ,卷积核窗口形状是 𝑘ℎ×𝑘𝑤 ,那么输出形状将会是:
(𝑛ℎ−𝑘ℎ+1)×(𝑛𝑤−𝑘𝑤+1)
所以卷积层的输出形状由输入形状和卷积核窗口形状决定。这一节介绍卷积层的两个超参数,即填充和步幅。它们可以对给定形状的输入和卷积核改变输出形状。
2.1. 填充
填充 padding 是指在输入高和宽的两侧填充元素(通常是0元素)。下图里我们在原输入高和宽的两侧分别添加了值为 0 的元素,使得输入高和宽从 3 变成了 5 ,并导致输出高和宽由 2 增加到 4 。下图中的阴影部分为第一个输出元素及其计算所使用的输入和核数组元素: 0×0+0×1+0×2+0×3=0 。
一般来说,如果在高的两侧一共填充 𝑝ℎ 行,在宽的两侧一共填充 𝑝𝑤 列,那么输出形状将会是如下所示,输出的高和宽会分别增加 𝑝ℎ 和 𝑝𝑤 。
(𝑛ℎ−𝑘ℎ+𝑝ℎ+1)×(𝑛𝑤−𝑘𝑤+𝑝𝑤+1)
在很多情况下,我们会设置 𝑝ℎ=𝑘ℎ−1 和 𝑝𝑤=𝑘𝑤−1 来使输入和输出具有相同的高和宽。这样会方便在构造网络时推测每个层的输出形状。假设这里 𝑘ℎ 是奇数,我们会在高的两侧分别填充 𝑝ℎ/2 行。如果 𝑘ℎ 是偶数,一种可能是在输入的顶端一侧填充 ⌈𝑝ℎ/2⌉ 行,而在底端一侧填充 ⌊𝑝ℎ/2⌋ 行。在宽的两侧填充同理。
卷积神经网络经常使用奇数高宽的卷积核,如 1 、 3 、 5 和 7 ,所以两端上的填充个数相等。对任意的二维数组 X ,设它的第 i 行第 j 列的元素为 X[i,j] 。当两端上的填充个数相等,并使输入和输出具有相同的高和宽时,我们就知道输出 Y[i,j] 是由输入以 X[i,j] 为中心的窗口同卷积核进行互相关计算得到的。当卷积核的高和宽不同时,我们也可以通过设置高和宽上不同的填充数使输出和输入具有相同的高和宽。
2.2. 步幅
卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅 (stride) 。上面的例子都是在高和宽两个方向上步幅均为 1 。我们也可以使用更大步幅。下图展示了在高上步幅为 3 、在宽上步幅为 2 的二维互相关运算。可以看到,输出第一列第二个元素时,卷积窗口向下滑动了 3 行,而在输出第一行第二个元素时卷积窗口向右滑动了 2 列。当卷积窗口在输入上再向右滑动 2 列时,由于输入元素无法填满窗口,无结果输出。下图中的阴影部分为输出元素及其计算所使用的输入和核数组元素: 0×0+0×1+1×2+2×3=8 、 0×0+6×1+0×2+0×3=6 。
当高上步幅为 𝑠ℎ ,宽上步幅为 𝑠𝑤 时,输出形状为:
⌊(𝑛ℎ−𝑘ℎ+𝑝ℎ+𝑠ℎ)/𝑠ℎ⌋×⌊(𝑛𝑤−𝑘𝑤+𝑝𝑤+𝑠𝑤)/𝑠𝑤⌋
如果设置 𝑝ℎ=𝑘ℎ−1 和 𝑝𝑤=𝑘𝑤−1 ,那么输出形状将简化为 ⌊(𝑛ℎ+𝑠ℎ−1)/𝑠ℎ⌋×⌊(𝑛𝑤+𝑠𝑤−1)/𝑠𝑤⌋ 。如果输入的高和宽能分别被高和宽上的步幅整除,那么输出形状将是 (𝑛ℎ/𝑠ℎ)×(𝑛𝑤/𝑠𝑤) 。
3. 多输入通道和多输出通道
前面我们用到的输入和输出都是二维数组,但真实数据的维度经常更高。例如,彩色图像在高和宽 2 个维度外还有红、绿、蓝 3 个颜色通道。假设彩色图像的高和宽分别是 ℎ 和 𝑤 ,那么它可以表示为一个 3×ℎ×𝑤 的多维数组。我们将大小为 3 的这一维称为通道 (channel) 维。本节我们将介绍含多个输入通道或多个输出通道的卷积核。
3.1. 多输入通道
当输入数据含多个通道时,我们需要构造一个输入通道数与输入数据的通道数相同的卷积核,从而能够与含多通道的输入数据做互相关运算。假设输入数据的通道数为 𝑐𝑖 ,那么卷积核的输入通道数同样为 𝑐𝑖 。设卷积核窗口形状为 𝑘ℎ×𝑘𝑤 。当 𝑐𝑖=1 时,我们知道卷积核只包含一个形状为 𝑘ℎ×𝑘𝑤 的二维数组。当 𝑐𝑖>1 时,我们将会为每个输入通道各分配一个形状为 𝑘ℎ×𝑘𝑤 的核数组。把这 𝑐𝑖 个数组在输入通道维上连结,即得到一个形状为 𝑐𝑖×𝑘ℎ×𝑘𝑤 的卷积核。由于输入和卷积核各有 𝑐𝑖 个通道,我们可以在各个通道上对输入的二维数组和卷积核的二维核数组做互相关运算,再将这 𝑐𝑖 个互相关运算的二维输出按通道相加,得到一个二维数组。这就是含多个通道的输入数据与多输入通道的卷积核做二维互相关运算的输出。
下图展示了含 2 个输入通道的二维互相关计算的例子。在每个通道上,二维输入数组与二维核数组做互相关运算,再按通道相加即得到输出。下图中阴影部分为第一个输出元素及其计算所使用的输入和核数组元素: (1×1+2×2+4×3+5×4)+(0×0+1×1+3×2+4×3)=56 。
3.2. 多输出通道
当输入通道有多个时,因为我们对各个通道的结果做了累加,所以不论输入通道数是多少,输出通道数总是为 1 。设卷积核输入通道数和输出通道数分别为 𝑐𝑖 和 𝑐𝑜 ,高和宽分别为 𝑘ℎ 和 𝑘𝑤 。如果希望得到含多个通道的输出,我们可以为每个输出通道分别创建形状为 𝑐𝑖×𝑘ℎ×𝑘𝑤 的核数组。将它们在输出通道维上连结,卷积核的形状即 𝑐𝑜×𝑐𝑖×𝑘ℎ×𝑘𝑤 。在做互相关运算时,每个输出通道上的结果由卷积核在该输出通道上的核数组与整个输入数组计算而来。
3.3. 1×1 卷积层
最后我们讨论卷积窗口形状为 1×1 (𝑘ℎ=𝑘𝑤=1) 的多通道卷积层。我们通常称之为 1×1 卷积层,并将其中的卷积运算称为 1×1 卷积。因为使用了最小窗口, 1×1 卷积失去了卷积层可以识别高和宽维度上相邻元素构成的模式的功能。实际上, 1×1 卷积的主要计算发生在通道维上。下图展示了使用输入通道数为 3 、输出通道数为 2 的 1×1 卷积核的互相关计算。值得注意的是,输入和输出具有相同的高和宽。输出中的每个元素来自输入中在高和宽上相同位置的元素在不同通道之间的按权重累加。假设我们将通道维当作特征维,将高和宽维度上的元素当成数据样本,那么 1×1 卷积层的作用与全连接层等价。
4. 池化层
在图像物体边缘检测应用中,我们构造卷积核从而精确地找到了像素变化的位置。设任意二维数组 X 的 i 行 j 列的元素为 X[i, j] 。如果我们构造的卷积核输出 Y[i, j]=1 ,那么说明输入中 X[i, j] 和 X[i, j+1] 数值不一样。这可能意味着物体边缘通过这两个元素之间。但实际图像里,我们感兴趣的物体不会总出现在固定位置:即使我们连续拍摄同一个物体也极有可能出现像素位置上的偏移。这会导致同一个边缘对应的输出可能出现在卷积输出 Y 中的不同位置,进而对后面的模式识别造成不便。 池化(pooling)层,它的提出是为了缓解卷积层对位置的过度敏感性。
4.1. 最大池化层和平均池化层
同卷积层一样,池化层每次对输入数据的一个固定形状窗口(又称池化窗口)中的元素计算输出。不同于卷积层里计算输入和核的互相关性,池化层直接计算池化窗口内元素的最大值或者平均值。该运算也分别叫做最大池化或平均池化。在二维最大池化中,池化窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当池化窗口滑动到某一位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素。
上图展示了池化窗口形状为 2×2 的最大池化,阴影部分为第一个输出元素及其计算所使用的输入元素。输出数组的高和宽分别为 2 ,其中的 4 个元素由取最大值运算 max 得出。
二维平均池化的工作原理与二维最大池化类似,但将最大运算符替换成平均运算符。池化窗口形状为 𝑝×𝑞 的池化层称为 𝑝×𝑞 池化层,其中的池化运算叫作 𝑝×𝑞 池化。
再次回到本节开始提到的物体边缘检测的例子。现在我们将卷积层的输出作为 2×2 最大池化的输入。设该卷积层输入是 X 、池化层输出为 Y 。无论是 X[i, j] 和 X[i, j+1] 值不同,还是 X[i, j+1] 和 X[i, j+2] 不同,池化层输出均有 Y[i, j]=1 。也就是说,使用 2×2 最大池化层时,只要卷积层识别的模式在高和宽上移动不超过一个元素,我们依然可以将它检测出来。
4.2. 填充与步幅
同卷积层一样,池化层也可以在输入的高和宽两侧的填充并调整窗口的移动步幅来改变输出形状。池化层填充和步幅与卷积层填充和步幅的工作机制一样。
4.3. 多通道
在处理多通道输入数据时,池化层对每个输入通道分别池化,而不是像卷积层那样将各通道的输入按通道相加。这意味着池化层的输出通道数与输入通道数相等。
5. 为什么是卷积神经网络
在线性模型中,我们将图像中的像素逐行展开,那么同一列相近的像素在这个向量中可能相距较远,这就意味着它们构成的模式可能难以被模型识别。卷积层保留输入形状,使图像的像素在高和宽两个方向上的相关性均可能被有效识别。
此外,在线性模型中,对于大尺寸的输入图像,使用全连接层容易造成模型过大。假设输入是高和宽均为 1000 像素的彩色照片(含 3 个通道)。即使全连接层输出个数仍是 256 ,该层权重参数的形状是 3,000,000×256 :占用了大约 3 GB 的内存或显存,所以线性模型导致了复杂的模型和过高的存储开销。卷积层通过滑动窗口将同一卷积核与不同位置的输入重复计算,从而避免参数过多。
6. 示例
相关代码已上传到github