[パラメータ更新の基礎]機械学習における勾配と微分を理解する
IT技術
勾配の計算から理解する、機械学習における微分の基礎
機械学習のトレーニングには、「勾配降下法」や「誤差逆伝播法」などの、勾配計算プロセスを用います。
そして、これらは微分を用いて計算されます。
今回は、勾配計算の基礎を理解するため、「機械学習における勾配の仕組み」と「微分がどのように使われているか」を解説していこうと思います!
実装環境
まず、実装環境です!
Colaboratory 上で、以下をインポートしています。
1#実装環境
2%matplotlib inline
3import matplotlib.pyplot as plt
4import numpy as np
微分の基礎をふりかえる
まず簡単に、微分の復習から始めましょう!
公式を用いることで、微分の計算は比較的容易にできると思います。
ですが、大事なのは「微分がどのような処理を行っているか?」を理解することです。
微分では、変数の微小な変化を考え、それによって関数がどう変化するかを調べます。
下の図は、「関数 f (x)」のグラフに対する微分を考えており、微分の過程を表した図なります。
「変数 x」の変化量を「h」とすると、この間( x と x+h )を結ぶ直線の傾きを求めることができます。
微分では、微小変化を考えたいので、「h」を限りなくゼロに近づけていきます。
すると、「x」の点で接する接線の傾きを求めることができ、瞬間的な傾きという変化量を得ることができます。
これを式にすると、以下のようになります。
ここで、「h」を限りなくゼロに近づけることを、「極限」と呼び、「」で表されます。
ですが実際には、コンピュータ上で限りなくゼロに近い変化を表すことが難しいです。
そのため、下図のような中心差分を用いた数値微分により、計算されます。
Pythonで実装してみる
これを Python で実装すると、以下のようになります。
1#数値微分の定義
2def numerical_diff(f, x):
3 h = 1e-4 #微小変化
4 return (f(x + h) - f(x - h)) / (2 * h)
計算してみる
また、これを用いて計算します。
1#関数を定義
2def fun1(x):
3 return x ** 3
4
5#x=10の時の数値微分
6numerical_diff_10 = numerical_diff(fun1, 10)
7print(numerical_diff_10)
出力:300.00000000939053
「関数f」の x=10 における、接線の傾きが計算されました!
ちなみに、この値を傾きとする接線をプロットしたものが、上の図になっています。
接線の描画コード
1#接線の関数定義
2def tangent_line(x, y, a):
3 b = y - a * 10
4 return a * x + b
5
6#描画(上の図では目盛りと目盛りラベルは消しています。)
7fig = plt.figure(figsize=(6, 5), dpi=100, facecolor="w")
8x = np.arange(0, 25, 0.1)
9y = fun1(x)
10y_tangent_line = tangent_line(x, fun1(10), numerical_diff_10)
11
12plt.plot(x, y, color="k")
13plt.plot(x, y_tangent_line, color="lightseagreen")
14plt.xlim([0, 20])
15plt.ylim([-2000, 5000])
16plt.xlabel('x')
17plt.ylabel('f(x)')
18plt.legend(["y = f(x)", "Tangent line"])
19
20plt.show()
一般的に、世の中の問題において、1つの変数で結果が決まることは少ないでしょう。
人工知能は、様々な「変数要因(多変数関数)」から分類を行ったり、結果を推測したりします。
そのため、機械学習では「偏微分」が使用され、以下の式で表されます。
偏微分では、ある1つの変数にのみ注目し、その他の変数は定数として微分します。
これによって、ある1つの変数が微小変化した時の、関数の接線の傾きを計算します。
以上のように、微分を用いて求められる関数の傾きを、一般的に「勾配(Gradient)」と言います。
そして得られた勾配は、変数の増加に対して関数が増減する方向と量を意味しています。
この事から、勾配は「関数を減らす方向を指すベクトル」として表されます。
機械学習ではこれを利用し、目的関数を各パラメータで微分することで、目的関数の最小値を探します。
例えば「目的関数 L」に対して、「あるパラメータ w」で微分し、勾配が得られたとします。
この時のパラメータ更新は、以下の式で表されます。
「目的関数 L 」の「パラメータ w」による微分は、「w」を増加させるとだけ増加すると言えます。
そのため、減少させるには、元々の「w」からを引くことで、減少方向への更新ができます。
また、は「学習率(Learning rate)」と言い、勾配にかけることで、一回の学習でどの程度パラメータを更新するかを、調整するものです。
学習率は、予め人の手によって設定する必要がある「ハイパーパラメータ」であり、最適値を様々な値で試しながら探す必要があります。
パラメータの更新は、上記式を用いて「関数の最小値を示す勾配方向に向かって、関数の値を徐々に減らすよう」に行われます。
この手法を「勾配法」と言います。
機械学習の最適化プロセスでは、得られた勾配を用いて、上記の更新式でパラメータの値を更新します。
さらに、更新した先でまた勾配を求め、同じようにパラメータを勾配方向へ更新していきます。
これを繰り返すことで、以下の図のように、徐々に目的関数の最小値へと近づいていくのです。
パラメータを更新していった結果、関数の最小値では傾き(勾配)はゼロとなります。
つまり、その点が目標となるパラメータの値と言えます。
このように、徐々に最小値に近づいていく更新処理を、「勾配降下法(Gradient Descent Method)」と呼びます。
これは、機械学習(特にニューラルネットワークなど)の最適化問題においてよく使用されます。
さいごに
今回は、「勾配」と「微分」から、機械学習のパラメータ更新の仕組みについて解説しました。
実践的には、「勾配降下法」よりも高速な「誤差逆伝播法」など、計算方法は色々あります。
その導入の助けになればと思ってます!
こちらの記事もオススメ!
2020.07.28機械学習 特集知識編人工知能・機械学習でよく使われるワード徹底まとめ!機械学習の元祖「パーセプトロン」とは?【人工知能】ニューラルネ...
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit