ソフトマックス関数のオーバーフローの式変形について

最近はAIに関する色々が流行になっていますね。

そんな流れに乗って私自身もディープラーニング(AI)に興味が出てきたので

下記の参考書を使って勉強中です。

今も読み進めている最中ですが、その中でソフトマックス関数のオーバーフロー式変形がよく分からなかったのでちょっと調べてみました。

 

www.oreilly.co.jp

 

ソフトマックス関数は以下の式で表されます。 

\displaystyle y_k =\frac{exp(a_k)}{\sum_{i=1}^{n} exp(a_i)}

\displaystyle exp(a_k) = e^{a_k}

※ a ... 各入力信号

 

この式のままだと、 a_iの値が大きい値(100とか1000とか)の場合に数値がオーバーフローしてしまいNaN(Not a Number : 不定な値)になってしまいます。

(例えば、 e^{1000}はまともに計算するととても大きな桁数になります)

 

上記式にある工夫を加えるとオーバーフローを防ぐことができるのですが、本を読んでもネットで調べてもよく分からなかったので今回そのことを書こうと思います。

 

式変形自体は、まず分子と分母にCという任意の定数をかけます。 両方に同じ値をかけているだけなので計算結果は変わらないはずです。

 

\displaystyle y_k =\frac{C exp(a_k)}{C\sum_{i=1}^{n} exp(a_i)}

 

参考書や各種ページでは「Cを指数関数expの中に移動」とさらっと書いてありますが、これは対数関数の公式を使うことでCを指数関数expの中へ移動できます。

※公式の証明は下記参考サイトを参照してください。

 

公式 \displaystyle a^{log_b c} = c^{log_b a} より

\displaystyle e^{log_e C} = C^{log_e e} = C^{1} (log_e e = 1) = C

つまりCは \displaystyle C = e^{log_e C} に変形可能。

よって 

 \displaystyle y_k =\frac{C exp(a_k)}{C \sum_{i=1}^{n} exp(a_i)}

     = \displaystyle  \frac{exp(log_e C) exp(a_k)}{exp(log_e C) \sum_{i=1}^{n} exp(a_i)}

     = \displaystyle  \frac{exp(a_k +log_e C)}{\sum_{i=1}^{n} exp(a_i +log_e C)}

 

と言う形で既存の指数関数の中にCを入れ込むことが出来ます。

\displaystyle log_e C\displaystyle log_e C = C^{'}と別の定数に置き換えられるので、あとは適当な定数を決めるだけです。

ココには入力信号の最大値を入れるのが一般的だそうです(ここはソフトマックス関数を説明している各サイトにも書かれています)

 

久しぶりに数式に触ったのでこの辺の公式全然覚えてなかったです。。。

指数関数の公式で調べるといっぱい出てきてどれが該当の公式なのかよく分かんなくなりますね。。。

 

 

 

[参考サイト]

指数・対数関数 | 高校数学の美しい物語