You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch手动实现简单梯度下降优化器迭代时报错该如何解决?

报错原因分析

你的代码存在两个核心问题导致第二次迭代反向传播报错:

  • 梯度更新时使用q = q - eta * grads的赋值方式,会直接创建一个全新的张量,新张量默认不开启梯度追踪,第二次迭代计算出的loss和无梯度属性的q关联,反向传播时就会抛出找不到梯度函数的错误
  • with torch.no_grad()后缺少冒号,属于语法错误,即使修复第一个问题也会直接运行失败
  • q.requires_grad = True的设置位置错误,不需要每次循环中重复设置,初始化阶段开启即可
手动梯度下降修复后的代码
# 初始化阶段就给q开启梯度追踪
q.requires_grad_(True)
eta = 0.01
for i in range(10):
    # 每次迭代前先清空上一轮的梯度,避免梯度累加
    if q.grad is not None:
        q.grad.zero_()
    print('i =', i, ' q =', q)
    v_trans = forward(v, q)
    loss = error(v_trans, v_target)
    loss.backward()
    # 用inplace操作更新q,不创建新张量,保留梯度属性
    with torch.no_grad():
        q -= eta * q.grad

print('Final q = ', q)
非神经网络项目使用PyTorch内置优化器的方法

PyTorch的内置优化器并非只能用于神经网络场景,任何需要梯度优化的张量都可以直接调用,无需手动实现梯度更新逻辑,使用示例如下:

import torch.optim as optim

# 初始化待优化张量,开启梯度追踪
q.requires_grad_(True)
eta = 0.01
# 实例化优化器,把需要优化的张量传入即可,支持SGD、Adam等所有内置优化器
optimizer = optim.SGD([q], lr=eta)
# 对学习率调整不熟悉的场景可以直接用Adam,收敛更稳定
# optimizer = optim.Adam([q], lr=eta)

for i in range(10):
    # 固定步骤:清空上一轮梯度
    optimizer.zero_grad()
    print('i =', i, ' q =', q)
    v_trans = forward(v, q)
    loss = error(v_trans, v_target)
    # 反向传播计算梯度
    loss.backward()
    # 优化器自动完成参数更新
    optimizer.step()

print('Final q = ', q)

额外注意事项

  • 所有参与loss计算、需要被优化的张量,都要在计算图构建前开启requires_grad=True,不要在计算过程中中途开启或者用赋值操作替换原张量
  • 固定取值的张量(比如示例中的v、v_target)不需要开启梯度,能节省显存和计算开销
  • 不管是手动更新参数还是用内置优化器,每次迭代前必须清空上一轮梯度,否则PyTorch会默认累加梯度,导致更新逻辑错误

内容的提问来源于stack exchange,提问作者Notin_sensus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:15:08