nn.CrossEntropyLoss()とnn.BCEloss()およびnn.BCEWithLogitsLoss()の違いに関するPytorch [ピット]



Pytorch Difference Between Nn



最近、私はpytorchを使って実験をしました。私はいくつかの穴を踏んだ、それらのいくつかは小さくて大きい。この問題は原因を見つけるのにかなりの時間がかかりました。大きな落とし穴だと考えてみましょう。

まず第一に、これらのカテゴリー 対応する機能 ために:



nn.CrossEntropyLoss()-》 nn.functional.cross_entropy()

nn.BCEloss()-》 nn.functional.binary_cross_entropy()



nn.BCEWithLogitsLoss()-》 nn.functional.binary_cross_entropy_with_logits()

クラスとそれに対応する関数のラベル形式は同時に同じであり、クラスBCEloss()とクラスBCEWithLogitsLoss()のラベル形式はまったく同じです。など 後で関数フォームを直接使用しました 、読者が読みやすくするため。

CrossEntropyLoss()は、複数分類を実行できるクロスエントロピーです。 BCEloss()は、2つのカテゴリのクロスエントロピーを参照します。まず、私の個人的な推測では、2つの分類を行うと、CrossEntropyLoss()またはBCEloss()を使用できます。入力メソッドが異なっていても、同じ効果が得られるはずです。



しかし実際には、 CrossEntropyLoss() 内部的に ソフトマックス 次に、ラベルとエントロピーを交差させます! BCEloss() 内部 何もしませんでした 入力とラベルを直接クロスエントロピーします! BCEWithLogitsLoss() 内部的に シグモイド 次に、ラベルとエントロピーを交差させます!

最初に結果を見てください。ここではデフォルトの平均は使用されていませんが、何も使用されていません。

input_ = torch.tensor([[0.7, 0.3]]) # Two classification, assuming that the results obtained are corresponding to the probability of two labels of 0.7, 0.3, #Here does not necessarily have to add up to 1, nor does it all need to be between 0-1, explained later target1 = torch.tensor([0]) # Here is a label in the form of CrossEntropy, only one label is needed, assuming that the correct label is 0 (there are two labels of 0 and 1) target2 = torch.tensor([[1, 0]]).to(torch.float) # Here is the label in the form of BCEloss, and the inside is the probability representation target3 = torch.tensor([[1, 0]]).to(torch.float) # Same as above, adding this target is convenient for readers to read # Seek loss respectively loss1 = torch.nn.functional.cross_entropy(input_, target1, reduction = 'none') loss2 = torch.nn.functional.binary_cross_entropy(input_, target2, reduction = 'none') loss3 = torch.nn.functional.binary_cross_entropy_with_logits(input_, target3, reduction = 'none')

最終結果

loss1: tensor([0.5130]) loss2: tensor([[0.3567, 0.3567]]) loss3: tensor([[0.4032, 0.8544]])

次に、matlabを使用して計算しました

CrossEntropyLoss()/ loss1

ソフトマックスの層を追加し(したがって、入力を設定するために合計する必要はなく、必ずしも0-1の間である必要はありません)、 ターゲットに対応する数値のみが計算されるため、値は1つだけです。

BCEloss()/ loss2

バイナリクロスエントロピー計算を直接実行します。

w_nは、データのバランスが取れていない場合に使用されます。デフォルトは1で、ここでは無視してください。

BCEWithLogitsLoss ()/損失3

シグモイドのレイヤーを追加してから、バイナリクロスエントロピー計算を実行します。

総括する

ブロガーが0.7と0.3を設定した理由は、デフォルトでは、損失が計算される前にsoftmaxが渡されたためですが、pytorchは善意で悪いことをすることを期待していませんでしたが、TensorFlowの開発者はpytorchの開発者。 CrossEntropyLoss()をBCEloss()を使用して、2番目の分類で同じ効果を達成できる(つまり、softmaxとsigmoidが同じ効果を達成する)こともできると思いましたが、ブロガーもそれを間違って覚えていました。 バイナリロジスティック回帰では、softmaxとsigmoidは確かに同等です( 同等性の証明 )が、これは2つのクロスエントロピーが同等であることを意味するものではありません。 入力が0.5と0.5に設定されている場合にのみ、2つは等しくなります。