どうも、カタミチです。
さて、今日も「最短コースでわかる ディープラーニングの数学」のひとり読書会、やっていきたいと思います。
ラスボスのディープラーニングモデルも、いよいよ第3形態ですね。
10-9. プログラム実装(その3)
さて、モデルの精度はまだ低い!ということで再びやってきました。
次なる手は…
活性化関数の変更です。
隠れ層のノードに使っていたシグモイド関数さんにはちょっとお休みいただいて、代わりに…ReLU関数さんの登場です。
いやー、ついにお出ましですね。本書では出てこないんじゃないかと思ってました。しかし、シグモイド関数が微分によって誤差を伝播しにくいことを解消するために採用されるのがReLU関数って理解だったんですが、隠れ層1層でも効果あるんですかねー。
どんな関数かというと、
\( f(x)= \begin{cases}0 & (x<0)\\x & (x \geq 0)\end{cases} \)
という、超シンプルな関数です。この関数の採用に至るまでに、多くの先人たちの苦悩があったと言うのは不思議なものです。グラフにするとこんな感じ。
ちなみにReLU関数は(ランプかんすう)と呼ぶのが一般的らしいです。前々から、なんでコレをランプって読むのか気になっていたので、少し調べてみました。
どうやら、ランプ関数ってのは、英語だと「ramp function」ってやつらしく、「ramp:傾斜路」が由来のようです。高速道路の入り口の「○○ランプ」ってやつですね。確かに、この関数のグラフの形状に似ていて直感的ですね。
じゃぁ、ReLUって何?って話なんですが、「Rectified Linear Unit」の頭文字で「ReLU」らしいです。「調整された直線装置」みたいな意味でしょうか。こちらも、グラフの形から名前が定義されたようですね。
…うーむ。
ReLUって書くなら(レル)って読んでください。ランプって読むならramp関数って書いてください。ていうか、どっちかに統一して!(心の叫び)
…ともあれ、活性化関数をシグモイドからReLUに変えることで、結果がどう変わるのかを見てみましょう。
どん!
おー、損失関数のグラフの下りっぷりが上がりましたね〜(下りっぷりとは)。
さて、精度のグラフはと言うと…
おー、95%付近まで来ました。これはもう、グッドモデルなんじゃないですかね!
…と、満足していたんですが、どうやらまだラスボスは倒れていないようです。最後の力を振り絞って、ラストブロウを打ち込みますかね!(つづく)
おまけ
…さて、ここで、これまでずっと疑問だったことに対しての実験をしてみたいと思います。その疑問とは…
「隠れ層の活性化関数を外したらだめなのか?」
ってものです。
出力層における予測値は、誤差を測るために正解値と合わせないといけないって使命がありますが、隠れ層についてはそれは無いのでは?というのが疑問の発端です。最後に出てきたReLU関数を見ても、正の値については活性化関数を噛ませていないのと同じですし…。
ということでやってみたいと思います。
コードを大きく変えて式を壊してしまうのが怖かったので、とりあえずReLU関数のところを\(f(x)=x\)に変更して、ReLU関数の微分のところを\(f'(x)=1\)に変更して…実行してみました。一応、関数を噛ませたことにはなっていますが、入力をそのまま出力するので素通りですね。活性化シナイ関数です。
さて、実行後の精度のグラフを見てみますかね。
どん!
なんか、とりあえず学習を繰り返すごとに精度は上がってるっぽいですね。ReLU関数を噛ませた時に比べると精度は落ちますが、悪くはないんじゃなかろうか…。
ということで、シロウト目には、「隠れ層の活性化関数は無くてもモデル構築はできる」というように見えました。もちろん、活性化関数を噛ませることで精度が上がりやすかったり、あるいは計算が早くなったり?するのかもしれませんが、チューニングの範疇な気がします。さて、実際のところどうなんですかねー。
ということで
ついに次で本章…そして実践編が最後になりますね。体内のチャクラも残りわずかですが、駆け抜けたいと思います!(チャクラとは)
ではまた。