前回、特定の値に対する微分係数を求めた。
式で書けば, 関数 f(x) に 対して x=a のときの微分係数 f'(a) を求めた。
そのとき、
x = Variable(np.array([5.0],dtype=np.float16))
として変数xを用意したのだが、np.array([5.0])で、スカラーを要素数1個の配列でわざわざ与えた。
ということは、配列に対しても、そのまま動くのではないだろうか。
ということで、 sin(x) を -np.pi <= x <= np.pi の区間内の複数の点に対して一気に計算してみよう。
まず、配列の生成を確認。
>>> np.array(np.linspace(-np.pi, np.pi, 21))
array([-3.14159265, -2.82743339, -2.51327412, -2.19911486, -1.88495559,
-1.57079633, -1.25663706, -0.9424778 , -0.62831853, -0.31415927,
0. , 0.31415927, 0.62831853, 0.9424778 , 1.25663706,
1.57079633, 1.88495559, 2.19911486, 2.51327412, 2.82743339,
3.14159265])
この配列を与えて、chainerの変数xを配列で作ってしまおう。
>>> x = Variable(np.array(np.linspace(-np.pi, np.pi, 21), dtype=np.float16))
>>> x.data
array([-3.140625 , -2.828125 , -2.51367188, -2.19921875, -1.88476562,
-1.5703125 , -1.25683594, -0.94238281, -0.62841797, -0.31420898,
0. , 0.31420898, 0.62841797, 0.94238281, 1.25683594,
1.5703125 , 1.88476562, 2.19921875, 2.51367188, 2.828125 ,
3.140625 ], dtype=float16)
値が少々違うが、これはnp.float16としたため、精度が落ちているのでやむを得ないだろう。
F.sin(x)にて配列xの各値に対して、まとめてsin(x)が求まるはずである。
>>> y = F.sin(x)
>>> y.data
array([ -9.67502594e-04, -3.08349609e-01, -5.87402344e-01,
-8.09082031e-01, -9.51171875e-01, -1.00000000e+00,
-9.51171875e-01, -8.09082031e-01, -5.87890625e-01,
-3.09082031e-01, 0.00000000e+00, 3.09082031e-01,
5.87890625e-01, 8.09082031e-01, 9.51171875e-01,
1.00000000e+00, 9.51171875e-01, 8.09082031e-01,
5.87402344e-01, 3.08349609e-01, 9.67502594e-04], dtype=float16)
yの値は、 -1 <= sin(x) <= 1 に収まっているようだ。
次に、y.backward() で微分してみよう。
>>> y.backward()
Traceback (most recent call last):
File "", line 1, in
File "/home/fuji/anaconda3/lib/python3.5/site-packages/chainer/variable.py", line 388, in backward
gxs = func.backward(in_data, out_grad)
File "/home/fuji/anaconda3/lib/python3.5/site-packages/chainer/function.py", line 382, in backward
return self.backward_cpu(inputs, grad_outputs)
File "/home/fuji/anaconda3/lib/python3.5/site-packages/chainer/functions/math/trigonometric.py", line 25, in backward_cpu
gx *= gy[0]
TypeError: ufunc 'multiply' output (typecode 'O') could not be coerced to provided output parameter (typecode 'e') according to the casting rule ''same_kind'
>>>
ということで、backward()したとたんに叱られた。
要素数1だと大丈夫だったのだが、複数個に対してはダメなんだ。
何か悪いことをしたらしい。
次回までに原因を考えることにし、今日はここまで。