"BOKU"のITな日常

62歳・文系システムエンジニアの”BOKU”は日々勉強を楽しんでます

SOFTMAX関数と損失関数について文系チックにざっくりと整理してみる/ディープラーニング

今回は「SOFTMAX関数」と「損失関数」について、数式をなるべく使わないで、ざっくりと整理してみます。

f:id:arakan_no_boku:20200109220616p:plain

 

SOFTMAX関数と損失関数

 

位置づけとしては「出力層」にあたります。

 

 

ごく一般的なモデルの場合に、出力層には

  • 与えられた正解ラベルである確率が何パーセントなのか?を計算=SoftMax関数。
  • 計算結果が正解に対してどのくらいずれているのか?を判定=損失関数

という、ざっくりした役割分担があります。

正解を予測して、ずれの大きさを計測する。

その結果に基づいて重み等を更新してずれを最小にしていくのが「学習」だと考えれば、とても重要なポジションになります。

 

SOFTMAX関数のしくみは?

 

SOFTMAX関数の役割は、上位の層の計算結果をうけとって、正解ラベル数分の「正解と判断できる確率としてとらえられる数字」を出力をすることです。

例えば。

正解ラベルが3つあって、以下の配列の0から2までが、正解ラベルA,B,Cに対応づいているとした場合

[ 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に対する「入力A」「入力B」があったとすると

「eの入力A乗」を「(eの入力A乗)と(eの入力B乗)の総和」で割って、入力Aに対する確率値を計算してます。

やっていることは、「それぞれ個別の数値を全入力の総和で割っている」だけなのですが、「ネイビア数(e)」に対するXX乗の形にしているのが肝です。

mathwords.net

ネイビア数(e)は「eのx乗」を微分しても、「eのx乗」のままで形が変わらないという面白い性質があって、微分を多用する学習(誤差逆伝播法など)には、とても都合がよいのですね。

arakan-pgm-ai.hatenablog.com

さて。

そんなSOFTMAX関数を、pythonで超ざっくり実装するとしたら

output = exp_in / np.sum(exp_in)

みたいな感じになります。

基本的に入力の行列と出力の行列の形は同じです。

SOFTMAXの入力にする前に、正解ラベル数にあわせて、行列の形を整えておきます。

例えば。

SONYニューラルネットワークコンソールで定義した例です。

SOFTMAXの上に「Affine層」がくっついてます。

そこで、Affine層の出力数を変えて、自動的にSOFTMAXの出力数も同じにします。

f:id:arakan_no_boku:20200111142903p:plain

 

損失関数について

 

損失関数は「計算結果が正解に対してどのくらいずれているのか?を判定」します。

そのずれの大きさは、当然ながら「数学的」な方法で計算します。

方法はいろいろあるみたいですが、基本的かつ代表的な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)のことです。

自然対数には、微分がとてもきれいな形でできる性質があるので、微分計算を多用する学習にとても都合がよいわけです。

arakan-pgm-ai.hatenablog.com

 

これらの意味合いと使い分けなど

 

上記の2種類は計算方法が違うので、同じ結果入力と教師データでも、結果となる数字は違います。

でも共通していることは。

  • 正解に近いほど誤差として出力される結果は小さくなる。
  • 正解から遠いほど誤差として出力される結果は大きくなる。

ということです。

だから。

その結果をもとにして、遡って重み(ウェイト)やバイアスを修正して、その修正をうけて再度損失率を計算する・・という繰り返しで、乗除に精度が向上するわけです。

上記の2種類の方法の使い分けとしては。

  • 2乗和誤差は予測等の回帰問題
  • 交差エントロピー誤差は分類問題

が一般的です。

理由は。

  • 2乗和誤差は「すべてに対して教師データとの差を計算している」
  • 交差エントロピー誤差が「正解ラベルに対してピンポイントで計算している」

という違いがあるからです。

 

まとめ

 

今回はSOFTMAX関数と損失関数について、頭の整理をしてみました。

この辺になると、数式を使わないほうが逆に難くなる場合もあり、数式になれた人達からは「数式見れば一発でわかることを、わざわざ日本語にする意味がわからん」・・的な指摘をもらったりもします。

でも。

数式って毎日のように触れている時はいいんですけど、しばらく離れると、見ただけで脳が拒否反応を示すこともあったりしますからね。

 

ではでは。