どうも、カタミチです。
さて、今日も「最短コースでわかる ディープラーニングの数学」のひとり読書会、やっていきたいと思います。
今日も「発展編」の内容ですね。いってみよ〜
11-4. 数値微分
ディープラーニングの根幹をなす勾配降下法に使われる「微分計算」ですが、アルゴリズム的には2つのアプローチがあるようです。ひとつは、これまで学んだように数式で微分計算を行ってから値を入れるアプローチですが、もうひとつのアプローチに「数値微分」というものがあるようです。
計算のベースとなるのは、微分の定義式…
\( \lim_{h \to 0} \frac{f(x+h)-f(x)} {h} \)
に対して少し変形した…
\( \lim_{h \to 0} \frac{f(x+h)-f(x-h)} {2h} \)
これです。微分の定義式の意味を損なわない変形になっていますね。
\(h\)を0に近づけるっていうのを、例えば\(h=0.001\)と置けば、苦労して式を微分しなくても数値代入だけである程度正確なんじゃね?というのが基本的な考えのようです。
例えば\(f(x)=e^x\)のときの\(f'(0)\)を求めたい場合、数式微分でやると、
\(f'(x)=e^x\) であるため、
\(f'(0)=e^0=1\) となりますね。
数値微分を使うと
\( f'(0)= \frac{e^{0+0.001}-e^{0-0.001}} {2 \cdot 0.001} \)
ってことになります。手計算だと面倒ですが、コンピュータにとっては楽勝ですね。Pythonのプログラムで書いてやると、結果は…
1.0000001666666813
となりました。うん、確かに結構正確に表してるっぽいですね。ちなみに、ケタをひとつ下げて\(h=0.0001\)にしてみたら、こんな感じになりました。
1.0000000016668897
うん、さらに精度が上がりました。ケタを下げれば下げるほど精度は上がると思うので、どこまで精度を求めるか?ってところですかねー。
ちなみに、気になったので微分の元の定義式\( \lim_{h \to 0} \frac{f(x+h)-f(x)} {h} \)に対して、\(h=0.0005\)として同じ様に計算してみたところ…
1.000250041671702
になりました。当たり前ですが、元の定義式を使っても似たようなことはできそうですね。変形後の定義のほうが精度が良いのは、微分の変化の中心を算出したい点に合わせたから…ってことになりますかねー。
11-5. 高度な学習法
この節では、勾配降下法の式の部分に手入れをする方法に触れられています。
勾配降下の式は、損失関数の微分をナブラ(\(\nabla\))って記号を使って\( \nabla L \)と表すとすると、こんな風に書けます。
\( \boldsymbol{W}^{(k+1)}= \boldsymbol{W}^{(k)}- \alpha \nabla L \)
Momentum
これに対してまず、Momentumという手法があるようです。ベクトルの「向き」に関して働きかけるもので、「勾配計算に当たって、繰り返し計算の過去のステップのベクトルも使う」というやり方です。具体的には、重み計算の過程に「モーメント行列:\( \boldsymbol{V} \)」を挟んだ、こんな感じの式になります。
\( \boldsymbol{V}^{(k+1)}= \gamma \boldsymbol{V}^{(k)}- \alpha \nabla L \)
\( \boldsymbol{W}^{(k+1)}= \boldsymbol{W}^{(k)}+ \boldsymbol{V}^{(k+1)} \)
式の意味を考えてみたんですが、例えば\(\boldsymbol{V}^{(k)}\)が\(0\)だとしたとき、\( \boldsymbol{V}^{(k+1)}= - \alpha \nabla L \)になるので、\( \boldsymbol{W}^{(k+1)}\)の式が勾配降下法の式と一致しますね。で、その次の繰り返しではどうなるかと考えてみると…勾配降下の式に「前回のベクトルの方向を足し算」することになりますね。ベクトル的には、前回の方向に少し引っ張られる感じでしょうかね。
ちなみに、momentumとは「勢い」とか「惰性」って意味みたいです。確かに、前回の勢いが余韻として残っている雰囲気がありますね。
その余韻の強さを表すのが\( \gamma \)ですね。このパラメータを減衰率と呼ぶようです。人が設定すべきパラメータがひとつ増えることになりますが、これによって収束が早まるのなら安いもの…ってことですかねー。
ところで、\(\boldsymbol{V}^{(k)}\)ってのが実体を持っている以上、純粋にベクトルの向きだけを補正するわけではなく、ベクトルの大きさにも少なからず影響は与えそうな気がしますがどうなんでしょうねー。
RMSProp
続いては、RMSProp。こちらはベクトルの大きさに着目したもののようです。勾配降下式で言うと\( \alpha \)の部分ですね。式としてはこんなやつみたいです。
\( h_{ij}^{(k+1)}= \alpha \cdot h_{ij}^{(k)}+ (1- \alpha) (\frac{\partial L}{\partial w_{ij}})^2 \)
\( \eta_{ij}^{(k+1)}= \frac{\eta_0} { \sqrt{h_{ij}^{(k+1)}}+\epsilon } \)
\( w_{ij}^{(k+1)}= w_{ij}^{(k)}- \eta_{ij}^{(k+1)} \frac{\partial L}{\partial w_{ij}} \)
…もはや、何がどういう調整でこうなったのかは分かりません(汗)が、とりあえず\( h_{ij}^{(k+1)}\)に対して\(h_{ij}^{(k)}\)が効いてるってことは、繰り返しの一つ前の結果を影響させていることは間違いないようです。与える必要があるパラメータは、\(\alpha,\epsilon,\eta_0\)の3つですかね?
高度な学習法ってだけあって、やはり込み入ってきますねー。ちゃんと理屈も理解していきたいところではありますが、このへんは理論は置いといてとりあえず使いこなせれば良い…って感じなのかなー。
Adam
最後に紹介されていたのがAdamですね。Momentumの「向き」の工夫、RMSPropの「大きさ」の工夫の両方を含むもののようです。これについては本書にも式は紹介されていなかったので、より深く行く場合はそこから探る感じになりますかねー。
ちなみに、今回紹介されていたMomentum、RMSProp、Adamについては、以前G検定の勉強したときも少しだけ触れていましたね。
…なんだか、勾配降下法の説明含めて、改めて見てみるとだいぶ理解できている自分に気付かされます(自己発見)。
ということで
数値微分の考え方は興味深かったですね。いろんな微分の公式を知らなくても、とりあえず微分の大本の公式のに突っ込んで、\(h\)をめっちゃ小さな値にすればできあがり…ってことですもんね。これまで覚えたすべての微分の基本公式をぶっ飛ばす勢いでしたが、人間としては式で見たほうが分かりやすいからまぁいいかー。
また、勾配降下法とひとことに言っても、工夫の余地はまだまだあるようですね。しかし、基本を理解してこそ高度な方法が理解できる…というのは痛感しました。やっぱり、積み上げって大事ですね。
ではまた。