theano.tensor で書いた関数を自動的に微分することができる。
ただし、関数で計算した結果得られる値はスカラーでなければならない。
ベクトルや行列になっているとエラーとなる。
gradを使った例を次に示す。
import numpy import theano import theano.tensor as T x=T.dscalar('x') v=T.dvector('v') M=T.dmatrix('M') y1=x**3 y2=T.dot(v,v)*x y3=T.sum(T.dot(M,M)) gy1=T.grad(y1,x) gy2=T.grad(y2,v) gy3=T.grad(y3,M) f1=theano.function([x],gy1) f2=theano.function([x,v],gy2) f3=theano.function([M],gy3) print "f1 :",theano.pp(f1.maker.fgraph.outputs[0]) print "f2 :",theano.pp(f2.maker.fgraph.outputs[0]) print "f3 :",theano.pp(f3.maker.fgraph.outputs[0]) print "f1(2) =",f1(2) print "f2(2,[3,5]) =",f2(2,[3,5]) print "f3([[1,2],[3,4]]) =",f3([[1,2],[3,4]])
実行すると、
f1 : Elemwise{Composite{[mul(i0, sqr(i1))]}}(TensorConstant{3.0}, x) f2 : Elemwise{Composite{[add(*1 -> mul(i0, i1), *1)]}}(x, v) f3 : gemm_inplace(_dot22(alloc(TensorConstant{(1, 1) of 1.0}, Shape_i{0}(M), Shape_i{1}(M)), M.T), TensorConstant{1.0}, M.T, alloc(TensorConstant{(1, 1) of 1.0}, Shape_i{0}(M), Shape_i{1}(M)), TensorConstant{1.0}) f1(2) = 12.0 f2(2,[3,5]) = [ 12. 20.] f3([[1,2],[3,4]]) = [[ 7. 11.] [ 9. 13.]]が得られる。f1 の出力を見ると、mul が掛け算で sqr が2乗、i0=TensorConstant{3.0}、
i1=x であるから、y1 を x で微分した結果である 3*x^2 が得られていることがわかる。
f2 と f3 は複雑すぎて読み方がわからないが、具体的な値を入れた結果は
正しく出力されている。
エラーが出る例として、ベクトルが戻り値になるような関数を試してみる。
import numpy import theano import theano.tensor as T x=T.dscalar('x') v=T.dvector('v') y=v*x gy=T.grad(y,x)すると、
Traceback (most recent call last): File "test.py", line 8, in <module> gy=T.grad(y,x) File "/usr/local/lib/python2.7/dist-packages/theano/gradient.py", line 411, in grad raise TypeError("cost must be a scalar.") TypeError: cost must be a scalar.といわれて微分できない。
0 件のコメント :
コメントを投稿