この記事は, Pythonを利用して研究を行なっていく中で私がつまずいてしまったポイントをまとめていくものです。同じような状況で苦しんでいる方々の参考になれば嬉しいです。Pythonつまずきポイント集の目次は以下のページをご覧ください。
【超初心者お悩み解決】Pythonつまずきポイント記事まとめページ
この記事は,Pythonを利用して研究を行なっていく中で私がつまずいてしまったポイントをまとめていくものです。同じような状況で苦しんで...
スポンサーリンク
読みたい場所へジャンプ!
環境
●Ubuntu 18.04
●Python 3.7.3
●conda 4.8.3
●pytorch 1.2.0
現象
「BCELoss」と「BCEWithLogitsLoss」の挙動が異なる。本来「BCEWithLogitsLoss」で重みを1にした場合には「BCELoss」と同じ挙動を示すはずなのになぜか違った結果を出力する。
原因
そもそも両者の入力定義が異なっていることが原因でした。「BCELoss」はシグモイドをとった後の値を入力として受け付けます。「BCEWithLogitsLoss」はシグモイドをとる前の値を入力として受け付けます。
BCELoss
\begin{align}
l_{n}=-w_{n}\left[y_{n} \cdot \log x_{n}+\left(1-y_{n}\right) \cdot \log \left(1-x_{n}\right)\right]
\end{align}
BCEWithLogitsLoss
\begin{align}
l_{n, c}=-w_{n, c}\left[p_{c} y_{n, c} \cdot \log \sigma\left(x_{n, c}\right)+\left(1-y_{n, c}\right) \cdot \log \left(1-\sigma\left(x_{n, c}\right)\right)\right]
\end{align}
なぜこんなにややこしい定義をしているのか分かりませんが,原因が分かってホッとしています。
2年前の記事にすみません。
そもそもBCEwithlogitsloss()はBCEloss()にシグモイドの機能をつけ足したものだと思います。
ご指摘ありがとうございます。
Forumにも記載がありましたね。
https://discuss.pytorch.org/t/bceloss-vs-bcewithlogitsloss/33586