pytorch中的反向传播与梯度累加

1.反向传播简要概括

pytorch的计算图中,只有两种元素: 数据(tensor)和运算。tensor可以分为两类,叶子节点(leaf node)和非叶子节点。使用backward()函数反向传播计算tensor的梯度时,并不计算所有tensor的梯度,而是只计算满足这几个条件的tensor的梯度:1.类型为叶子节点、2.requires_grad=True、3.依赖该tensor的所有tensor的requires_grad=True。

神经网络模型中前传与后传的简要逻辑如下:

        ①初始化网络,动态图在此时创建 -> net = model()

        ②前向传播 -> outputs = model(inputs)

        ③计算输入的损失 -> loss = loss_fn(outputs, labels)

        ④将损失反向传播,通过链式法则计算各点的梯度,动态图销毁 -> loss.backward()

        ⑤更新梯度 -> optimizer.step()

        ⑥梯度清零 -> optimizer.zero_grad()

计算完成后,动态图被销毁,仅叶节点的梯度grad被保存,非叶节点内存将被释放(中间变量)。这里需要注意的是区分网络中的叶节点和非叶节点,神经网络模型的参数基本都以叶节点形式出现,因此在梯度反传后期grad仍然存在,用于后续处理(参考文章2中对动态图结构的二叉树解释)。

2.梯度累加

理清上面关于神经网络的前传与后传逻辑后,梯度累加就很好理解了。在步骤④,得到当前计算的loss关于各参数矩阵的梯度后,先不进行⑤⑥步的梯度更新与清零。而是反复积累几次后,再一次性更新梯度以及将各参数对应的梯度清零。代码逻辑可参考文章3。

参考文章:1.pytorch计算图_xinming_365的博客-CSDN博客_pytorch计算图

2.Pytorch的backward()相关理解_DHexia的博客-CSDN博客_backward pytorch

3.pytorch中如何做梯度累加 - 知乎

你可能感兴趣的:(pytorch,深度学习,人工智能)