目前正在尝试使用以下逻辑实现线性回归的自定义损失函数:* 如果模型输出值大于或等于目标,则回波损耗为(输出-目标)。* 如果模型输出值小于目标,则回波损耗为(目标-输出)^2
以下是我当前的实现:
import torch.nn as nn
class E_Loss(nn.Module):
def __init__(self, weight=None, size_average=True):
super(E_Loss, self).__init__()
def forward(self, inputs, targets, smooth=1):
inputs = inputs.view(-1)
targets = targets.view(-1)
is_greater = torch.gt(inputs, outputs)
print(is_greater)
if is_greater: #torch.gt(inputs, targets):
loss = (inputs - targets)
else:
loss = np.square(targets - outputs)
return loss
当运行我的模型进行训练时,我在loss. backward()step上得到这个错误:运行时错误:只能为标量输出隐式创建grad
假设它需要一个标量输出,我如何重写我的损失函数来产生这个?重写我的代码不使用数据加载器会更容易吗?
以下是整个模型部分
x一个一个一个一个x一个一个二个x
1条答案
按热度按时间x3naxklr1#
你发布的代码没有任何意义
is_greater = torch.gt(inputs, outputs)
使用了未定义的变量outputs
。torch.gt
是一个基于元素的大于运算,除非inputs
和outputs
都是标量,否则在条件语句中使用它的结果是没有意义的。由于批处理大小为64,因此应该会得到一个异常RuntimeError: Boolean value of tensor with more than one value is ambiguous
。np.square
。这是不明确的,可能会也可能不会起作用,这取决于它是如何实现的。使用PyTorch函数和PyTorchTensor。Tensor支持大多数python运算符,所以只需要使用x**2
或x*x
来做元素平方。您提出的错误表明,尽管存在所有明显的错误,您仍然能够运行损失函数代码,但反向传播失败,因为损失函数不是标量值。您发布的代码对我来说无法运行,而且似乎也没有执行任何形式的均值缩减。假设上述问题得到解决,并且它实际上运行。那么我就预料到你会遇到这样的错误。出现这个错误是因为
Tensor.backward
要求Tensor是标量值,即损失应该是一个数字。通常,这是通过对整个批次的损失求平均值来实现的。为了解决损失函数的实现问题,如果将所描述的函数视为
output - target
的函数,则该函数更容易实现。由于output >= target
等价于output - target >= 0
,因此在令x = output - target
之后,我们只需要在x
为非负时等于x
,否则等于x**2
的函数。这可以通过不同的方法来实现,但一个简单的方法是认识到
Tensor.relu
可以用来将函数分解为正项和负项x = relu(x) + (-relu(-x))
。使用这个恒等式,很有可能很清楚你想要的是loss = relu(x) + relu(-x)**2
。解决均值缩减问题以及损失函数的工作版本可以是: