Convolution demo

简介

为什么用卷积

  • 局部连接:提取 context 的特征(例如 $3 \times 3$ 卷积提取了 9 个像素的综合特征)。
  • 权值共享:小的卷积核(例如 $3 \times 3$)用在大的特征图上(例如 $64 \times 64$)。
  • 多层次结构:多个卷积层叠加(例如 VGG16),提取更高级抽象的特征。

卷积与互相关

卷积(convolution)与 互相关(cross-correlation)的区别在于卷积操作需要翻转 卷积核,而互相关不用。我们在卷积神经网络中使用的「卷积」其实是互相关,但是在实际使用上没有差别,因为卷积核都是学出来的,无非差了一个翻转操作。

卷积的相关计算

参数与计算量

假设输入数据的 shape 为 $(C_{in}, H_{in}, W_{in})$,卷积核的 shape 为 $(C_{out}, C_{in}, K, K)$,输出的 shape 为 $(C_{out}, H_{out}, W_{out})$,假设卷积带 Bias,那么

  • 参数量为 $C_{out} \times (C_{in} \times K \times K + 1)$;
  • 计算量(一次乘法与一次加法,Bias 的加法只算 1 次)为 $(C_{out} \times H_{out} \times W_{out}) \times (C_{in} \times K \times K + 1)$。

Padding 计算

假如输入大小为 $L_{in} \times L_{in}$,卷积核大小为 $K \times K$,Stride 为 $s$,那么

Valid padding

$$ L_{out} = \lceil \frac{L_{in} - (K - 1)}{s} \rceil $$

Same padding

$$ L_{out} = \lceil \frac{f_{in}}{s} \rceil $$

Full padding

$$ L_{out} = L_{in} + (K - 1) $$

感受野计算

如果第 $l$ 层的输出的某个位置的感受野为 $F_l$,那么它的输入的感受野 $F_{l-1}$ 为

$$ F_{l-1} = ((F_l - 1) * s) + K $$

其中 $s$ 为 stride,$K$ 为卷积核大小。

举例:

  1. 某卷积层的输出的感受野为 $3 \times 3$,stride $s=1$,卷积核 $K=3$,那么它的输入的感受野为 $(3 - 1) \times 1 + 3 = 5$;如果 $s=2$,那么感受野为 $(3 - 1) \times 2 + 3 = 7$。
  2. VGG16 网络的 conv4_3 层(第 4 个 stage 的第 3 个卷积层的输出)的感受野为 $((((1 + 6) \times 2 + 6 ) \times 2 + 4) \times 2 + 4) = 92$(可以参考 YaqiLYU:卷积神经网络的感受野)。

卷积的实现

普通实现

假设输入数据的 shape 为 $(C_{in}, H, W)$(Caffe 默认维度顺序),卷积核的 shape 为 $(C_{out}, C_{in}, K, K)$,$K$ 为奇数,padding 为 $(K - 1) / 2$,stride 为 $1$,那么计算步骤如下:

  1. 利用输入数据构建矩阵 $M_{feature}$,shape 为$(H \times W, C_{in} \times K \times K)$。
    • 输入数据可能被复制多次(例如 stride 为 1)或某些输入数据被丢弃(例如 padding 与 stride 不齐);
    • 若 padding 与 stride 不满足题中假设,则此处的 $H$ 与 $W$ 指的是输出的维度。
  2. 将卷积核转为矩阵 $M_{filter}$,shape 为 $(C_{out}, C_{in} \times K \times K)$。
  3. 计算矩阵乘法 $M_{filter} \times M_{feature}^T$,得到结果矩阵 $M_{output}$,其 shape 为 $(C_{out}, H \times W)$。
  4. 将矩阵 $M_{output}$ 转为三维 $(C_{out}, H, W)$。

在这些步骤中有两个比较关键的 reshape 函数 im2colcol2im 分别负责将图片转为向量、将向量转为图片。

FFT 实现

TODO

Winograd 实现

TODO

卷积类型

扩张卷积(Dilated Conv)

扩张卷积(dilated convolution)又译为空洞卷积,指的是通过在卷积核的元素之间插入空值来使卷积核「膨胀」,例如将 $3 \times 3$ 卷积核加宽 1 单位之后将编程一个 $5 \times 5$ 卷积核,其中存在 2 行 2 列空值。

特点

  • (+) 增大感受野,不增加任何成本。

转置卷积(Transposed Conv)

转置卷积(transposed convolution)又称 fractionally strided convolution,类似卷积的反操作(实际上还是卷积)。一般的卷积实现会将 feature 与 filter 分别展成两个矩阵 $M_{feature}$、$M_{filter}$ 再进行矩阵乘法,得到的结果矩阵 $M_{result}$ 再 reshape 得到输出:

$$ M_{result} = M_{filter} \times M_{feature}^T $$

左右乘上一个 $M_{filter}^T$ 可得(注意:这里的公式只表示矩阵形状匹配,不表示具体值匹配!):

$$ \begin{aligned} M_{filter}^T \times M_{result} &= M_{filter}^T \times M_{filter} \times M_{feature}^T \\ M_{feature}^T &= M_{filter}^T \times M_{result} \\ \end{aligned} $$

那么转置卷积相当于在此处的 $M_{filter}$ 矩阵变为了原来的转置,$M_{result}$ 与 $M_{feature}^T$ 调换了输入输出位置,从而实现了从小图像到大图像的上采样。

特点

  • (+) 实现特征上采样。

逐点卷积(Pointwise Conv)

逐点卷积(pointwise convolution)即俗称的 $1 \times 1$ 卷积。

特点

  • (+) 改变通道数。
  • (+) 通道之间的信息融合。
  • (+) 增加非线性(其实是激活函数的作用)

逐通道卷积(Depthwise Conv)

逐通道卷积(depthwise convolution)即每个通道单独进行卷积,然后再 concat 起来。

特点

  • (o) 忽略通道之间的关系,只挖掘单个通道内的深度特征,通常与逐点卷积(pointwise Conv)串联使用,称为深度可分离卷积(depthwise separable convolution)。

分组卷积(Group Conv)

分组卷积(group convolution)即多通道版本的逐通道卷积(depthwise convolution)。最初 AlexNet (NIPS 2012) 为了节省显存(当时的 GPU 显存不大)使用了分组卷积,将不同的组分到不同的 GPU 上进行运算,后来人们发现分组卷积似乎还有别的好处。

特点

  • (+) 效率高,大大减少参数量、计算量。
  • (+) 在显存不足的时候可以利用分组卷积进行模型并行训练。
  • (+) 打破所有通道的协同训练,防止过拟合,尤其是切换分组组合之后(如 ShuffleNet)。

空间可分离卷积(Spatially Separable Conv)

空间可分离卷积指的是将单个卷积操作分解为两个连续的卷积操作,例如将 $3 \times 3$ 卷积分解为一个 $3 \times 1$ 卷积与一个 $1 \times 3$ 卷积,从参数量上看,原先需要 $3 \times 3 = 9$ 个参数,现在只需要 $3 \times 1 + 1 \times 3 = 6$ 个参数;从计算量上看(粗略计算),原先需要 $H \times W \times 3 \times 3 = 9HW$ 次运算,现在只需要 $H \times W \times 1 \times 3 + H \times W \times 3 \times 1 = 6HW$ 次运算。

特点

  • (+) 既保证了一定的非线性能力(不是所有卷积核都能分解为两个小核),又大大减少了参数与计算量。

深度可分离卷积(Depthwise Separable Conv)

深度可分离卷积其实就是一个逐通道卷积(depthwise convolution)与逐点卷积(pointwise convolution)串在一起。与普通的卷积相比,该卷积节省了非常多的参数与计算量,依然保持了一定的非线性变换能力。

特点

  • (+) 既保证了一定的非线性能力(不是所有普通卷积都能分解为一个逐通道卷积和逐点卷积),又大大减少了参数与计算量。

发展趋势

卷积核

  • 大 → 小(例如 $3 \times 3$ conv);
  • 单尺寸 → 多尺寸(例如 Inception);
  • 固定形状 → 可变形(即 deformable conv);
  • 使用 $1 \times 1$ 卷积核(利用 bottleneck)。

卷积通道

  • 普通卷积 → depthwise conv;
  • 普通卷积 → group conv(再加 channel shuffle);
  • 普通卷积 → squeeze-and-excitation(即 SENet)。

卷积连接

  • 普通串联 → shortcuts(即 ResNet);
  • 普通串联 → densely connections(即 DenseNet)。

参考