《Bag of Tricks for Image Classification with CNN》

《Bag of Tricks for Image Classification with CNN》

《Bag of Tricks for Image Classification with Convolutional Neural Networks》论文笔记

这篇文章整理对比了CNN分类网络中常用的一些tricks,例如改善模型结构,训练过程的精修,包括修改损失函数、数据预处理等。值得一读!

论文第二部分先给出了一个训练Resnet-50、Inception-V3、MobileNet网络的baseline。

因为现在在训练过程中使用低数值精度(lower numerical precision)larger batch size会更有效,所以第三部分介绍了一些可以在不牺牲模型精度的同时enable这两种做法works的方法。

3.1.Large-batch training

文中指出,直接使用大的batch size可能会减缓训练过程的速度,因为对于凸优化问题,收敛的速率会随着batch size增大而降低。与此同时,在训练同样的epoches的前提下,用一个更大的batch size训练会导致模型验证集准确率的降低

许多工作用来启发式的解决这个问题。文中介绍了四种方法。

Linear scaling learning rate.

梯度下降是一个随机过程,增大batch size没有改变随机梯度的期望,但是减小了它的方差。换句话说,增大学习率减小了梯度中的噪声(noise),所以,我们应该增大学习率来进行调整。例如我们在batch size=256的时候使用的lr为0.1,那么batch size为b的时候,学习率应调整为0.1*b/256.

Learning rate warmup.

在训练刚开始的时候,所有的参数都是随机值,离最终的结果偏离比较大,如果直接使用较大的lr会造成数值的不稳定(numerical instability),所以我们可以先用一个较小的lr,当训练过程稳定的时候再调回初始的学习率。假设我们前m个batches是用来warmup的,我们设置的初始lr为 \eta ,那么当 1\leq i\leq m 的时候,学习率应该被设置为 i\eta /m

Zero \gamma .

Resnet每一个block最后一层使用了Batch Normalization(BN)层,BN层首先标准化其输出,记为 \widehat{x} ,然后进行尺度的变换,即 \gamma \widehat{x}+\beta 。其中, \gamma\beta 都是可学习的参数,分别被初始化为1和0。而zero \gamma 策略指的是,将所有残差块最后的BN层的 \gamma 参数初始化为0,就相当于减少了层数使得初始阶段更加易于训练。

No bias decay.

一般的是将weight decay应用在所有可学习的参数上,包括weights和bias。然而,更推荐的做法是,只将L2正则化项应用在weights上来避免过拟合。其他参数,包括BN层里的 \gamma\beta 都是不经过正则化的。

除了这四种方法,另外文中也提出,像LARS这种layer-wise adaptive lr更适合于超大的batch size(beyond 16k)。

3.2 Low-precision training

一般的NN是在32-bit浮点数上(FP32)训练的,但随着硬件中增加了对一个低精度数据类型的处理单元,对处理像FP16这样的数据具有更高的算力(FLOPS),使用这种数据类型的数据进行训练的话,容易出现的问题是结果会超出范围从而影响训练过程。有人就提出用FP16对所有的parameters和activations进行存储和梯度的计算,与此同时使用FP32对参数进行拷贝用于参数的更新。另外,在损失函数上乘以一个标量来将梯度的范围更好的对齐到FP16也是一个实用的做法。

模型所需的计算力是如何计算的可以参考[2]中的高票回答。

以上五种做法对实验结果的影响如下表3和4。表三中,感觉有点问题的是,这个实验没有控制变量,因为在改变了数据类型的同时修改了batch_size的大小。

4.Model Tweaks

文中第四部分是对Resnet-50模型架构的修改尝试。图1是原始的resnet,图2是经过修改的三种模型。

图1.Original Resnet Model.
图2.Three Modified Resnet Model.

如图2所示,其中ResNet-B和ResNet-D模型架构修改的思想是修改特定层的strides参数,目的是为了不让1*1的卷积层的strides大于1,从而避免了特征的丢失。而ResNet-C的想法是使用多个小的卷积核3 * 3代替大的 7 * 7 的卷积核。实验结果如表5所示。

表5

5. Training Refinements.

文章中第五部分是通过训练过程中的一些策略来进一步提升模型的准确率。

5.1 Cosine Learning Rate Decay.

被广泛使用的策略是学习率指数下降,也有的是每30 epoches学习率减为0.1倍的.即Step Decay.还有的是每两个epoches降低为0.94倍的。顾名思义,余弦下降即,

\eta _{t} = \frac{1}{2}(1+cos(\frac{t\pi}{T}))\eta

但在论文中展示的,这种做法并不比step decay有准确率上有提升。

5.2 Label Smoothing.

分类问题中one-hot标签存在的问题是,encourage输出score极大限度的区分度高容易导致过拟合,无法保证模型的泛化能力。为了是模型less confident,我们对训练标签做label smoothing。

在tensorflow中,tf.losses.softmax_cross_entropy()函数中有一个label_smoothing的参数,当label_smoothing参数不为0, smooth the labels towards 1/num_classes:

new\_onehot\_labels = onehot\_labels * (1 - label\_smoothing) + label\_smoothing / num\_classes

pytorch的实现可以参考[4].

我们可以认为,此时的损失函数是包括[对预测label和真实label]和[预测label和先验分布]两部分惩罚。

注意这里论文中关于真实值和预测值p,q的顺序应该是弄混了,注意区分。

5.3 Knowledge Distillation.

知识蒸馏的做法是用一个更复杂的teacher model来监督一个student model,目的是为了压缩一个大的网络结构到一个更为紧凑的网络并把知识保留下来。若z和r分别是student model和teacher model的输出,p是真实标签的分布,那么此时的损失函数为,

l(p,softmax(z))+T^{2}l(softmax(r/T),softmax(z/T))

其中,T是超参数代表temperature.

5.4 Mixup Training.

混合训练即随即将两个样本 (x_i,y_i)(x_j,y_j) 进行加权线性插值,其结果作为新的样本用于训练。

\left\{\begin{matrix} \widehat{x} = \lambda x_i +(1-\lambda )x_j \\  \widehat{y} = \lambda y_i +(1-\lambda )y_j \end{matrix}\right.

其中, \lambda\in[0, 1] 是从 Beta(\alpha, \alpha) 分布中的随机值。实验结果如表6所示。

Table 6
最后,之所以称之为Tricks,我们也知道在实际应用中是否有效还得看面向不同数据集的具体的任务,需要我们耐心的尝试,才能找到一个相对最优的方案。


参考资料:

[1]、arxiv.org/abs/1812.0118

[2]、cnn模型所需的计算力(flops)是怎么计算的?

[3]、tensorflow.org/api_docs

[4]、Transformer注解及PyTorch实现(下)

发布于 2018-12-26

文章被以下专栏收录