例如,我想使用一些辅助损失来提升我的模型性能。
哪种类型的代码可以在pytorch中实现?
#one
loss1.backward()
loss2.backward()
loss3.backward()
optimizer.step()
#two
loss1.backward()
optimizer.step()
loss2.backward()
optimizer.step()
loss3.backward()
optimizer.step()
#three
loss = loss1+loss2+loss3
loss.backward()
optimizer.step()
感谢您的回答!
最佳答案
第一次和第三次尝试完全相同且正确,而第二种方法完全错误。
在 Pytorch 中,低层梯度不会被随后的 backward()
调用“覆盖”,而是被累积或求和。这使得第一种和第三种方法相同,但如果您的 GPU/RAM 内存较低(批处理大小为 1024,一次 backward() + step()
调用与具有8 个大小为 128 的批处理和 8 个 backward()
调用,最后有一个 step()
调用。
为了说明这个想法,这里有一个简单的例子。我们想让张量 x
同时接近 40,50 和 60
:
x = torch.tensor([1.0],requires_grad=True)
loss1 = criterion(40,x)
loss2 = criterion(50,x)
loss3 = criterion(60,x)
现在是第一种方法:(我们使用 tensor.grad
来获取张量 x
的当前梯度)
loss1.backward()
loss2.backward()
loss3.backward()
print(x.grad)
此输出:tensor([-294.])
(编辑:将 retain_graph=True
放在前两个 backward
调用中以获得更复杂的计算图)
第三种方法:
loss = loss1+loss2+loss3
loss.backward()
print(x.grad)
再次输出:tensor([-294.])
第二种方法不同,因为我们在调用 step()
方法后不调用 opt.zero_grad
。这意味着在所有 3 个 step
调用中使用第一个 backward
调用的梯度。例如,如果 3 次损失为相同的权重提供梯度 5,1,4
,而不是 10 (=5+1+4),现在您的权重将为 5*3+1 *2+4*1=21
作为梯度。
关于python - 我如何处理pytorch中的多重损失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53994625/