FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

ゼロから作るDeep Learning ③ のDezeroをRubyで作り直してみる(ステップ29/ステップ30)

ゼロから作るDeep Learning ❸ ―フレームワーク編

ゼロから作るDeep Learning ❸ ―フレームワーク編

  • 作者:斎藤 康毅
  • 発売日: 2020/04/20
  • メディア: 単行本(ソフトカバー)

ゼロから作るDeep Learning ③のDezero実装、勉強のためRubyでの再実装に挑戦している。計算グラフが表示できるようになって、いよいよ難しそうなところに突入していく。今回はステップ29とステップ30。

ニュートン法により関数の最小値を求める方法を探っていく。勾配降下法との違いは、最小値を決めるためのステップを定数として固定するのではなく、テイラー展開により決める点にある。ここで必要なのは、テイラー展開による2次微分を求めるというところなのだが、現在のDeZeroでは1次微分までを求めることはできるが2次微分までは行えない。とりあえずは2次微分は自力で実装しておいて、ニュートン法の正しさを確認する。

def f(x)
  y = x ** 4 - (x ** 2) * 2
  return y
end

def gx2(x)
  return (x ** 2) * 12 -4
end


x = Variable.new(np.array(2.0))
iters = 10

for i in 0..iters do
  puts [i, x.to_s].to_s

  y = f(x)
  x.cleargrad()
  y.backward()

  x.data -= x.grad / gx2(x.data)
end

実行結果は以下となった。わずか10ステップで値を最小値まで持ってくることができた!

[0, "variable(2.0)"]
[1, "variable(1.4545454545454546)"]
[2, "variable(1.1510467893775467)"]
[3, "variable(1.0253259289766978)"]
[4, "variable(1.0009084519430513)"]
[5, "variable(1.0000012353089454)"]
[6, "variable(1.000000000002289)"]
[7, "variable(1.0)"]
[8, "variable(1.0)"]
[9, "variable(1.0)"]
[10, "variable(1.0)"]
  • ステップ30:高階微分を求めるための下準備。

高階微分を求めるためにDeZeroを改良していく。ここでの問題点は、forward()により計算グラフを作ったのは良いが、backward()では計算グラフを構築しないという点。そこでVariable.gradについてもVariableで管理することによってbackward()において計算グラフを作成すること考える。これが次回の課題となる。