多値分類において深層学習の最終層にsoftmax関数が用いられることが多い
最終層直前の出力を正規化することで、確率として表現することが可能になる
softmax関数は以下のように定義される
y_k = \frac{exp(a_k)}{\sum_{i=0}^n{exp(a_i)}}
出力に対して指数関数の和で正規化される
これには以下の3つの理由がある
- 非負として扱うことが可能
- 単調増加関数
- 微分がなめらかで最適化手法を適用しやすい
最終層直前で負の値になった場合、確率として扱うとすると0~1の間に収める必要がある
指数関数は非負の関数なので、都合が良い
また、指数関数は単調増加関数なので、値の上下関係を正しく表現することが可能である
非負を扱いたい場合、絶対値などを使うことも想定されるが、境界値において微分を定義できない
微分の定義ができないと勾配降下法など重みを学習するにあたって不都合が生じる
指数関数はなめらかで微分がしやすいというのも利用されている一因である
softmax関数を使う上での注意点
softmax関数では指数を扱うがゆえに、最終総直前の出力が大きいと、オーバーフローが発生することがある
# 最終出力値>>> x = np.array([1000, 900, 1500])# softmax関数における分母の計算>>> np.exp(x)array([inf, inf, inf]) # => オーバーフローの発生
そこで式変形を行い最大値を引くことでオーバーフローが発生することを防ぐ
y_k = \frac{exp(a_k)}{\sum_{i=0}^n{exp(a_i)}} \\
= \frac{C exp(a_k)}{\sum_{i=0}^n{C exp(a_i)}} \\
= \frac{exp(a_k + logC)}{\sum_{i=0}^n{exp(a_i + logC)}} \\
= \frac{exp(a_k + C')}{\sum_{i=0}^n{exp(a_i + C')}} \\
これによって出力がオーバーフローになるのを防ぐ
pytorchでもsoftmaxの計算にはこれらの処理が加えられている