目次
SOFTMAX関数と損失関数
今回は「SOFTMAX関数」と「損失関数」について、数式をなるべく使わないで、ざっくりと整理してみます。
専門用語を極力使わず、多少の不正確さは目をつぶっても、なんとなくイメージできることを目標にして整理します。
まず、ニューラルネットワークで学習する流れをざっくり図にしてみました。
ニューラルネットワークの目的のひとつとして「既存の正解がわかっているデータで勉強(学習)して、未知のデータから、正解が導けるようになること」があります。
ポイントはどうやって「勉強(学習)」するか?ですが、ニューラルネットワークでは、それを「計算」でやってます。
どういうことかというと。
既存の正解のわかっている入力データにたいして、パラメータ(重み)をかけあわせる計算を行い、その結果をもとに答えを出して、答え合わせを行い、間違ってたら、正解に近づけるようにパラメータ(重み)を少し修正するみたいなことを延々と繰り返して、もっとも。正解に近い結果を計算で求められる確率の高いパラメータ(重み)の値を決めていく・・のを学習と呼んでいるわけです。
上記の図は、それをごく簡易的に書いてます。
上記の図では「計算して結果を整えて、それを次の入力にする」部分を1回しか書いてませんが、実際は、そこが何層にもわかって繰り返されることで、学習の精度をあげようというのが、ニューラルネットワークであり、ディープラーニングなどと言われるゆえんということです。
SOFTMAX関数は、上記の図でいえば「③ 結果から確率を計算する」にあたります。
損失関数は、上記の図では「④ 答え合わせをする」にあたります。
ちゃんとした用語での位置づけとしては両方とも「出力層」にあたります。
ごく一般的なモデルの場合に、出力層には
- 与えられた正解ラベルである確率が何パーセントなのか?を計算=SoftMax関数。
- 計算結果が正解に対してどのくらいずれているのか?を判定=損失関数
という、ざっくりした役割分担があるというわけです。
SOFTMAX関数
SOFTMAX関数の役割は、上位の層の計算結果をうけとって、正解ラベル数分の「正解と判断できる確率としてとらえられる数字」を出力をすることです。
例えば。
正解ラベルが3つあって、以下の配列の0から2までが、正解ラベルA,B,Cに対応づいているとした場合、SOFTMAX関数の出力で
[ 0.2 0.3 0.5 ]
とあれば
- 正解ラベルA: 0.2
- 正解ラベルB: 0.3
- 正解ラベルC: 0.5
と読み替えられるわけです。
これらの合計は、必ず1.0(つまり100%)です。
だから結果が正解ラベル1,2,3である確率と読み替えることができる・・とまあ、そういう考え方です。
考え方は簡単なのですけど。
実際にSOFTMAX関数の入力値には、プラス・マイナスが混在していますし、0に近い位小さかったり、非常に大きかったり様々です。
単純に全部足し算してそれを分母にして割れば良しというわけにはいきません。
SOFTMAX関数のしくみ
SOFTMAX関数では以下のようにしてます。
例えば。
SOFTMAXに対する「入力A」「入力B」があったとすると
「eの入力A乗」を「(eの入力A乗)と(eの入力B乗)の総和」で割って、入力Aに対する確率値を計算してます。
やっていることは、「それぞれ個別の数値を全入力の総和で割っている」だけなのですが、「ネイビア数(e)」に対するXX乗の形にしているのが肝です。
ネイビア数(e)は「eのx乗」を微分しても、「eのx乗」のままで形が変わらないという面白い性質があって、微分を多用する学習(誤差逆伝播法など)の仕組みには、とても都合がよいのですね。
SOFTMAX関数を実装レベルで考える
SOFTMAX関数を、pythonで超ざっくり実装するとしたら
output = exp_in / np.sum(exp_in)
みたいな感じになります。
基本的に入力の行列と出力の行列の形は同じです。
SOFTMAXの入力にする前に、正解ラベル数にあわせて、行列の形を整えておきます。
例えば。
SONYのニューラルネットワークコンソールで定義した例です。
SOFTMAXの上に「Affine層」がくっついてます。
そこで、Affine層の出力数を変えて、自動的にSOFTMAXの出力数も同じにしてやらないといけないわけです。
損失関数
損失関数は「計算結果が正解に対してどのくらいずれているのか?を判定」します。
そのずれの大きさは、当然ながら「数学的」な方法で計算します。
方法はいろいろあるみたいですが、基本的かつ代表的な2つのやり方が。
- 2乗和誤差(mean squared error)
- 交差エントロピー誤差(cross entropy error)
です。
このへんは、数学用語を言葉の説明におきかえるのが難しくて、一部、そのままつかってますが、ご容赦ください。
損失関数:2乗和誤差(mean squared error)
(SOFTMAXで出力された結果数値 - 教師ラベルデータ)の結果を二乗(マイナスの値があるから・・)してしたものの総和をとって、二分の一にする・・・という方法で率を計算する方法です。
例えば、前であげた例みたいに。
[ 0.2 0.3 0.5 ]
という結果があって、この正解が実は「2番目の正解ラベル2」だった場合だと、教師ラベルデータを以下のようにあらわします。
[ 0 1 0 ]
正解にあたるところが「1」、それ以外は「0」で表現してあります。
このような表し方を「one-hot表現」といいます。
そうして「SOFTMAXで出力された結果数値 - 教師ラベルデータ」で計算します。
上記の例だと「(0.2 - 0)の2乗+(0.3 - 1)の2乗+(0.5 - 0)の2乗」を計算して、結果を2で割る感じです。
必然的に、正解(1)に対応する部分が「1」に近ければ(つまり、確率が高ければ)誤差は小さくなりますし、そうでない場合は大きくなるというわけです。
損失関数:交差エントロピー誤差(cross entropy error)
ざっくりと言えば。
上記のように正解ラベルデータが
[ 0 1 0]
のような形(one-hot表現)で与えられていて、SOFTMAXの出力結果が
[ 0.2 0.3 0.5 ]
だったとすると。
正解ラベルデータの値 × SOFTMAXの出力結果に対する自然対数
の総和をとるような形で計算します。
正解ラベルデータの値が0のところは、結局、結果も0になってしまいますから、正解ラベルデータ値が1の部分に対応する結果・・上記例なら「正解ラベル2の0.3」に対する自然対数・・のみが計算されることになります。
実際には1件だけデータを処理するわけではなく。
その時の学習単位(ミニバッチとかいいかす)件数分の総和をとってデータ件数で割って(平均をとる)マイナスにするみたいな計算式になるので、数式で見ると、複雑に見えますが、やっていることはそんなことです。
ちなみに、自然対数とは「e」(ネイビア数)を底とする対数(log)のことです。
自然対数には、微分がとてもきれいな形でできる性質があるので、微分計算を多用する学習にやっぱり、都合がよいわけです。
損失関数の意味合いと使い分け
上記の2種類は計算方法が違うので、同じ結果入力と教師データでも、結果となる数字は違います。
でも共通していることは。
- 正解に近いほど誤差として出力される結果は小さくなる。
- 正解から遠いほど誤差として出力される結果は大きくなる。
ということです。
だから。
その結果をもとにして、遡って重み(ウェイト)やバイアスを修正して、その修正をうけて再度損失率を計算する・・という繰り返しで、乗除に精度が向上するわけです。
上記の2種類の方法の使い分けとしては。
- 2乗和誤差は予測等の回帰問題
- 交差エントロピー誤差は分類問題
が一般的です。
理由は。
- 2乗和誤差は「すべてに対して教師データとの差を計算している」
- 交差エントロピー誤差が「正解ラベルに対してピンポイントで計算している」
という違いがあるからです。
最後にちょっと補足(言い訳?)
今回はSOFTMAX関数と損失関数について、頭の整理をしてみました。
この辺になると、数式を使わないほうが逆に難くなる場合もあり、数式になれた人達からは「数式見れば一発でわかることを、わざわざ日本語にする意味がわからん」・・的な指摘をもらったりもします。
でも。
数式って毎日のように触れている時はいいんですけど、しばらく離れると、見ただけで脳が拒否反応を示すこともあったりしますから、こういうアプローチが必要な場合があるんじゃないかと思って書いてます。
すいません。
ではでは。
PS:他の部品(レイヤー)については、以下にまとめてます。