PyTorch 中自定义损失函数变量输入的 AttributeError
AttributeError on variable input of custom loss function in PyTorch
我制作了一个自定义损失函数来计算多输出多标签问题的交叉熵 (CE)。在 class 中,我想将我输入的目标变量设置为不需要梯度。我在前向函数中使用 class.
之外的预定义函数(取自 pytorch 源代码)执行此操作
def _assert_no_grad(variable):
assert not variable.requires_grad
def forward(self, predicted, target):
"""
Computes cross entropy between targets and predictions.
"""
# No gradient over target
_assert_no_grad(target)
# Define variables
p = predicted.clamp(0.01, 0.99)
t = target.float()
#Compute cross entropy
h1 = p.log()*t
h2 = (1-t)*((1-p).log())
ce = torch.add(h1, h2)
ce_out = torch.mean(ce, 1)
ce_out = torch.mean(ce_out, 0)
# Save for backward step
self.save_for_backward(ce_out)
此时,当我 运行 批处理 for 循环中的代码(见下文)时,出现以下错误:
AttributeError: 'torch.FloatTensor' object has no attribute 'requires_grad'
这看起来很简单,因为我们应该传递一个 torch.autograd.Variable,但是我已经在这样做了,如下面的代码片段所示。
for t in range(50):
print('Epoch {}'.format(t))
if t > 0:
print('Loss ->', loss)
for batch_idx, (x_batch, y_batch) in enumerate(train_loader):
# Wrap in Variable
x_in, target = Variable(x_batch), Variable(y_batch)
predicted = model(x_in)
# Compute and print loss
loss = criterion(predicted, target)
# Zero gradients, perform a backward pass, and update the weights.
optimizer.zero_grad()
loss.backward()
optimizer.step()
补充一点,我的最终目标是生成一个 class 除了多个标签而不仅仅是二进制之外,它的行为类似于 BCELoss。我觉得我已经搜索了整个 PyTorch 文档并且主要使用了这个和一些论坛条目。
http://pytorch.org/docs/master/notes/extending.html
所以
问题出在将您的 t 变量转换为张量的 "target.float()" 行中。你可以直接使用target,你的CE计算没有任何问题。
另外,我猜你并不真的需要 "self.save_for_backward(ce_out)" 因为我猜你正在定义 nn.Module class 它将在内部处理后向传递。
我制作了一个自定义损失函数来计算多输出多标签问题的交叉熵 (CE)。在 class 中,我想将我输入的目标变量设置为不需要梯度。我在前向函数中使用 class.
之外的预定义函数(取自 pytorch 源代码)执行此操作 def _assert_no_grad(variable):
assert not variable.requires_grad
def forward(self, predicted, target):
"""
Computes cross entropy between targets and predictions.
"""
# No gradient over target
_assert_no_grad(target)
# Define variables
p = predicted.clamp(0.01, 0.99)
t = target.float()
#Compute cross entropy
h1 = p.log()*t
h2 = (1-t)*((1-p).log())
ce = torch.add(h1, h2)
ce_out = torch.mean(ce, 1)
ce_out = torch.mean(ce_out, 0)
# Save for backward step
self.save_for_backward(ce_out)
此时,当我 运行 批处理 for 循环中的代码(见下文)时,出现以下错误:
AttributeError: 'torch.FloatTensor' object has no attribute 'requires_grad'
这看起来很简单,因为我们应该传递一个 torch.autograd.Variable,但是我已经在这样做了,如下面的代码片段所示。
for t in range(50):
print('Epoch {}'.format(t))
if t > 0:
print('Loss ->', loss)
for batch_idx, (x_batch, y_batch) in enumerate(train_loader):
# Wrap in Variable
x_in, target = Variable(x_batch), Variable(y_batch)
predicted = model(x_in)
# Compute and print loss
loss = criterion(predicted, target)
# Zero gradients, perform a backward pass, and update the weights.
optimizer.zero_grad()
loss.backward()
optimizer.step()
补充一点,我的最终目标是生成一个 class 除了多个标签而不仅仅是二进制之外,它的行为类似于 BCELoss。我觉得我已经搜索了整个 PyTorch 文档并且主要使用了这个和一些论坛条目。 http://pytorch.org/docs/master/notes/extending.html
所以
问题出在将您的 t 变量转换为张量的 "target.float()" 行中。你可以直接使用target,你的CE计算没有任何问题。
另外,我猜你并不真的需要 "self.save_for_backward(ce_out)" 因为我猜你正在定义 nn.Module class 它将在内部处理后向传递。