梯度累积:参考数据并行的方式,梯度累积简单理解是把并行的数据替换成串行的数据传入,可以在显卡数量有限的情况下使用,还没有了解是否影响收敛速度。
具体实现:
正常训练过程:
outputs = model(data_batch)
loss = loss_function(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
梯度累积:
accumulation_steps = 4
outputs = model(data_batch)
loss = loss_function(outputs, labels)
# 2.1 loss regularization loss正则化
loss += loss / accumulation_steps
# 2.2 backward propagation 反向传播计算梯度
loss.backward()
# 3. update parameters of net
if ((i+1) % accumulation)==0:
# optimizer the net
optimizer.step()
optimizer.zero_grad() # reset grdient
学习率可能要增大一些;batchnorm可能需要替换为groupnorm,由于梯度累积的训练batch与测试batch均值方差不同。
在不同框架实现中有所区别,torch需要梯度清空,mxnet计算梯度有两个参数,’write'和‘add',
'write'是默认参数,默认写入新梯度,无需pytorch中每次调用
optimizer.zero_grad();
'add'表示梯度累积,梯度将在每次backward()时增加到已有数据中。
mxnet梯度累积可参考:
通过手动梯度累加方式:acc_grad[:] += parameter.grad()
https://github.com/szhengac/Grad_Accumulation/blob/master/gpu/train.py
通过设置'add‘梯度计算方式,在bind()中 grad_req设置为’add',默认‘write',具体查看executor_group.py,这时需要在参数更新后手动梯度清零。
这两种方式,是mxnet实现梯度累积的方式,具体还没有实现。