PyTorch中两次前向传播单次反向传播的正确性及方法差异咨询
问题解答
方法一的正确性判断
方法一是正确的,完全匹配你“对两个数据集前向传播、基于总损失执行反向传播、更新单个模型”的需求。
你先分别计算两个样本对应的损失loss1和loss2,将二者求和得到总损失后执行反向传播,PyTorch会自动累加两个损失对应的梯度,最终通过optimizer.step()完成一次参数更新,逻辑完全符合预期。
两种方法的差异
这两种方法最终的参数更新结果完全等价,但执行过程存在细微区别:
- 梯度计算方式不同:
- 方法一:先计算两个损失并求和,仅执行一次
backward(),PyTorch会一次性计算总损失对所有参数的梯度。 - 方法二:分别对
loss1和loss2执行backward(),PyTorch会自动将两次计算的梯度累加在参数的.grad属性中,最后通过optimizer.step()完成一次更新。
- 方法一:先计算两个损失并求和,仅执行一次
- 内存占用略有差异:
方法一需要同时保留loss1和loss2对应的计算图;方法二中,默认执行loss1.backward()后计算图会被释放,内存占用会稍低,但该差异在大多数场景下可以忽略。
注意:如果在方法二中两次backward()之间调用了optimizer.zero_grad(),结果会和方法一完全不同——梯度会被清零,最终仅用loss2的梯度更新参数。但你给出的方法二没有这一步,因此和方法一等价。
示例代码回顾
初始代码:
import torch import torchvision.models as models model = models.resnet18() optimizer = torch.optim.SGD(model.parameters(), lr=1e-3) x = torch.randn(1, 3, 224, 224) y = torch.randn(1, 3, 224, 224)
方法一代码:
loss1 = model(x).mean() loss2 = model(y).mean() (loss1+loss2).backward() optimizer.step()
方法二代码:
loss1 = model(x).mean() loss1.backward() loss2 = model(y).mean() loss2.backward() optimizer.step()
内容的提问来源于stack exchange,提问作者kowser66
相关产品推荐
相关产品推荐

