【问题标题】:Get the Cross Entropy Loss in pytorch as in Keras像在 Keras 中一样在 pytorch 中获取交叉熵损失
【发布时间】:2020-09-24 13:17:21
【问题描述】:

我正在努力将分类模型从 keras 移植到 pytorch。尤其是交叉熵损失似乎返回完全不同的数字。

import numpy as np
import torch as t
import torch.nn as nn
import tensorflow.keras.backend as K

y_true = np.array([[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]])
y_pred = np.array([[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1, 0.41, 0.31, 0.21, 0.11]])

print("Keras", K.categorical_crossentropy(K.constant(y_true), K.constant(y_pred)))
print("PyTorch", nn.CrossEntropyLoss()(t.tensor(y_pred).argsort(dim=-1).float(), t.tensor(y_true).argmax(dim=-1)))```

打印:

Keras tf.Tensor([2.3369865], shape=(1,), dtype=float32)

PyTorch 张量(1.4587)

由于我有一个自定义损失函数,其中交叉熵是其中的一部分,因此即使数字不同,我也需要得到相似的数字。

【问题讨论】:

    标签: python tensorflow keras pytorch


    【解决方案1】:

    问题是它们有不同的实现。

    正如 pytorch docs 所说,nn.CrossEntropyLossnn.LogSoftmax()nn.NLLLoss() 组合在一个类中。但是,tensorflow docs 指定 keras.backend.categorical_crossentropy 默认不应用 Softmax,除非您将 from_logits 设置为 True。出于这个原因,除非你使用from_logits=True,否则你不应该使用keras.backend.categorical_crossentropy,除非你使用from_logits=True

    如果你不想预先应用 softmax,你应该使用:

    import numpy as np
    import torch as t
    import torch.nn as nn
    import tensorflow.keras.backend as K
    
    y_true = np.array([[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]])
    y_pred = np.array([[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1, 0.41, 0.31, 0.21, 0.11]])
    
    
    print("Keras", K.categorical_crossentropy(K.constant(y_true), K.constant(y_pred), from_logits=True))
    # output: Keras tf.Tensor([2.408051], shape=(1,), dtype=float32)
    print("PyTorch", nn.CrossEntropyLoss()(t.tensor(y_pred).float(), t.tensor(y_true).argmax(dim=-1)))
    # output: PyTorch tensor(2.4081)
    

    否则,您可以在计算 categorical_crossentropy 之前手动应用 Softmax

    import numpy as np
    import torch as t
    import torch.nn as nn
    import tensorflow.keras.backend as K
    
    y_true = np.array([[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]])
    y_pred = np.array([[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1, 0.41, 0.31, 0.21, 0.11]])
    
    
    print("Keras", K.categorical_crossentropy(K.constant(y_true), K.softmax(K.constant(y_pred))))
    # output: Keras tf.Tensor([2.408051], shape=(1,), dtype=float32)
    print("PyTorch", nn.CrossEntropyLoss()(t.tensor(y_pred).float(), t.tensor(y_true).argmax(dim=-1)))
    # output: PyTorch tensor(2.4081)
    

    因此,您不应像在示例中那样使用 keras.backend.categorical_crossentropyfrom_logits=False

    tf.keras.backend.categorical_crossentropy

    target:与输出形状相同的张量。

    输出:由 softmax 产生的张量(除非 from_logits 为 True,在这种情况下,输出应为 logits)。

    from_logits:布尔值,输出是 softmax 的结果,还是 logits 的张量。

    【讨论】:

    • 所以如果我选择选项 2,那么我在 pytorch 模型中的最后一个操作需要是 Softmax 对吗?因为 Keras 实际上会检查最后一个操作是否是 softmax github.com/tensorflow/tensorflow/blob/…
    • 并非如此,pytorch 默认应用 softmax,因此您不需要在模型中使用 softmax。使用 keras,如果 from_logits=False,则需要应用 softmax。否则,如果 from_logits=True,则充当 pytorch 函数。
    猜你喜欢
    • 2021-08-25
    • 2018-04-14
    • 2022-01-09
    • 2020-08-09
    • 2019-11-02
    • 2020-12-23
    • 2021-01-21
    • 2020-08-13
    • 2019-08-08
    相关资源
    最近更新 更多