原文链接:https://www.yuque.com/yahei/hey-yahei/typical_cnn
参考:
CNN的典型组合方式是,以 卷积层+激活函数(比如relu)+池化层 作为一组操作;
一张图片经过若干组这样的操作的stack之后,变得越来越小,同时越来越深(feature maps越来越多);
在stack的顶层,经过一个常规的前馈神经网络(由若干个带激活的全连接层组成)后产生预测结果(通常经过一个softmax层)——
1998年由Yann LeCun提出,用于实现手写体数字识别(MNIST);
而其他层不再进行padding,所以可以看到每经过一层,图片尺寸就发生一次萎缩
y i = ∑ j ( x j − w i j ) 2 y_i = \sum_j (x_j - w_{ij})^2 yi=j∑(xj−wij)2
论文:《Imagenet Classification with Deep Convolutional Neural Networks(2012)》
赢得2012年的ImageNet ILSVRC比赛;
与LeNet-5很像,只是更大更深(约60万个参数)
使强烈激活的神经元在相邻特征图的相同位置上的神经元被抑制(仿生),这促进不同的特征图得到差异化,能够关注到不同的特征。
b i = a i ( k + α ∑ j = m a x ( 0 , i − r / 2 ) m i n ( i + r / 2 , f n − 1 ) a j 2 ) β b_i = a_i (k + \alpha \sum_{j = max(0, i - r/2)}^{min(i+r/2, f_n -1)} a_j^2)^\beta bi=ai(k+αj=max(0,i−r/2)∑min(i+r/2,fn−1)aj2)β
其中,
a i , b i a_i, b_i ai,bi分别是LRN的第i个特征图输入、正则化输出;
k , α , β , r k, \alpha, \beta, r k,α,β,r是超参量, k k k 称为偏置, r r r 称为深度半径;
$$f_n$$ 是特征图的数量;
比如,当 $$r=2$$ 时,强烈激活的神经元会抑制他的上一个和下一个特征图中相同位置的神经元;
变种:ZFNet
论文:《Visualizing and Understanding Convolutional Networks(2014)》
2013年ILSVRC比赛冠军
论文:《VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION(2015)》
2014年ILSVRC亚军
特点:
增加网络深度时确保各层输入大小随深度增加而不减小
论文:《Network In Network(2014)》
这里提出的NIN并不常用,但却启发了后来的Inception和ResNet。
特点:
参考:《从Inception v1到Inception-ResNet,一文概览Inception家族的「奋斗史」| 机器之心》
注意Inception的默认输入尺寸是299而不是224
论文:《Going Deeper with Convolutions(2015)》
2014年ILSVRC冠军,也称为GoogLeNet;
利用子网络inception模块,网络更加高效(大约只有AlexNet的十分之一),使得网络可以更深;
Inception模块:
Inception-v1(GoogLeNet)框架:
包括9个堆叠Inception模块,每个卷积层都使用ReLU激活函数。
辅助损失:
为了缓解深层网络的梯度消失问题,Inception-v1从网络中间抽出两组特征图,分别以此用“k5s3平均池化 + k1s1卷积 + 全连接 + 全连接 + Softmax”计算得到两个辅助损失aux_loss1和aux_loss2,与主loss加权后作为总loss进行训练。 total_loss = main_loss + 0.3 * aux_loss1 + 0.3 * aux_loss2
论文:《Rethinking the Inception Architecture for Computer Vision (CVPR2016)》
v2只是个过渡版本,论文里把v3也一并提了出来。
三种改进的Inception模块:
B |
论文:《Rethinking the Inception Architecture for Computer Vision (CVPR2016)》同v2
在Inception-v2的基础上,
完整结构:
(图中As in figure 5/6/7 分别对应前述的 A/B/C)
论文:《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning (AAAI2017)》
这篇论文同时提出了Inception-v4、Inception-ResNet-v1和Inception-ResNet-v2;
Inception-ResNet-v1计算规模与Inception-v3相当,
Inception-ResNet-v2计算规模与Inception-v4相当
改进stem:
一般会将网络最初的卷积层堆叠(比如这里是指Inception模块之前的所有层)称为stem。
(左:Inception-v1/v2/v3; 中:Inception-ResNet-v1; 右:Inception-v4、Inception-ResNet-v2)
这里把三个版本的stem都列出来作一比较,
改进Inception模块:
A | B | C | |
---|---|---|---|
I1 |
| I2/I3 | **
| **
| **
|
| I4 | | | |
| IR1/IR2 | | | |
设计专门的下采样块:
v1-v3都是直接用最大池化来实现下采样。
(左:I4/IR1/IR2第一次下采样; 中:I4第二次下采样; 右:IR1/IR2第二次下采样)
残差激活值缩放:
作者观察到当网络太深时,深层的残差单元可能会使网络崩溃,此时可以尝试在残差上设置一个缩放因子(如0.1-0.3)来增加训练的稳定性。
论文:《Deep Residual Learning for Image Recognition(2015)》
参考:
受LSTM中门机制的启发,提出高速公路网络,对前馈神经网络进行修正,使信息能够在多个神经网络层之间高效流动;这一思想也影响了ResNet网络
2015年ILSVRC冠军;网络更深(152层),如此深的网络能够被训练主要得益于**Skip Connections(或Shortcut Connections)**技术;
残差学习(Residual Learning):
在常规网络的基础上,网络输出前增加一个与输入加和的操作;
这时网络不再直接训练目标函数 h ( x ) h(x) h(x),而是训练 f ( x ) = h ( x ) − x f(x) = h(x) - x f(x)=h(x)−x;
对于常规网络,权重通常被初始化为一个比较小的数值(回顾《梯度消失与梯度爆炸 - 随机初始化 | Hey~YaHei!》),网络一开始只能输出一个非常小的结果;
但是残差网络输出的却是一个接近输入的结果,而往往我们所要训练的目标函数跟这个输入还是比较接近的,这将大大加速我们的训练过程;
而且,如果加入了很多skip connections,网络可以在很早的时候就开始取得进步(有效地学习),即使中间有部分层还没开始进步也不影响,因为信号的传递很容易穿过整个网络(随后ResNet-v2部分的会就残差单元如何有效缓解梯度消失做详细论述);
深层残差网络可以看作是很多残差单元(Residual Unit, RU)的堆叠,每个残差单元是一个包含一个skip connection的小网络(Network In Network的思想)——
整体框架:
常见的有ResNet18, ResNet34, ResNet50, ResNet101, ResNet152,数字表示的是“卷积层数量+全连接层数量”(但不包括下采样时shortcut通路上的下采样卷积);
每经过一定层数,图片会经过一个步长为2的卷积层而被压缩,然后接下来的残差单元的宽度都增加一倍
此时这个残差单元的输入不能直接加到输出上(大小不一致),而应该在加和前让输入经过一个1x1步长2的卷积层来完成下采样和通道映射——
论文:《Bag of Tricks for Image Classification with Convolutional Neural Networks(2018)》Model Tweak
改进1:推迟下采样
(左:原始的Bottleneck下采样; 右:改进的Bottleneck下采样)
考虑原始的下采样,其中第一个1x1卷积用来作为下采样,所以步长设为了2。但你仔细想想会发现,核大小1x1、步长2的卷积会造成3/4的信息直接丢失。以6x6的特征图为例,如下图所示,只有红色部分的信息能够传递到下一层去,非红色部分均不参与卷积计算。
由此可见,在1x1的卷积层作下采样是不明智的,更好的做法是把下采样过程挪到3x3的卷积上,如下图所示,由于卷积核宽度大于步长,卷积核在移动过程中能够遍历输入特征图上的所有信息(甚至还能有重叠):
改进2:拆解大核卷积
Inception-v1跟ResNet-v1一样都使用了7x7大核卷积,Inception-v3则将其拆解为三个3x3小核卷积,这一操作同样可以借鉴过来改进ResNet-v1。
(左:原始的stem; 右:改进的stem)
改进3:用平均池化替代1x1卷积做下采样
(左:原始的Bottleneck下采样; 中:改进1的Bottleneck下采样; 右:改进1+3的Bottleneck下采样)
还是下采样模块,原本shortcut支路也是用步长为2的1x1卷积做下采样,但如果直接把1x1卷积改为3x3卷积,将大大增加计算量(甚至超过残差路径的计算量),因此用更简单的2x2平均池化实现shortcut支路的下采样,既不会引入太多的额外开销,又不会直接丢失过多的信息。
效果:
(B/C/D分别代表改进1/1+2/1+2+3后的ResNet)
ResNet50-D准确率提高了0.95%,FLOPS增加了13%,但实测速度只下降3%。
论文:《Identity Mappings in Deep Residual Networks(ECCV2016)》
对ResNetv1做了一些有效的改进,使得shortcut的通路更加“干净”,有利于信息的流通,不仅可以训练更深层的网络,而且使得ResNet的表现有了进一步的提升。
残差单元如何缓解梯度消失:
先用数学符号定义残差网络
y l = h ( x l ) + F ( x l , W l ) x l + 1 = f ( y l ) \begin{aligned} \mathbf{y}_{l}=& h\left(\mathbf{x}_{l}\right)+\mathcal{F}\left(\mathbf{x}_{l}, \mathcal{W}_{l}\right) \\ & \mathbf{x}_{l+1}=f\left(\mathbf{y}_{l}\right) \end{aligned} yl=h(xl)+F(xl,Wl)xl+1=f(yl)
其中,
x l \mathbf{x}_{l} xl 是第l个残差单元的输入;
W l = { W l , k ∣ 1 ≤ k ≤ K } \mathcal{W}_{l}=\left\{\mathrm{W}_{l, k}|_{1 \leq k \leq K}\right\} Wl={Wl,k∣1≤k≤K} 是第 l l l个残差单元的一系列权重;
F \mathcal{F} F 表示残差单元的计算过程(不包含最后的ReLU);
h ( x l ) = x l h\left(\mathbf{x}_{l}\right)=\mathbf{x}_{l} h(xl)=xl 表示shortcut的通路;
f f f 表示激活函数
为了方便分析,我们先简化问题,使 x l + 1 = f ( y l ) = y l \mathbf{x}_{l+1}=f\left(\mathbf{y}_{l}\right) = \mathbf{y}_{l} xl+1=f(yl)=yl,则有
x l + 1 = x l + F ( x l , W l ) \mathbf{x}_{l+1}=\mathbf{x}_{l}+\mathcal{F}\left(\mathbf{x}_{l}, \mathcal{W}_{l}\right) xl+1=xl+F(xl,Wl)
那么对任意 L L L,
x L = x l + ∑ i = l L − 1 F ( x i , W i ) = x 0 + ∑ i = 0 L − 1 F ( x i , W i ) \begin{aligned} \mathbf{x}_{L} &= \mathbf{x}_{l}+\sum_{i=l}^{L-1} \mathcal{F}\left(\mathbf{x}_{i}, \mathcal{W}_{i}\right) \\ &= \mathbf{x}_{0}+\sum_{i=0}^{L-1} \mathcal{F}\left(\mathbf{x}_{i}, \mathcal{W}_{i}\right) \end{aligned} xL=xl+i=l∑L−1F(xi,Wi)=x0+i=0∑L−1F(xi,Wi)
对应地,反向传播时有
∂ E ∂ x l = ∂ E ∂ x L ∂ x L ∂ x l = ∂ E ∂ x L ( 1 + ∂ ∂ x l ∑ i = l L − 1 F ( x i , W i ) ) \begin{aligned} \frac{\partial \mathcal{E}}{\partial \mathbf{x}_{l}} &= \frac{\partial \mathcal{E}}{\partial \mathbf{x}_{L}} \frac{\partial \mathbf{x}_{L}}{\partial \mathbf{x}_{l}} \\ &= \frac{\partial \mathcal{E}}{\partial \mathbf{x}_{L}}\left(1+\frac{\partial}{\partial \mathbf{x}_{l}} \sum_{i=l}^{L-1} \mathcal{F}\left(\mathbf{x}_{i}, \mathcal{W}_{i}\right)\right) \end{aligned} ∂xl∂E=∂xL∂E∂xl∂xL=∂xL∂E(1+∂xl∂i=l∑L−1F(xi,Wi))
如此一来,残差单元在前向传播时能直接获得浅层信息,而且在反向传播时不容易出现梯度消失,这也是ResNet有效的主要原因。
即使如此,ResNet-v1在超过200层时依旧会出现明显的过拟合现象。
首先要观察到,前述的分析中为简化问题忽略了激活函数的作用,而v2则指出激活函数妨碍了shortcut通路的信息流通,并尝试改变激活的位置来使得通路更加干净。
shortcut路径通畅的重要性:
作者设计了如下实验,分别为shortcut通路引入各种干扰——比如缩放、门控、丢弃等,发现模型的表现明显下降,以此证明shortcut路径通畅的重要性。
改进方案:改变非线性激活的位置
作者实验了各种激活的位置,得到了更好的设计方式
论文:《Densely Connected Convolutional Networks (CVPR2017)》
多个堆叠的小卷积逐步累积拓宽通道数量,通过拼接复用浅层特征,加强跨层的信息流通。
(DenseBlock示意:四组卷积,且取 k = 4 k=4 k=4)
(各版本DenseNet的具体配置,命名中数字表示“卷积层数量+全连接层数量”)