【问题标题】:Why is the implementation of cross entropy different in Pytorch and Tensorflow?为什么 Pytorch 和 Tensorflow 中交叉熵的实现不同?
【发布时间】:2020-08-30 12:07:32
【问题描述】:

我正在阅读 Pytorch 和 Tensorflow 中的交叉熵文档。我知道他们正在修改交叉熵的幼稚实现,以解决潜在的数字上溢/下溢问题。但是,我无法理解这些修改有什么帮助。

implementation of Cross Entropy in Pytorch 遵循以下逻辑 -

其中 是softmax 分数, 是原始分数。

这似乎并不能解决问题,因为 也会导致数字溢出。

现在,我们将它与 Tensorflow 的实现进行对比(我知道了from a discussion in Github。这可能完全错误)-

是所有k个原始logit分数的向量。


虽然这解决了上溢问题,但它遇到了下溢问题,因为 可能会导致更小的

有人可以帮我理解这里发生了什么吗?

【问题讨论】:

  • 这不是 PyTorch 中的实现方式。他们也subtract the max,否则它会在数值上不稳定。指出它们的实现并让我们知道是否有任何区别。我不认为会有,除了化妆品
  • 哦,是吗?好吧,它处理了数字溢出部分,但是数字下溢呢?我的信息来源是pytorch.org/docs/stable/generated/…
  • 大多数人并不关心下溢。看看朴素的原始公式,当至少有一个占主导地位的大值时,非常小的值不会真正改变任何东西。

标签: tensorflow neural-network pytorch precision


【解决方案1】:

为了社区的利益,结合评论部分的答案在这里回答。

由于您已经解决了 PyTorch 中的数值溢出问题,因此可以通过减去最大值来处理,如下所示 (from here)。

scalar_t z = std::exp(input_data[d * dim_stride] - max_input);

在 TensorFlow 的交叉熵实现中,下溢 的问题并不是那么重要,因为它在数值上被忽略了,占主导地位的大值。

【讨论】:

    【解决方案2】:

    在 PyTorch 中

    loss = F.cross_entropy(x, target)
    

    相当于:

    lp = F.log_softmax(x, dim=-1)
    loss = F.nll_loss(lp, target)
    

    对于log_softmax,我们不直接计算softmax的对数,而是使用log-sum-exp技巧:

    def log_softmax(x): 
        return x - x.exp().sum(-1).log().unsqueeze(-1)
    

    这在数字上是稳定的。 PyTorch 和 Tensorflow 都使用了这个技巧。

    【讨论】:

      猜你喜欢
      • 2019-02-07
      • 2021-10-24
      • 2020-08-16
      • 2021-08-25
      • 2017-11-11
      • 2017-11-13
      • 2020-06-04
      • 2018-02-27
      • 2021-08-09
      相关资源
      最近更新 更多