【问题标题】:Why do we average the losses of all elements of the batch if we typically should average the gradients (rather than the losses)?如果我们通常应该平均梯度(而不是损失),为什么我们要平均批次中所有元素的损失?
【发布时间】:2020-05-01 15:58:06
【问题描述】:

我的loss 输出是

tensor([0.0430, 0.0443, 0.0430, 0.0430, 0.0443, 0.0466, 0.0466, 0.0466],
       grad_fn=<AddBackward0>)

当我执行loss.backward()时,我得到了*** RuntimeError: grad can be implicitly created only for scalar outputs

在某些地方,他们宁愿建议loss.mean().backward()loss.sum().backward()

为什么使用.mean().backward(),即如果我们通常应该平均梯度(而不是损失),为什么我们要平均批次中所有元素的损失?

这是我的code

【问题讨论】:

    标签: python pytorch gradient


    【解决方案1】:

    因为默认情况下,当调用标量时,它会将[1] 作为输入传递给后向函数。如果它是一个具有多个元素的张量,那么您应该将 [1,1,....1] 作为向后的输入传递。

    loss.backward(torch.Tensor([1, 1, 1, 1, 1, 1, ... ,1])) 
    

    loss.backward(torch.ones(batch_size)) 
    

    个数 = 在您的情况下,一维张量中的元素数。

    回答为什么我们使用均值和全部,因为它充当规范化术语。我们没有让单个批次的所有损失大量影响,而是标准化它的影响。这是一个问题吗?不会。相反,通过缩放,我们可以更合理地了解损失曲线的表现。

    【讨论】:

    • 不是那么干净。我从来没有见过这样的做法。
    • @David.: 抱歉,你指的是哪一个?什么不干净?如果向后不应用于标量,那么是的,这就是方法。
    • 如果我有batch_size = 256,我不想写loss.backward(torch.Tensor([1, 1, 1, 1, 1, 1, ... ,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))。你有解决这个问题的办法吗?我很高兴它可能会起作用,但我无法在我的代码中编写它
    • @David.: torch.ones(batch_size)
    • @David.:现在检查一下
    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 2022-10-02
    相关资源
    最近更新 更多