PyTorch Autograd梯度未正常生成:参数grad仍为None求助
问题解决:Autograd中参数grad为None的原因及修复方案
核心问题分析
问题出在loss=ce_loss(torch.tensor(y_hat,requires_grad=True),y)这一行:
- 你手动创建了一个新的
torch.tensor并设置requires_grad=True,这个新张量是独立的叶子节点,完全切断了它和之前par参与计算的y_hat张量之间的计算图关联。 - 原
y_hat列表里的每个元素都是由act(par@obs)生成的,它们的计算图和par相连,但重新包装成新张量后,这个关联被破坏,反向传播时自然不会更新par的梯度。
修复方案
方案一:保留计算图的张量拼接
直接用torch.stack()或torch.cat()把y_hat列表转换成张量,不要手动设置requires_grad=True:
ce_loss=torch.nn.BCELoss() par=torch.randn((1,n),requires_grad=True) act=torch.nn.Sigmoid() y_hat=[] for obs in data: y_hat.append(act(par@obs)) # 用stack拼接列表中的张量,保留原计算图关联 loss=ce_loss(torch.stack(y_hat), y) loss.backward()
方案二:批量运算替代循环(更高效)
如果data是批量数据,建议直接用批量运算避免循环,同时从根源上避免这类问题:
ce_loss=torch.nn.BCELoss() par=torch.randn((1,n),requires_grad=True) act=torch.nn.Sigmoid() # 假设data是形状为(batch_size, n)的张量 y_hat = act(par @ data.T) # 批量计算,得到形状为(1, batch_size)的张量 loss=ce_loss(y_hat.squeeze(), y) # 根据y的形状调整维度 loss.backward()
注意事项
- 不要随意手动创建带
requires_grad=True的张量来包装已有计算图中的张量,这会打断梯度传播链。 - 列表中的张量通过
stack/cat拼接后,会保留原有的计算图信息,反向传播时就能正常追溯到par。
内容的提问来源于stack exchange,提问作者misc misc
相关产品推荐
相关产品推荐

