ChainerはVariableに変数を渡してforwardパス、backwardパスを計算するので、パス内に特殊な操作が入ると計算ができなくなる、と困るのでいくつかchainer.functionsに便利な関数が用意されていた。ipython起動してchainer.functionsをインポートしてからdir(chainer.functions)とかで一度関数の一覧を見てみると結構役に立ちそうな関数があったりする。
今回は主に配列や行列操作でお世話になったので、それらをメモとしてまとめておく。
以下、
from chainer import functions as F
とする。
F.reshape(shape) numpy.reshapeのVariable版。
F.broadcast_to(x,shape)
numpy.broadcast_toのVariable版。配列や行列のxをshape(タプル)に拡張してくれる。F.swapaxes(x,a,b)
numpy.swapaxesのVariable版。aの次元とbの次元の数が逆になるように行列を操作してくれる。F.transpose(x)
numpy.transposeのVariable版。F.expand_dims(x,axis)
axisで指定した次元を新たに挿入する。axis=0でVariable([x])と同じことをしてくれる(Variableを呼び出すと再定義になってbackwardできなくなってしまうのでこれを使う)F.split_axis(x,split_size,axis)
axisで指定した次元についてsplit_sizeコの配列or行列になるように分割してくれる。分割してできたVariable達はタプルで返される。F.concat(x,axis)
axisで指定した次元について配列もしくは行列を結合する。Mコの2次元配列を組み合わせて3次元配列をつくる場合、F.expand_dims(hoge,0)としてxを3次元配列にしてから使わないとエラーが起こるF.matmul(a,b,transa=False,transb=False) numpy.dot,numpy.tensordotのVariable版。何気に転置してくれるtransa,transbがついている。別にF.transposeしても同じだと思うけど、せっかくなので使ってる。
F.batch_matmul(x,y) F.matmulのバッチ付き版。例えば、3次元配列X(MxAxB)とY(MxBxC)があるとすると、以下と同じ計算を効率的にやってくれている。
Z=[] for i in range(M): temp=F.matmul(X[i],Y[i]) Z.append(F.expand_dims(temp,0)) Z=F.concat(Z,0)
for文を使わなくて良くなるのが助かる。中身はnumpy.tensordotとか使ってForwardとBackwardを定義している。
ソースコードを読んだら自分でもchainerのfunctionを書いてみたくなった。