11548
pythonとも機械学習とも勉強不足でわからない点があったため、chainerの交差エントロピー誤差を計算するsoftmax_cross_entropy()
について質問させてください。

MNISTを識別するサンプルコード  
<https://github.com/pfnet/chainer/blob/master/examples/mnist/train_mnist.py>  
を動かしてみました。

疑問に思った点は以下です。

  1. 49行目のreturn F.softmax_cross_entropy(y, t), F.accuracy(y, t) で、多クラス識別をする際の交差エントロピー誤差は、出力層のユニット数分(ラベルに対応するユニットだけでなくほかのユニットの確率も余事象として)計算しなければならないのに、教師データtを1ofK表記にせず、そのまま渡している点。  
交差エントロピーは与えられたラベルのユニットだけに関する重みを更新するのでしょうか。  
関数内部で1ofK表記、または多ラベル表記に変換しているのかなと考えてソースを見たのですがよくわかりませんでした。どのような処理をしているのかも教えてほしいです。

  2. 48行目の y = model.l3(h2) でsoftmax関数を通していない理由は、softmax_cross_entropy() 内で self.y, = Softmax().forward_cpu((x,)) として、関数内でsoftmax関数を適用しているからなのでしょうか  
そうすると 49行目の return F.softmax_cross_entropy(y, t), F.accuracy(y, t)
のyをh2の値を渡してもいい気がするのですがどうなんでしょう(yで線形変換する必要はあるのか)

質問は以上です。  
初歩的な質問かもしれませんがよろしくお願いします。

交差エントロピー、多クラス識別について参考にしたブログ  
<http://hshinji.hateblo.jp/entry/2015/05/20/081530>

softmax_cross_entropyのReference  
<https://github.com/pfnet/chainer/blob/master/chainer/functions/softmax_cross_entropy.py>
CC BY-SA 3.0
2015-06-19T07:19:40.167
11506
2015-06-20T04:05:10.197
8661
question
python 機械学習
chainerのsoftmax_cross_entropy()について
こんにちは

ご指摘の通り、この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`のコードは[こちら](https://github.com/pfnet/chainer/blob/master/chainer/functions/softmax_cross_entropy)を参照してください

  * 変数名は`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のコードでは[この部分](https://github.com/pfnet/chainer/blob/master/chainer/functions/accuracy.py#L8)です
CC BY-SA 3.0
2015-06-20T04:05:10.197
11548
2015-06-20T04:05:10.197
10224
11506
answer