我们如何实现使用 PyTorch 反向传播的自定义损失?

数据挖掘 损失函数 火炬
2022-02-24 00:29:05

在用 PyTorch 编写的神经网络代码中,我们定义并使用了这个自定义损失,它应该复制交叉熵损失的行为:

def my_loss(output, target):
    global classes    

    v = torch.empty(batchSize)
    xi = torch.empty(batchSize)

    for j in range(0, batchSize):
        v[j] = 0
        for k in range(0, len(classes)):
            v[j] += math.exp(output[j][k]) 

    for j in range(0, batchSize):
        xi[j] = -math.log( math.exp( output[j][target[j]] ) / v[j] )

    loss = torch.mean(xi)
    print(loss)
    loss.requires_grad = True
    return loss

但它并没有收敛到可接受的精度。

1个回答

您应该只使用 pytorch 的数学函数实现,否则,torch 不知道如何区分它们。替换math.exptorch.exp,math.logtorch.log

此外,尽可能多地尝试使用矢量化操作而不是循环,因为这样会快得多。

最后,据我所知,您只是在 pytorch 中重新实现日志丢失,为什么您不使用默认实现的日志丢失?(见这里这里

[编辑]:如果在删除了数学运算并实现了损失的矢量化版本之后,它仍然没有收敛,这里有一些关于如何调试它的提示:

  • 通过手动计算值来检查损失是否正确,并将其与函数输出的值进行比较
  • 手动计算梯度并检查它是否与loss.grad运行后的值相同loss.backward()(更多信息在这里
  • 在几次迭代后监控损失和梯度,以检查训练期间一切是否正常