CONTAINER技術系のこと書きます。勾配法はニューラルネットワークなどの機械学習アルゴリズムの中で、学習するときに使われているアルゴリズム。教師データと現在の出力の誤差を計算する損失関数を与えれば、その最小値を探すことで教師データに出力を近づけることができる。見つかることが保証されているわけではなく、局所的な最適解に陥る恐れはある。使って単純な勾配法を実装してみることにする。使った環境は次の通り。インストールしておく。この関数の最小値を勾配法を使って探してみることにする。最小値を求めたい関数をグラフに図示してみることにする。main()上記のプログラムを実行すると、次のようなグラフが得られる。一階導関数を求める先ほどはグラフから最小値をあっさりと判断できたけど、それは可視化した上で人間が判断しているため。コンピュータに最小値を探させるには、別の方法が必要になる。それに、今回は変数がひとつだけなので良いものの、みっつ以上に増えれば可視化も難しくなる。そこで登場するのが今回の勾配法なわけだけど、これにはまず最小値を求めたい関数を微分する必要がある。ちなみに、このやり方であれば人間の判断は必要なくなって、変数が増えたときにも偏微分で対応できる。微分したものをグラフにしてみよう。main()最終的には微分までコンピュータにやらせるけど、ここではあえて人間が微分している。上記を実行すると、次のようなグラフが得られる。青色の線が最小値を求めたい関数で、緑色の線が一階導関数になっている。境にして、一階導関数の出力がプラスとマイナスに切り替わっていることが見て取れる。勾配法では、この最小値を境にして一階導関数のプラスとマイナスが切り替わるところが重要になる。一階導関数の符号を反転してみると?先ほどの一階導関数をそのままプロットしたグラフでは、最小値よりも大きい範囲ではプラスに、小さい範囲ではマイナスになっていた。main()上記を実行すると、次のようなグラフが得られる。(グラフでは凡例にマイナス符号を付けるのを忘れていた)今度のグラフでは一階導関数が最小値を境にして大きい範囲ではマイナス、小さい範囲ではプラスになっている。すると、符号を反転した一階導関数の出力は、最小値に近づけるために必要な移動方向と一致することが分かる。最小値は符号を反転した一階導関数を出力が指し示す方向にあるということになる。あとは、その指し示す方向を頼りに徐々に移動していけば、いつかは最小値にたどり着ける。いえ、もちろんたどり着いた先が局所的な最適解で、実際の最小値が別にある可能性はある。これはようするに、関数の出力がぐねぐねしていて、ところどころに凹みがあると、そこにハマってしまうということ。勾配法ここで勾配法のアルゴリズムを数式で書いてみよう。学習率と呼ばれるもので、どれくらいの勢いで最小値に近づいていくかを表している。最小値を探したい関数の一階導関数になっている。勾配法では、上記の作業を複数回繰り返すことで最小値を探す。いう関数で勾配法を実装している。上記の工程を何回繰り返すかを表す。設定した上で最小値をそこから探していく。main()上記を実行すると次のような出力が得られる。ハイパーパラメータと呼ばれていて人間が適切に選ぶ必要がある。これは大きくても小さくても上手くいかない。大きすぎれば移動する量が大きすぎていつまでも収束せず、小さすぎれば最小値になかなか近づかない。は大きすぎれば計算量が大きくなりすぎるし、小さすぎれば最小値に近づくまでに終了してしまう。最小値に収束していく様子を可視化してみる先ほどは最小値に収束した結果だけを出力にしたけど、次は収束していく様子を可視化してみる。main()上記を実行すると、次のようなグラフが得られる。近づいていくことが見て取れる。微分をコンピュータにやらせるここまでで勾配法を使って最小値を探すことができることは分かった。先ほどの例ではまだ人間が最小値を探したい関数を微分していた。これをどうにかしないことには機械学習には使えない。そこで、まずは微分の定義から見直してみよう。得る、という意味になっている。これをそのまま実世界のコンピュータに適用することはできない。小数を実装したコンピュータでは正しく扱うことができない。あまりにも小さい値は丸め誤差で無視されてしまう。1e-1001.0そのため、定義どおりに限りなくゼロに近づけたような値ではなく、丸め誤差で無視されない程度に小さな値を使うことになる。限りなくゼロに近づけた値が使えないために生じる問題がある。加えて傾きを求めるとしよう。そこで、上記の問題を解決するために中央差分というものを使って変化量を求める。差分を使って傾きを求めるというもの。試しに、上記で説明した中央差分を使った微分で一階導関数を求めてみよう。いう関数で中央差分を元にした微分を実装している。main()ちなみに、先ほどのように人間が数式から手計算で微分することを解析的な微分と呼ぶ。それに対し、上記サンプルコードのようなコンピュータを使った近似的な微分を数値微分という。上記を実行すると次のグラフが得られる。グラフで見る限り解析的な微分したときと同じ結果が得られている。数値微分を勾配法に組み込んでみる今回の記事の最終形態として、先ほどの勾配法に数値微分を組み込んでみよう。main()上記の実行結果は次の通り。1.4272476927065283e-05解析的な微分を使っていたときとわずかに値は異なるものの、ほぼ同じ値が得られている。未処理の例外が上がったときの処理をオーバーライドする注目記事スポンサードリンクスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。