神经网络中张量均为leaf但loss反向传播返回None的问题求助
问题分析与解决建议
核心问题拆解
- loss与可训练变量无梯度关联:你用
Variable(loss2_function(), requires_grad=True)定义loss的方式完全错误。首先PyTorch早已不需要手动用Variable包装张量,其次如果loss2_function()的计算过程没用到w1、b1,那loss和这两个可训练参数之间就没有梯度通路,反向传播自然不会生成梯度。另外loss.backward()本身就返回None,这是PyTorch的正常设计,它的作用是把梯度计算出来存到张量的grad属性里,不是返回梯度值。 - 参数更新逻辑混乱:你既手动用
with torch.no_grad()更新w1、b1,又调用optimizer.step(),等于让参数被更新两次,逻辑完全冲突。 - 梯度清零顺序错误:手动更新后立刻清零梯度,再调用
optimizer.zero_grad(),会导致梯度管理混乱,正确的做法是在每次计算loss前先清零梯度。
修正后的代码示例
def train_step(w1, b1): print("w=", w1) trainable_variables = [w1, b1] optimizer = torch.optim.SGD(trainable_variables, lr=learning_rate) # 先清零上一轮残留的梯度 optimizer.zero_grad() # 计算loss:必须确保loss2_function内部用到了w1和b1,形成有效计算图 loss = loss2_function() # 反向传播计算梯度,此时w1.grad、b1.grad会被填充 loss.backward() # 用optimizer统一更新参数 optimizer.step()
关键注意事项
- 务必检查
loss2_function()的实现,确保它的计算过程依赖w1和b1,否则梯度永远不会生成。 - 不要同时混用手动参数更新和optimizer更新,二者选其一即可,优先用optimizer管理参数,避免手动操作出错。
loss.backward()返回None是正常现象,不需要纠结这个,只需要检查w1.grad和b1.grad是否有值即可判断反向传播是否有效。
内容的提问来源于stack exchange,提问作者A12
相关产品推荐
相关产品推荐

