アカデミック

【Pythonお悩み解決】「BCELoss」と「BCEWithLogitsLoss」の挙動が異なる

この記事は, Pythonを利用して研究を行なっていく中で私がつまずいてしまったポイントをまとめていくものです。同じような状況で苦しんでいる方々の参考になれば嬉しいです。Pythonつまずきポイント集の目次は以下のページをご覧ください。

【超初心者お悩み解決】Pythonつまずきポイント記事まとめページ この記事は,Pythonを利用して研究を行なっていく中で私がつまずいてしまったポイントをまとめていくものです。同じような状況で苦しんで...

本記事で紹介する解決策がBestという保証はできません。正確な情報を発信するように心掛けていますが図らずも誤った情報を記載してしまう場合があります。もしご指摘等がありましたら,コメント欄またはお問い合わせページよりご連絡下さい。

読みたい場所へジャンプ!

環境

●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}

なぜこんなにややこしい定義をしているのか分かりませんが,原因が分かってホッとしています。

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です