1. 一种学习率的优化方式——Warmup
刚开始训练时,模型的权重是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epochs或一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型稳定后再选择预先设置好的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。
2. 梯度累加
梯度累加就是每次获取1个batch的数据,计算一次梯度,梯度不清空,不断累加,累加一定次数后,根据累加的梯度更新网络参数,然后清空梯度,进行下一次循环。一定条件下,batchsize越大训练效果越好,梯度累加则实现了batchsize的变相扩大,如果accumulation_steps为8,则batchsize"变相"扩大了8倍,是实验室解决显存受限的一个不错的trick,使用时需要注意,学习率也要适当放大。BN的估算是在forward阶段就已完成,并不冲突,只是accumulation_steps=8和真实的batchsize放大八倍相比,效果自然是差一些,毕竟8倍Batchsize的BN估算出来的均值和方差更精准一些。
3.混合精度训练
(1)一般的神经网络在训练过程中主要用单精度浮点数float32来存储和计算的。混合精度就是在保证模型训练精度的情况下,利用半精度浮点数float16加速模型的训练,同时还能减少显存的占用。
(2)float16虽然内存占用少,计算更快,但是存在溢出问题和舍入误差。为解决此问题,混合精度训练采用了权重备份、损失缩放和运算精度。
(3)不是所有的GPU都支持float16,拥有TensorCore的GPU(V100和TITAN V系列)。涉及到sum的操作非常容易发生溢出,如果发生不明所以的Nan,可以通过逐步定位前向计算去检查是否部分操作发生了溢出inf的问题。而且在验证的过程中需要保证自己复现每一步时也同时采用float16,否则找不到。
参考:https://zhuanlan.zhihu.com/p/127114884