对同一模型的重复评估定义的损失

时间:2021-04-17 05:10:30

标签: neural-network pytorch

我有一个用 f() 表示的模型,

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

由于 y1y2 都要求 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.在向后做之前累积损失张量,即

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() 

1 个答案:

答案 0 :(得分:1)

<块引用>

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

由于 y1y2 都要求 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()

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

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

enter image description here

这里唯一的问题可能是您的函数 f 不可微分或以某种方式无效(可能在就地分配中发生在 f 中)。