TIM Labs

Chainer:初期勾配を与えたら配列でも微分できた

| コメント(0) | トラックバック(0)
前回、変数を配列にしたらエラーがでてしまった。

それで、やはりマニュアル、イントロなどを読まねばと非常にまともなことを考えて読み始めた。

Introduction to Chainerの中のForward/Backward Computationに、配列を与えた場合の微分の例が見つかった。

こういうときは、初期勾配(全要素が1.0)を用意してからbackward()をやらないといけないらしい。
それで、このように変更してみた。
>>> y = F.sin(x)
>>> y.grad = np.ones(21,dtype=np.float16)     # 追加, 勾配の初期化
>>> y.backward()
>>> x.grad
array([ -1.00000000e+00,  -9.51171875e-01,  -8.09082031e-01,
        -5.87890625e-01,  -3.08837891e-01,   4.83751297e-04,
         3.08837891e-01,   5.87890625e-01,   8.09082031e-01,
         9.51171875e-01,   1.00000000e+00,   9.51171875e-01,
         8.09082031e-01,   5.87890625e-01,   3.08837891e-01,
         4.83751297e-04,  -3.08837891e-01,  -5.87890625e-01,
        -8.09082031e-01,  -9.51171875e-01,  -1.00000000e+00], dtype=float16)
これで、配列xの各値に対するsin(x)の微分係数が求まっているはず。
もちろん、sin(x)の微分はcos(x)なので確認しよう。

>>> dy = F.cos(x)
>>> dy.data
array([ -1.00000000e+00,  -9.51171875e-01,  -8.09082031e-01,
        -5.87890625e-01,  -3.08837891e-01,   4.83751297e-04,
         3.08837891e-01,   5.87890625e-01,   8.09082031e-01,
         9.51171875e-01,   1.00000000e+00,   9.51171875e-01,
         8.09082031e-01,   5.87890625e-01,   3.08837891e-01,
         4.83751297e-04,  -3.08837891e-01,  -5.87890625e-01,
        -8.09082031e-01,  -9.51171875e-01,  -1.00000000e+00], dtype=float16)
どうやら一致しているようだが、目視確認なんて面倒くさい。

ということで、こうやって確認した。
>>> x.grad-dy.data
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.], dtype=float16)
Lazyはプログラマの最大の美徳であることを忘れてはいけない。
Lazyな確認方法により信頼性が一気に向上した。

これで、どうやらsin(x)の微分はできているみたいだが、こんな簡単な微分ができたから、Chainerの微分がちゃんと動作していると考えるのは甘いだろう。
次からは、もっと複雑な関数を微分してみよう。

トラックバック(0)

トラックバックURL: http://labs.timedia.co.jp/mt/mt-tb.cgi/553

コメントする

このブログ記事について

このページは、fujiが2017年1月25日 00:00に書いたブログ記事です。

ひとつ前のブログ記事は「書評:『Chainerによる実践深層学習』」です。

次のブログ記事は「Chainer:もっと複雑な関数を微分してみよう」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。