资讯动态

opt梯度计算

发布时间:2026/10/31 7:20:34 来源:尧图企业网站定制
为什么先zero_grad()再保存梯度然后梯度下降因为loss.backward()会把新算出的梯度累加到参数的.grad里而不会自动覆盖旧梯度。普通训练时我们希望每个 batch 根据自己的梯度更新所以先清掉上一个 batch 留下的梯度opt.zero_grad() # 清除之前保存的梯度 loss.backward() # 计算当前 batch 的梯度存入参数的 .grad opt.step() # 根据这些梯度更新参数比如某个参数情况上一批留下的梯度当前批算出的梯度更新时使用的梯度先清除清为 033不清除235清掉的是“上一次该怎么调整参数”的梯度模型参数本身不会被清零之前学到的东西也不会丢失。另外opt.step()更新参数后梯度仍然留着所以处理下一批时还需要清除。只有刻意做“梯度累积”、合并多个 batch 的梯度时才会暂时不清。opt.step()内部如何算opt.step()会读取各个参数的.grad计算调整量再直接修改模型里的参数。具体怎么算取决于opt是哪种优化器。你这条 IEKT 流程用的是Adam创建位置在 [wandb_train.py 第 138 行 (line 138)](D:/pykt-work/pykt-toolkit/examples/wandb_train.py:138)opt torch.optim.Adam( model.parameters(), lrlearning_rate, weight_decay1e-6 )这里已经把模型参数交给opt管理了所以调用opt.step()时不用再传参数。可以类比 Javaopt保存着这些参数对象的引用更新的是同一批对象。Adam 除了当前梯度还会为每个参数保存两份历史变量保存什么用途m梯度的移动平均综合最近的梯度方向v梯度平方的移动平均调整更新幅度对一个参数w一次step()的核心计算可以写成下面这样。m、v、t初始为 0此后每次更新都保留g w.grad # backward() 已经算好的梯度 g g weight_decay * w # 加上权重衰减项 t t 1 # 更新次数增加 m 0.9 * m 0.1 * g v 0.999 * v 0.001 * g**2 m_hat m / (1 - 0.9**t) # 修正从零初始化造成的偏小 v_hat v / (1 - 0.999**t) w_new w - lr * m_hat / (v_hat**0.5 1e-8)实际实现会把最后算出的值写回模型参数。这里使用的是 Adam 默认系数。PyTorch 官方说明拿一个数算一遍假设第一次更新时参数 w 0.5 梯度 g 0.2 学习率 lr 0.001 历史 m 0v 0为了方便观察暂时忽略很小的权重衰减项和分母中的1e-8计算结果m 0.9×0 0.1×0.20.02v 0.999×0 0.001×0.2²0.00004m_hat 0.02 ÷ (1−0.9)0.2v_hat 0.00004 ÷ (1−0.999)0.04调整量 0.001 × 0.2 ÷ √0.040.001新参数 0.5 − 0.0010.499下一批数据做前向计算时就使用更新后的0.499。联系你刚才问的zero_grad()它清除的是.grad不会清除 Adam 保存的m、v。所以下一次step()会结合新梯度和保留下来的历史重新计算调整量并不是每次都固定减去0.001。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑