首页 > 解决方案 > 对同一模型的重复评估定义的损失

问题描述

我有一个模型表示f()

假设目标是tf(x1) = y1并且f(x2) = y2我的损失定义为
loss = mse(y1,y2) + mse(y2,t)

由于y1y2reguires grad,我收到了错误,例如

梯度计算所需的变量之一已被就地操作修改

我的理解是,假设我首先评估 y1,图表在我评估 y2 时发生了变化。我应该修复一些张量,例如,y1_no_grad = y1.detach().numpy()然后使用 loss = mse(y1_no_grad,y2) + mse(y2,t)
但是,我仍然收到错误Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy(),我不确定是否是因为 y1_no_grad 是一个 numpy 数组,而 y2 是一个张量。

更新:

后来我才意识到我的问题。这是因为我创建了多个损失张量,并且我首先后退了一个损失张量,它就地更改了参数。当我想后退另一个损失张量时,这会导致错误。

例如

f(x1) = y1
f(x2) = y2
f(x3) = y3 
...
f(xn) = yn

f(x) = y

for i in range(n):
    optimizer.zero_grad()
    loss = mse(y,yi) + mse(yi,t)
    loss.backward()
    optimizer.step()

对我来说,解决方案是:

1.在做backward之前累积损失张量,即

for i in range(n):
    loss = mse(y,yi) + mse(yi,t)
    loss.backward()
optimizer.step()

2.在每次后退之前再次评估,即:

for i in range(n):
    optimizer.zero_grad()
    y = f(x)
    yi = f(xi)
    loss = mse(y,yi) + mse(yi,t)
    loss.backward()
    optimizer.step() 

标签: neural-networkpytorch

解决方案


假设目标是tf(x1) = y1并且f(x2) = y2我的损失定义为 loss = mse(y1,y2) + mse(y2,t)

由于y1y2reguires grad,我收到了错误,例如

这种说法是不正确的。您所描述的不需要就地分配错误。例如

import torch
from torch.nn.functional import mse_loss

def f(x):
    return x**2

t = torch.ones(1)

x1 = torch.randn(1, requires_grad=True)
x2 = torch.randn(1, requires_grad=True)

y1 = f(x1)
y2 = f(x2)

loss = mse_loss(y1, y2) + mse_loss(y2, t)
loss.backward()

不会产生任何错误。可能您的问题在其他地方。

对于您描述的一般情况,您应该得到一个可以可视化为的计算图

在此处输入图像描述

这里唯一的问题可能是您的函数f不可区分或在某种程度上无效(可能就地分配发生在 中f)。


推荐阅读