跳转至

卷积神经网络

卷积神经网络

卷积函数

对于高维感知数据,多层感知机会造成过高的参数规模,进而消耗大量算力和时间

因此我们会使用函数来降维采样原本的数据,减少模型需求的参数

这样的架构需要以下的性质:

  • 平移不变性(translation invariance):神经网络的前面几层对相同的图像区域具有相似的反应
  • 局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系

对于原本的多层感知机的映射 \(\begin{split}\begin{aligned} \left[\mathbf{H}\right]_{i, j} = [\mathbf{U}]_{i, j} + \sum_a \sum_b [\mathsf{V}]_{i, j, a, b} [\mathbf{X}]_{i+a, j+b}.\end{aligned}\end{split}\)

使得V仅与a,b有关,而与隐藏层H的位置无关,可以实现平移不变性

在加和时限制循环范围,则可以实现局限性

故而原映射可以优化为 \([\mathbf{H}]_{i, j} = u + \sum_{a = -\Delta}^{\Delta} \sum_{b = -\Delta}^{\Delta} [\mathbf{V}]_{a, b} [\mathbf{X}]_{i+a, j+b}.\)

使用卷积函数则可以满足上述的要求

常用的实现流程如下:

correlation

卷积架构

填充和步幅

每次使用卷积层会导致失去k-1的数据宽度,在深层学习中会丢失很多边界信息

此时我们可以使用填充的方式,即在数据周边填充一圈的空数据,以来保存边界信息

而卷积窗口滑动的步幅也是可以调整的,调大步幅则能减少隐藏层的参数宽度

多通道输入输出

对多通道的输入,卷积层也可以具有不同的通道

conv-multi-in

以上是多通道输入单通道输出的事例

事实上,通过增加卷积层组数可以实现更多的输入通道

比较特别例子如 1 X 1卷积层,可以看做通道的映射变化

池化层

卷积层具有一定的局部性,它可能会对位置过于敏感,缺乏泛化性

同时卷积层的最后也需要进行汇聚,实现全局的映射

基于这两点,我们引入了池化层,它可以视为固定参量的窗口函数

常用的池化层如最大池化层(maximum pooling)和平均池化层(average pooling)

池化层也具有填充与步伐,它经常也能起到降低参数规模的作用

(P.S. 由于算力的增长,以及通过数据变化来扩展数据集的做法,池化层的重要性已经有所下降)

代码实现

使用Pytorch可以方便地使用卷积层

以下为经典的LeNet架构

#二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度),
net = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2), #平均池化层
    nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
    nn.Linear(120, 84), nn.Sigmoid(),
    nn.Linear(84, 10))

使用卷积可以大大降低参数规模,以及增加模型对位置特征的学习

使用卷积神经网络可以很容易地在手写数字识别中获得高准确度

cor_better_dp_0918_2135