はじめに
この記事は古川研究室 Workout calendar 9日目の記事です. 本記事は古川研究室の学生が学習の一環として書いたものです.
Workout_calendar盛り上がって嬉しいです。今週の金曜にいよいよ新入生の投稿が始まります!
本記事の目的
Pytorchの自動微分機能を使って, 勾配法を実現します!!
最急降下法
勾配法として最も単純な方法である。
勾配法は $n$次ベクトル $\mathbf{x} = (x_1,x_2,...,x_n)$を引数とする写像 $f(\mathbf{x})$ の極値を求める手法の一つである.
反復法, 学習を繰り返して $\mathbf{x}$を更新する.
$t$時刻目の学習の解が$\mathbf{x}^{(t)}$であるとき, 最急降下法では次のように値を更新する.
\begin{align}
\mathbf{x}^{(t+1)} &= \mathbf{x}^{(t)}-\eta \operatorname{grad} f\left(\mathbf{x}^{(t)}\right) \\
\\
&= \mathbf{x}^{(t)}-\eta \left[\begin{array}{c}{\frac{\partial f\left(\mathbf{x}^{(t)}\right)}{\partial x_{1}^{(t)}}} \\ {\frac{\partial f\left(\mathbf{x}^{(t)}\right)}{\partial x_{2}^{(t)}}} \\ {\frac{\partial f\left(\mathbf{x}^{(t)}\right)}{\partial x_{2}^{(k)}}} \\ ・\\ {\frac{\partial f\left(\mathbf{x}^{(t)}\right)}{\partial x_{n}^{(k)}}}\end{array}\right]
\end{align}
ここで$\eta$はステップ幅である. ステップ幅が大きくなると更新量は大きくなるが発散の恐れがある. 逆にステップ幅が小さすぎると学習は遅れてしまう.
実装
今回使う写像(関数): $$ E(\mathbf{x}) = x_1^2 + x_2^2$$
n_epoch = 200 # 学習回数
eta = 0.01 # ステップ幅
x = torch.tensor([2.0,2.0],requires_grad=True) # (x_1, x_2)
A = torch.tensor([[1.0,0.0],[0.0,1.0]])
for epoch in range(n_epoch):
quad = torch.einsum("i,ij,j",x,A,x) # f
quad.backward()
with torch.no_grad():
x = x - eta * x.grad
x.requires_grad = True
実装メモ
$\mathbf{x}$: optionにrequires_grad = Trueが必要.
$quad$ : 偏導関数はスカラー値である必要がある.
結果
青のマットは今回の関数の形で, 黒の $x$ は $t$ 時刻目の更新する点です. 黄色の点線は学習の軌跡になっています. 横軸(x,y)が$\mathbf{x}$の成分で, 縦軸(z)が関数の値になっています.
$(x_1, x_2) = (2.0, 2.0)$ を初期値として, 関数の最小値に向かっていることが確認できました.
まとめ
次はこれと前回あげた Nadaraya-Watson推定 の実装を組み合わせて, 自分の研究の基盤技術を実現しようと思います.
参考ページ
ソースコード
今回もGithubとColabにソースコードあげております.
ビューワーありで動かしたい方はよかったら参考にしてください.
Special Thanks
コード提供: Watanabe さん