06.11 Softmax-with-Lossレイヤ

昨日正誤表をダウンロードしようと、O'REILLY オライリー・ジャパンの「ゼロから作るDeep Learning」のサイトを見ていたら著作権の中にサンプルプログラムは商用でも非商用でも使用可能とあったのでダウンロードしてみてください。今までフォルダーcommonには有用なプログラムが一杯ありますので、使用してみてください。

最後は出力層ソフトマックス関数です。ソフトマックスは「04.07 恒等関数とソフトマックス関数」で確かラーメン屋のラーメンの売り上げ杯数を例にとって説明したと思います。ちょっと復習してみるとニューラルネットワークの最終結果は最後のAffineレイヤ等の結果が出てきます。Softmaxレイアは入力された値を「正規化」という手段を用い出力結果の総和が必ず「」となるように変化します。この時のAffineレイヤの出力値を「スコア」と呼ぶ場合があります。というのもラーメンの話で前にも述べましたが、ニューラルネットワークにおける「推論」時は最大値のみ分かればよいため、あえて時間が掛かるSoftmaxを使用する必要がないからです。例えば京都の某科捜研の番組のように犯人の顔認証システムが仮にできたとすると、目標の顔データに対し照合した全ての顔データの確率は不必要で確率が最も高いデータのみが出てこれば番組は成立するわけです。

ところが「学習」の場合は、そういうわけにはいかないというのが、今回の本題となります。「ゼロから作るDeep Learning」では損失関数の交差エントロピー誤差(cross entropy error)Softmaxをミックスした「Softmax-with-Lossレイア」として実装が開始されています。しかしその前に「ゼロから作るDeep Learning」では難しいので「計算グラフに興味があるなら」ということで巻末付録に計算グラフの解き方がありますので全部やると決めたのでやってみましょう。

全体的にみると下記のような構造になるはずです。

【Softmax-with-Lossレイヤの計算グラフ(概要)】


★ ソフトマックスの復習と順伝播
ソフトマックス関数は次の式で表されます。exp(x)は e x をあらわす指数関数です(eは自然対数の底=ネイピア数=2.7182・・・)。

y k = exp( a k ) i = 1 n exp( a i )

【Softmaxsレイヤの計算グラフ(順伝播)】


計算グラフは「ゼロから作るDeep Learning」巻末付録Aに記載されている条件=入力(a1,a2,a3)、Softmaxレイヤ出力(y1,y2,y3)、教示データ(t1,t2,t3)、損失関数出力値Lとします。また同参考書にあるように全部書くと字が小さくて見えないので指数の総和はSで略しています。また以降登場しますが「exp()」ノードと「log()」ノードは、同算術式を行うと考えればよいと思われます。

 交差エントロピー誤差の復習と順伝播
次に「交差エントロピー誤差(cross entropy error)」ですが、次の式で表されます。
E = - k t k log y k

【Cross Entropy Errorの計算グラフ(順伝播)】


★ 逆伝播のポイント
ここでの最大のポイントは参考書には書いていませんが「log」ノードを微分した時にどうなるかという問題でしょう。そこで参考書にはないので、この爺が1つ解いてみることにしましょう。

lim h 0 log x + h - log x h = lim h 0 1 h log x + h x = lim h 0 1 h log 1 + h x

この次が分からん!!?  ここでちょっと最下部「参考書籍」のサイトを見て納得。どうもこれ以降は違う知識が必要になるようです。それg自然対数の底の式でした。以前掃除のおばさんの例で

e = lim n 1 + 1 n n

でありました。この視点を変えてn→∞を「 n = 1 t 」と置き換えると、t→0の時

e = lim t 0 1 + t 1 t

となります。これを前述に用います。

lim h 0 log x + h - log x h = lim h 0 1 h log x + h x = lim h 0 1 h log 1 + h x

ここで「 h x = t 」と置き換えると、h→0の時t→0となって

= lim t 0 1 x 1 t log 1 + t

= 1 x lim t 0 log 1 + t 1 t

= 1 x log

となり、最終的にこんな感じになとなり、微分の結果は、

y x = 1 x

となります。 従って逆伝播は処理時間のかかるlogは一切使用せずできます。

あとは「×」ノードは順伝播をひっくり返した値を流れてきた値に乗算すればよいし、「+」はそのままスルーととなります。

★ 交差エントロピーの逆伝播
有名なC言語教習本の中に「猿でもわかるC言語講座」みたいなのがありますが、ここまでくれば後は機能的にルールを適応するだけですので、一見すると難しい交差エントロピー誤差レイヤの逆伝播は簡単です。下記のようにします。

【Cross Entropy Errorの計算グラフ(逆伝播)】


★ ソフトマックスレイヤの逆伝播
ソフトマックス逆伝播の初めは交差エントロピー誤差逆伝播の最終値でありますから、既に値が決まっており「 - t1 y1 , - t2 y2 , - t3 y3 」の値が入力値となります。

① ステップ1
まず順伝播で「 y1 = exp( a i ) 」でありましたから、単純なひっくり返して×式は下記のように変化します。


t1 y1 exp( a 1 ) = -t1 exp( a i ) exp( a 1 ) = -t1

② ステップ2
分岐が ある場合、どうなるかですが、「ゼロから作るDeep Learning」よると、「/」ノードの入力値「 - t1 S, - t2 S, - t3 S 」が逆伝播時に加算され結果が「 1 ( t1 + t2 + t3 ) 」 になると書いてあるのですが、GGEにはどうしてそうなるかが全く分かりません。仮に成立すると「 ( t1 + t2 + t3 ) 」の合計はone-hot形式の教示データである為合計は必ず1になる答えは「1/S」ということになります。あとは最終的には「 ( y1 - t1 , y2 - t2 , y3 - t3 ) 」となります。

「おっと、閃いたぞ!!」

「/」ノードの逆伝播のなぞを改めて解明していきましょう。

まず「 06.09 Sigmoidレイヤの実装」で初めて「/」の解説で、

y x = -1 x 2 = - y 2

上記のような式が成り立ちました。今回のケースは、その総和であるため多分下記のようになるのではないかと思われます。


= -t1 S - 1 S 2 + -t2 S - 1 S 2 + -t3 S - 1 S 2

= 1 S t1 + t2 + t3

t1 + t2 + t3 = 1 」であるために、結果的に「 1 S 」だけが残ることになります。 これで全てすっきりしました。内容がめちゃくちゃ複雑でも計算グラフで解決すれば簡単に解け、さらにコンピュータ上も高速で演算できるようになります。

【Softmaxsレイヤの計算グラフ(逆伝播)】



Softmax-with-Lossレイア
でも元に戻りまして、上記「Softmaxレイヤ」と「交差エントロピー誤差レイヤ」を合体した「Softmax-with-Lossレイヤ」は
下記のような統合計算グラフとなります(単純にくっ付けただけです)。

【Softmax-with-Lossレイヤの計算グラフ】


ただし合体版レイヤへの入力「 a1, a2, a3 」、出力「 y1, y2, y3 」、教示ラベル「 t1, t2, t3 」、損失L、逆伝播「 ( y1 - t1 , y2 - t2 , y3 - t3 ) 」の構成要素だけを使用すると、最初に登場した下記の構成図になります。逆伝播の最終的な要素を言葉で表現すると、これは

 「Softmaxレイヤと教示データの差分

なのです。
 
【Softmax-with-Lossレイヤの計算グラフ(概要)】


当たり前といえば当たり前のことで、「学習の目的はSoftmax出力を教示データに近づけるように重みを調整すること」なのですから。

★ Pythonで実装
では実際に実装してみましょう。 本体はサンプルプログラムのcommon/layers.pyに入っています。但しサンプルの実装は各種ケースに対応し作成されているため上記作成部のみを添付します。使用時はサンプルを使用してください。

class SoftmaxWithLoss:
 def __init__(self):
  self.loss = None
  self.y = None # softmaxの出力
  self.t = None # 教師データ

 def forward(self, x, t):
  self.t = t
  self.y = softmax(x)
  self.loss = cross_entropy_error(self.y, self.t)
  return self.loss

 def backward(self, dout=1):
  batch_size = self.t.shape[0]
  dx = (self.y - self.t) / batch_size
  return dx


【参考書籍】
算数から高度な数学まで、網羅的に解説したサイト
https://mathwords.net/logxnobibun

対数関数 log x の微分公式とその証明
https://sci-pursuit.com/math/differential-logarithm.html#2-1

【参考文献】
辻真吾著「Python スタートブック ~いちばんやさしいパイソンの本~」技術評論社

斎藤康毅著「ゼロから作るDeep Learning」O'REILLY オライリー・ジャパン



≪清須電脳倶楽部メインページへ戻る場合はここをクリックしてください≫
Copyright(c)2018 GGE Kiyosu Cyber Club Allrights Reserved
inserted by FC2 system