質問: Softmax().forward_cpu((x,)) として、関数内でsoftmax関数を適用しているからなのでしょうか そうすると 49行目の return F.softmax_cross_entropy(y, t), F.accuracy(y, t) のyをh2の値を渡してもいい気がするのですがどうなんでしょう(yで線形変換する必要はあるのか) 質問は以上です。 初歩的な質問かもしれませんがよろしくお願いします。 交差エントロピー、多クラス識別について参考にしたブログ softmax_cross_entropyのReference
回答: こんにちは ご指摘の通り、このFunctionは入力ベクトル`x`に対して`Softmax`を適用した後、正解ラベル`t`との交差エントロピーを取ります。ラベルの数をKとしたとき、`x`はK次元ベクトルですが、`t`は1 of K表現ではなく、ラベルのインデックスを整数で表しています。 ### 1について 正解ラベル以外のインデックスに対してはエラー(損失の勾配)が0になるので、エラーを逆伝播する必要がありません。 分布`p`と`q`の交差エントロピーは`-Σ_i p(i) log q(i)`で、今の場合`p`は、正解ラベル`t`で`p(t)=1`で、それ以外の値`t'`で`p(t’)=0`という分布です。なので、`y=Softmax(x)`とし`y`を`y=[y1, ..., yK]`と成分で書くと、交差エントロピーは`-log yt`となります。 ある変数`z`のエラーは損失(今の場合交差エントロピー)を`z`で微分した値です。今の場合`t`と異なる`t’`について、損失`-log yt`を`yt’`で偏微分をすると`0`なので、`yt’`についてはエラーが発生しません。 Chainerでの`SoftmaxCrossEntoropy`のコードはこちらを参照してください * 変数名は`example`のコードではなく、`SoftmaxCrossEntropy`のソースコードに合わせています。`example`での`y`が`SoftmaxCrossEntropy`のコード内での`x`に対応しています * 実際にはミニバッチなので、ミニバッチサイズを`B`とした時、`x`は`B`行`k`列の行列、`t`は`B`次元のベクトルですが、今はミニバッチサイズは`1`として書いています ### 2について ご指摘の通り、定義通りにAccuracyを計算するには、`Softmax`を取ってから値が最大となるインデックスを取る(`argmax`を取る)必要があります。しかし、`example`のコードでは`x`そのものに対して`argmax`をとっています。 しかし、ベクトル`x`の中で最大値を取るインデックスと`Softmax(x)`の中で最大値を取るインデックス同一(つまり`argmax x = argmax Softmax(x)`)なので、`Softmax`を取る前のベクトルに対して`argmax`を取って構いません。 例えば`x=[1, 3, 6]`とすると、`Softmax(x) = [exp(1)/Z, exp(3)/Z, exp(6)/Z]`となります。ここで、`exp`は指数関数、`Z`は出力ベクトルの合計が1となるようにするための定数で、この例の場合は`Z = exp(1) + exp(3) + exp(6)`です。確かに`x`でも`Softmax(x)`でも値が最大の要素は3番目で共通しています。 実際に`argmax`をとっているのはChainerのコードではこの部分です