Theanoの使い方 (2) 自動微分
Theanoの使い方 (1) シンボルと共有変数(2015/5/9)のつづき。
今回はTheanoの自動微分を試してみる。ロジスティック回帰やニューラルネットなど勾配降下法を使うアルゴリズムではパラメータの更新式にコスト関数(誤差関数) の微分が必要になる。
通常、誤差関数の微分 を紙の上で解いてからその結果の数式を実装する。たとえば、前に実装した多層パーセプトロンによる関数近似(2015/1/22)では、手順 (4) で誤差関数の微分を手計算で求めてから実装している。
しかし、コスト関数が複雑になってくるとこの微分を手で計算するのは面倒くさいし間違いやすい。Theanoの自動微分では、コスト関数とどの変数について微分するかを与えるだけで自動的に微分を計算してくれるのだ。まずは、手計算できる簡単な微分を計算してみよう。
例1
まずは簡単な例で
を計算してみよう。手で計算すると
となることがすぐわかる。これをTheanoの自動微分で解いてみる。
(TensorConstant{2.0} * x) 4.0 6.0 8.0
T.grad()
のcost
に微分される数式のシンボル、wrt
に微分する変数のシンボルを入れれば、微分の数式のシンボルが返される。微分はシンボルのままでは使えないのでfunction()
で関数化してから使う。
微分の数式を表示したいときはtheano.pp()
で表示できる。TheanoチュートリアルのNoteにあるが、gy
をそのまま与えないで、関数化したあとのf.maker.fgraph.outputs[0]
を与えるとよりわかりやすい表記になる。
例2
exp(x) 7.38905609893 20.0855369232 54.5981500331
例3
cos(x) 1.0 6.12303176911e-17 -1.0
例4
Elemwise{Composite{(i0 + sqr(i1) + (i2 * (i3 + i1) * i1))}}(TensorConstant{6.0}, x, TensorConstant{2.0}, TensorConstant{-4.0}) 6.0 1.0 2.0
結果の式のi0
などは後ろの丸かっこ内の数字のプレースホルダとして使われているようだ。sqr()
は2乗を意味する。展開すると手計算した結果と同じになるのが確認できる。この奇妙な結果式は内部の微分のやり方と関係あるのかな?
例5
Elemwise{Composite{((i0 * sqr((i1 + sqrt(i2)))) / sqrt(i2))}}(TensorConstant{1.5}, TensorConstant{1.0}, x) 6.18198051534 6.46410161514
これもプレースホルダに値を入れれば手計算した結果と同じになるのが確認できる。
例6
最後に偏微分の例も試してみよう。
Elemwise{Composite{(i0 * (i1 + (i0 * i2)))}}(TensorConstant{2.0}, x, y) Elemwise{Composite{(i0 * (i1 + (i2 * i3)))}}(TensorConstant{4.0}, x, TensorConstant{2.0}, y) 10.0 12.0 20.0 24.0
自動微分は初めて知ったけれどこれはすごい。次回はこれまでの例を組み合わせたより実践的な事例として2クラスのロジスティック回帰を実装してみたい。