通俗理解深度学习梯度累加(Gradient Accumulation)的原理

首先你得明白什么是梯度,可以看我之前写的一篇博客 :

微分与梯度的概念理解

本质上,梯度是一种方向导数,是一个矢量,因此这里的梯度累加并不是简单的相加,而是类似于初高中物理学的力的合成,梯度作为一种方向导数(矢量)的其累加的效果就是将各个小的梯度合成为一个指向Loss function 最终优化方向的梯度。

这里结合代码理解一下:

正常训练的过程

for i, (images, labels) in enumerate(train_data):
    # 1. forwared 前向计算
    outputs = model(images)
    loss = criterion(outputs, labels)

    # 2. backward 反向传播计算梯度
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

梯度累加的训练过程

# 梯度累加参数
accumulation_steps = 4


for i, (images, labels) in enumerate(train_data):
    # 1. forwared 前向计算
    outputs = model(imgaes)
    loss = criterion(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_steps)==0:
        # optimizer the net
        optimizer.step()
        optimizer.zero_grad() # reset grdient

以上代码来自:

https://www.zhihu.com/question/435093513/answer/2302992975

可以看出,梯度累加的训练过程中,每次反向传播都会计算出一个梯度,但是并不会使用optimizer.step() 更新参数,直到达到设定的累计次数后,才一次性的将参数依据累积的梯度进行更新。(殊途同归,每次计算出来的梯度可以看作是一个具有微弱方向变化的矢量,不断叠加,最终合成一个具有特定方向的矢量。每次变化一点点,和将每次一点点的变化累积起来形成一个最终的变化方向,这在效果上是没有太大差异的),梯度累积可以实现和使用大的Batch Size 接近的效果,但是消耗的GPU显存却不会显著增加,这在GPU显存有限的情况下,是一种较为不错的训练方法。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

daimashiren

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值