存在的问题:在模型训练过程中,虽然增加minibatchsize能够提高模型的泛化能力,并且加快模型的收敛。但是当超过8k的时候,会出现难以优化的情况,并且泛化能力也大大下降。
为此作者提出了
liner scale rule 以及warm up
以及在实验中对于多卡训练中包括权值更新等的一些思考以及看法。
对于传统的SGD:
这里是作者提出的:当minibatch size 乘以k,也即总得batchzie为kn,相应的学习率也乘以k
首先我们看下当minibatch为n,经过k代的SGD后,权值的更新情况:
而如果这里直接将学习率乘与k的话,权值的更新情况:
要让这两条公式相等,就只能假设
但是由于这个假设并不能真的正确,所以会出现以下的情况:
1.是会在网络开始训练的前几代,网络的表现会激烈变化
2.是minibatch不能任意地增加,达到8k的时候仍然会出现figure1中的情况
所以作者提出了warmup这个概念,也就是在网络训练的初期不选择太多“急剧”的学习率。作者提出了两种warmup!
1.是Constant warmup
在前五代设置 lr = x,当过了五代以后,设置学习率为k*x。
这种warmup形式对于objectdection,segmentation这些在pretrain_model后面加上新的对应层的task很有帮助。但是这种形式还是难以解决优化困难的问题,并且当五代,结束学习率改变的时候,错误率会激增。所以提出了第二种
2.Gradual warmup
首先第一代设置 lr = x,在第五代结束的时候,lr为 kx,在这五代期间,每一代按代数关系慢慢将x增加到kx。这样避免了学习率急剧的变化
BN
在公式1,2中,我们都是假设每一样本的loss是独立的,但在BN的计算中,由于BN的计算,这些样本的loss并不是独立的,所以lossfunction的也会改变
所以;
也即将B(一个bacthsize,size为n)看做为总batchsize(size为kn)的集合xn的一个sample,所以就能将每一个sample的loss独立计算。
注意当n设置为不一样的时候,BN计算出来的mean,variance的也会随机变化。所以我们把每张卡上面的n都固定住,所以原本的3,4变为了
而关于Distributed SGD,作者也提出了一些看法;
1.是weight decay
一般的lossfunction为
这里作者把weightdecay定义为
也即是这里面中的第一项
可以看到如果没有这个weight decay这一项,把predictionloss这一项也乘以k,是与lr乘以k的效果一样的,但是,现实就是这样子,所以得出了第一个结论:
由于weightdecay的存在,所以
2.是Momentun correction,
加上momentun的SGD的表达式为下:
而在kn中,由于采取k倍的学习速率,上面的公式改为;
可以看到在9中u是只与梯度相关的,而与学习率无关。但在10中,v是与学习率有关的,当学习率改变的时候(warmup),为了和9学习率改变时一样,我们应该做以下变换
将:
作者发现这个修正很重要尤其当下一代的学习率远远大于当代的学习率的时候,所以得到第二个结论:
3.gradient aggregation
根据(4)中的:
可以看到要进行gradient aggregation的话,要对kn个sample的loss求平均,
这样对每个卡来说就要对n个sample的loss求平均。聚合后再除以k,求得平均loss
然而对于现在的显卡之间的通讯来说,求和比求平均更有效率。
所以作者觉得先在每一张卡的loss的求解中加上1/k的scaling,再通讯求和更有效率
所以第三个结论:
4.Data shuffling:
在普通SGD中每一个epoch,对train_set做Data random shuffing,会让结果更好。
为了和这个使用shuffle的baseline做平等对比,作者也要求每一个epoch,对trainset做shuffle,然后分为k部分,分配给k张卡(或者设备)。
所以第四个结论:
但是由于前面存在的近似问题,所以大于8k的时候就gg。