[论文阅读]Bag of Tricks for Image Classification with Convolutional Neural Networks
Abstract
作者介绍了几种常用的tircks,这些tricks能够明显提高普通网络的精度
Trainning Procedures
Training Steps
-
将图片转成RGB
-
随机在原图像中裁剪出一个矩形区域,其长宽比为[3/4,4/3],同时大下会在[8%,100%]这个区间选择。然后将图片resize到224-by-224
3.0.5的几率随机水平翻转
4.随机改变色调,饱和度,亮度,比例区间为[0.6,1.4]
5.添加PCA噪声,系数服从 N ( 0 , 0.1 ) N~(0,0.1) N (0,0.1)分布
6.Normalize RGB channels
7.初始化方式
-
卷积层的初始化方式使用Xavier algorithm,bias 初始化为0
-
BN层的 γ \gamma γ 初始化为1, β \beta β初始化为0
8.最初的学习率为 1 ,分别在30,60,60个epoch的时候将学习率除以10
Efficinet Training
linear scaling learning rate
在训练的时候使用更大的batch size更有效
假设的求得的梯度结果服从某种分布,较大的batch size所得的结果方差更小,可信度越高,所以相对应的learning rate应该更大。同时还可以提高收敛的速度
其中lr 和 batchsize的大小应该成正比
learning rare warmup
在训练的最开始,所有的参数都是随机的,和最终的收敛结果相差很远。这个时候使用较大的学习率将会导致数值不稳定。
所以采用学习率热身的方法,设定到达第m个batch时才会达到预设的学习率,之前为
i
η
/
m
i\eta/m
iη/m
zero γ \gamma γ
在所有的残差模块的最后一个BN层,将BN层的 γ \gamma γ系数设置为0,这样每一个残差模块的最开始的输出将会都是原本的输入
no bias decay
不要使用bias decay,而只是使用weight decay。同时只在卷积层和FC层使用weight decay而在BN层不要使用
low precision training
通常的神经网络采用的都是FP32类型,但显卡对于低精度的数据运行速度更快训练的时间也减少
同时低精度的数据范围更窄,所以更容易超范围。所以有人就现在FP32上拷贝一份运算,然后转到FP16上去(这样训练时间不还增加了吗)
直观上感觉变换到FP16之后数据之间分布跨度变大了,解的空间也变小了,所以微小的扰动对于整体结果的影响变小了。所以不容易过拟合。
Model Tweaks
最原始的resnet
- 最开始为一个7x7的conv(stride=2) + 3x3的maxpooling(stride = 2)
ResNet-B
注意到Path A中一开始使用了1x1conv(s = 2),这样减少了3/4的信息
所以将第一层的conv的s变为1,第二层3x3conv的s变为2
ResNet-C
将最开始的7x7的conv变为了3个3x3的conv,其中第一个的步长为2
保持了感受野不变并且参数更少
ResNet-D
注意到Path B的1x1conv 步长也为2,忽略了3/4的信息。所以先做一个2x2 avg_pool然后做1x1 conv(感觉越深效果越好)
Training Refinements
Cosine Learning Rate Decay
使用余弦衰减函数
η t = 1 2 ( 1 + c o s ( t π T ) ) η \eta_t = \frac 12(1+cos(\frac{t\pi}{T}))\eta ηt=21(1+cos(Ttπ))η
(虽然我感觉好像没啥人用)
Label Smoothing
将 [0,1] 标签转变为 [1- ϵ , ϵ / ( K − 1 ) \epsilon, \epsilon/(K-1) ϵ,ϵ/(K−1)]
Knowledge Distillation
知识蒸馏(不是很了解)
Mixup Training
将两张图片混合起来
x ^ = λ x i + ( 1 − λ x j ) \hat{x} = \lambda x_i+(1-\lambda x_j) x^=λxi+(1−λxj)
y ^ = λ y i + ( 1 − λ y j ) \hat{y} = \lambda y_i+(1-\lambda y_j) y^=λyi+(1−λyj)
然后分别计算和两张图片的loss
l o s s = λ l o s s i + ( 1 − λ ) l o s s j loss = \lambda loss_i + (1-\lambda) loss_j loss=λlossi+(1−λ)lossj