neural-network - 对同一模型的重复评估定义的损失
问题描述
我有一个模型表示f()
为
假设目标是t
,f(x1) = y1
并且f(x2) = y2
我的损失定义为
loss = mse(y1,y2) + mse(y2,t)
由于y1
和y2
reguires 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()
解决方案
假设目标是
t
,f(x1) = y1
并且f(x2) = y2
我的损失定义为loss = mse(y1,y2) + mse(y2,t)
由于
y1
和y2
reguires 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
)。
推荐阅读
- php - 完全不相关的异常,同时保存多对多关系学说和php
- stock - 表盘的 Fitbit 库存数据
- oracle - 存储过程 - 无法显示未找到数据消息
- wix - WIX 使用引导程序安装所需的软件。错误“提取失败”
- c# - ASP.NET Core 3.1 URL 参数返回不正确的参数值
- azure - 无法从 azure 应用服务连接到 management.azure.com
- python - 有人可以解释这种在 Python 中查找集合的所有子集的逻辑吗?
- c# - 为什么即使 Azure 函数并行运行,Azure Eventhub 批处理消息处理也比单个消息处理更快?
- c++ - 本地类的限定名称
- c++ - 需要帮助来编写一个小程序来乘以多达 n 个元素和 k 个多重性的循环