PyTorch简单神经网络W1梯度为None,如何通过反向传播优化输入层权重
问题原因与修复方案
核心问题原因
- 计算隐层输出
h时使用torch.tensor()手动拼接张量,直接切断了W1到h的计算图,导致梯度无法回传到W1,因此W1.grad始终为None - 其他影响运行的问题:
- 训练循环内重复实例化优化器,会每次重置优化器状态,导致动量等参数失效
- 未定义
criterion就直接调用,存在运行报错隐患 - 反向传播前未清空梯度,会导致多轮梯度累加,更新逻辑错误
- 你尝试的手动计算方案中用到
math.tanh等Python原生数学库算子,同样会脱离PyTorch计算图,导致梯度中断
修复方案
1. 修正forward方法的计算逻辑
直接对xW1整体调用tanh,不需要拆分后再用torch.tensor()拼接,保留完整计算图链路:
def forward(self, X): self.xW1 = torch.matmul(X, self.W1) self.h = torch.tanh(self.xW1) # 直接对整个张量做tanh,保留梯度 return torch.sigmoid(torch.matmul(self.h, self.W2))
2. 修正训练循环逻辑
将优化器、损失函数定义移到循环外,每次反向传播前清空梯度:
import torch import torch.nn as nn X = torch.tensor(([1, 2]), dtype=torch.float) y = torch.tensor([1.]) learning_rate = 0.001 class Neural_Network(nn.Module): def __init__(self, ): super(Neural_Network, self).__init__() self.W1 = torch.nn.Parameter(torch.tensor(([1, 0], [2, 3]), dtype=torch.float, requires_grad=True)) self.W2 = torch.nn.Parameter(torch.tensor(([2], [1]), dtype=torch.float, requires_grad=True)) def forward(self, X): self.xW1 = torch.matmul(X, self.W1) self.h = torch.tanh(self.xW1) return torch.sigmoid(torch.matmul(self.h, self.W2)) net = Neural_Network() # 优化器、损失函数在循环外定义一次即可 optim = torch.optim.SGD(net.parameters(), lr=learning_rate, momentum=0.9) criterion = nn.MSELoss() for z in range(60): optim.zero_grad() # 清空上一轮梯度,避免累加 pred = net(X) loss = criterion(pred, y) loss.backward() optim.step()
修复后运行可以看到W1正常产生梯度,参数得到更新。
内容的提问来源于stack exchange,提问作者OuttaSpaceTime
相关产品推荐
相关产品推荐

