ResNet 训练 Bag of Tricks 精读笔记
最近读了一篇很实用的论文——《Bag of Tricks for Image Classification with Convolutional Neural Networks》,主要思路是把一堆训练技巧叠在一起,把 ResNet-50 在 ImageNet 上的 Top-1 精度从 75.3 提升到 79.29。整体内容按章节走,逐一记录。
标准训练流程(Baseline)
论文第 2 章先把标准训练流程讲清楚,作为后续比较的 baseline。
训练阶段数据预处理步骤:
- 将图片转换为 32 位 float,像素值放到 [0, 255] 范围内;
- 随机裁剪一个矩形区域,长宽比在 3/4 到 4/3 之间,裁剪后 resize 到 224×224;
- 以 0.5 的概率随机水平翻转;
- 调整亮度、饱和度等颜色属性;
- 加入 PCA 噪声,噪声系数从 N(0, 0.1) 中采样;
- 归一化。
验证阶段则是保持长宽比将短边缩放到 256,然后在中心 crop 出 224×224。
网络初始化统一使用 Xavier,优化器是 Nesterov Accelerated Gradient,硬件是 8×V100,共训练 120 个 epoch,batch size 256,初始学习率 0.1,在第 30、60、90 个 epoch 时各衰减为原来的 1/10。
面向新硬件平台的训练技巧
第 3 章讨论的是面向现代 GPU 硬件的工程层面 trick。
大 Batch 与学习率线性缩放
在凸优化中 batch size 越大收敛速度会下降,神经网络上也观测到类似现象:同等 epoch 下,小 batch size 往往能取得更好的验证集精度。把 batch size 从 256 调到 1024,大概会损失 0.x% 的 Top-1 精度。
增大 batch size 不改变随机梯度的期望,只会减小其方差,也就是降低梯度噪声。这时可以对应调大学习率——建议线性缩放:256 对应 0.1,512 对应 0.2,以此类推。
Warm-up
直接从很大的学习率起步容易不稳定,可以配合 warm-up:在训练最开始的 n 个 epoch(比如 5 个)将学习率从 0 线性增加到初始学习率。
Weight Decay 的施加范围
weight decay 最好只加在卷积层和全连接层的权重上,不要加在 bias 上,BN 层的参数(gamma、beta)也不要加 weight decay。
低精度训练(FP16)
在 V100 上从 FP32 切换到 FP16 计算,速度可以提升 2~3 倍——V100 的 FP32 算力约 14 TFLOPS,FP16 约 100 TFLOPS。
直接用 FP16 会干扰训练,一种方式是把所有参数和激活值存为 FP16,参数更新时使用 FP32 做累加。另一个实用办法是在 loss 上乘一个标量,将梯度数值限制在 FP16 可表示的范围内,同样可以加速。
网络结构上的微调
第 4 章是直接对 ResNet 做了几处细小的结构改动,并提出了一个改进变体,属于网络设计层面的调整,这里不展开。
训练过程的额外改良
第 5 章介绍了几个对精度提升比较明显的训练技巧。
Cosine 学习率衰减
原始 ResNet 用的是 step decay(阶梯式垂直下降),换成 cosine 衰减之后可以把精度提升将近一个点。
Label Smoothing
label smooth 同样能带来将近一个点的精度提升,实现简单,效果稳定。
Knowledge Distillation
利用 KD:在 softmax 输出的分类 loss 基础上,加上一项和 teacher 模型输出分布之间的 KD loss,让 student 从 teacher 的软标签中获取更多监督信号。
Mixup
mixup 数据增强也有效果,但需要注意:用了 mixup 之后要训练更长的时间,论文里是从 120 epoch 增加到了 200 epoch。
迁移学习效果
第 6 章讨论这些 trick 在迁移学习场景下的效果。最近接触这块不多,先暂时忽略。