しいたげられたしいたけ

拡散という行為は、元記事の著者と同等以上の責任を拡散者も負う

O'REILLY『ゼロから作るDeep Learning』5章誤差逆伝播法は見かけに反して意外な難関だった(その1)

相変わらずO'REILLY『ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装』(以下 “テキスト”)を少しずつ読んでいる。読めば読むほど、著者の 斎藤康毅 氏は、つくづく頭のいい人なんだということを実感する。どの章も、章の初めにごく簡単な例を示して、そこから次に、一気に実用的なサンプルプログラムの説明に入る。いわば特急列車のようなものだ。

一方私は、頭のよくないロートルなので、とても理解が追いついてゆかない。そこで自分の歯に合う、易しい練習問題をいくつか作っては解いてみることにより、なんとかわかったつもりになるということを、章ごとに繰り返している。いわば鈍行列車である。

もう一つ、章を読み進めるにしたがって、著者の斎藤氏は、プログラマとしても超一流なのだろうと、ひしひしと感じるようになった。『入門 Python 3』の監訳者でもあるので、ひょっとしたらプログラミングの方が本業なのかも知れない。私が Python 初心者で不慣れなことを大幅に差し引いても、「絶対にこんな風には書けない」と感じるコードが次々に出てくる。

スポンサーリンク

 

前回の関連エントリーはこちら。数値微分による勾配法で実現されているクラスを使って、簡単な自作テストデータセットに対して機械学習をやらせてみたという話だ。驚いたことに、本来その用途に作られていないクラスが、私のでっち上げたテストデータを処理してしまった! このあたりも著者の斎藤氏の凄腕に驚かされた事例である。

www.watto.nagoya

ただし数値微分による勾配法では、処理量が増えるに従って動作が重くなり、本命である MNISTデータセット相手では、パソコン上で動かすインタープリタじゃ処理に何時間かかるか、何昼夜かかるかわかったもんじゃないことが判明したところで4章が終わった。次なる「誤差逆伝播法」への導入としては、できすぎと言えるほどのストーリー展開である。

しかして次なる5章では、処理の高速化の手段として誤差逆伝播法というのが登場する。微分を数値近似から解析的手法に変更することにより、計算量の大幅削減を実現しようというのである。

原理的には、理系人間にとってはお馴染みのものだ。高校数学で言うところの「媒介変数表示された関数の微分法」というやつである。

テキストP130~131の例を引用させてもらうと…

f:id:watto:20170711010131p:plain

すなわち t というパラメータ(媒介変数)を用いることにより、元の関数の導関数が、二つの導関数の積によって表せるという公式を応用するのである。ただしテキストでは、数式をガリガリと書いていくのではなく、「計算グラフ」というので図示する手法が採用されている。

計算グラフの例を、テキストP128から引用。図はオリジナルではなく、パワーポイントの図形を使って模写したものです。

f:id:watto:20170711010051p:plain

1個100円のリンゴを2個買って消費税10%がかかると、代金は220円となる。もし支払い料金に1円の変化があったとすると、元のリンゴの料金には何割つか何パーセントの影響があるか、ということを示す計算例である。

ただこの例が、現実の買い物において起こりうる状況を、なんら反映していない(よね?)ことが、私の理解を大きく妨げた。あくまでこうした計算は、損失関数の出力値を減少させるために必要な係数の値の変化量を計算する場合においてのみ役立つのであって、支払い料金が1円増減することによりリンゴの値段が2.2倍になるわけでも2.2分の1になるわけでもない(よね?)。

ところがテキストでは、この例示のあと、計算グラフと媒介変数表示関数の微分の公式を用いて、機械学習で用いられる関数レイヤの実装方法を次々と説明し、章末でいきなり本命MNIST関数を処理させるクラスが示されるのである。しかもそのクラスというのが、Python ライブラリの OrderDirect という関数を使用して関数レイヤを呼び出すという、まあようするに洗練されたというか完成度が高いというか、シロウトが読んですっと理解できるようなコードではないのだ。

そんなで今回も、易しめの問題を自作して解いてみた。解いてみてわかったことが二つあった。一つめは「言うは易く行うは難し」というのか、逆伝播法というのは理論としてはわかりやすいが、いざ実装となるとつい混乱して間違いが多くてまず一発で動くものではないということだった。そして二つめは、私に書けるコードがいかに汚いかということだった。比較にもならないが、もし著者の斎藤氏が同じ機能を実装したなら、ぜってーぜってー私が書いたものとは似ても似つかぬコードを書いたであろうことは想像に難くない。

それでもあえて晒そうとする理由は、同じ本の学習者にとって他山の石くらいにはならないかと考えてのことと、もう一つは、いつぞやの C++ のときのように、誰かコメントかブコメで教えてくれないかと期待してのことである。

という訳で今回も対象読者限定なので、遠慮して新着から目立ちにくくするため日付をさかのぼって公開します。

この項続く。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装