覚え書きブログ

読者です 読者をやめる 読者になる 読者になる

Deep Learning覚え書き(Chainerのインストール編)

ディープラーニング

PFNがChainerという新しいDeep Learningのフレームワークを公開したので、早速インストールしてみた。
http://chainer.org/chainer.org

インストールは、git cloneを使えば簡単にできる。

> git clone https://github.com/pfnet/chainer.git

次に、MNISTのサンプルコードを実行してみたが、次のようなエラーがでた。

> python chainer/examples/mnist/train_mnist.py
Traceback (most recent call last):
  File "chainer/examples/mnist/train_mnist.py", line 11, in <module>
    from chainer import cuda, Variable, FunctionSet, optimizers
ImportError: No module named chainer

環境変数PYTHONPATHに、chainerモジュールのパスを追加してみると、下記のようにMNISTのサンプルコードを実行することが出来た。

> export PYTHONPATH=~/Works/DeepNet/chainer:$PYTHONPATH
> python chainer/examples/mnist/train_mnist.py
fetch MNIST dataset
epoch 1
train mean loss=0.275178533252, accuracy=0.915666669135
test  mean loss=0.108640040111, accuracy=0.966200004816
epoch 2
train mean loss=0.139073197367, accuracy=0.956600004435
test  mean loss=0.0889382731105, accuracy=0.97180000782
epoch 3
train mean loss=0.109916572729, accuracy=0.966483339965
test  mean loss=0.0765921290717, accuracy=0.975200003386
epoch 4
...
epoch 19
train mean loss=0.0452081310556, accuracy=0.986866676609
test  mean loss=0.0711012239701, accuracy=0.982900006175
epoch 20
train mean loss=0.0445344028511, accuracy=0.986650010943
test  mean loss=0.0631615034466, accuracy=0.983500006795

Chainerの特徴は、ネットワーク構造の定義から学習したモデルの保存まで、全ての処理を、Python上で行うシンプルなところである。例えば、caffeではネットワーク構造はprotocol bufferで定義し、学習したモデルはcaffemodelという拡張子のファイルに保存されていたが、Chainerではそんなまどろこしいはしない。

例えば、MNISTのサンプルコードでは、4層のネットワーク(入力層:784ノード、中間層1:1000ノード、中間層2:1000ノード、出力層:10ノード)をpythonコード上で次のように定義している。

# Prepare multi-layer perceptron model
model = FunctionSet(l1=F.Linear(784, 1000),
                    l2=F.Linear(1000, 1000),
                    l3=F.Linear(1000, 10))

# Neural net architecture
def forward(x_data, y_data, train=True):
    x, t = Variable(x_data), Variable(y_data)
    h1 = F.dropout(F.relu(model.l1(x)),  train=train)
    h2 = F.dropout(F.relu(model.l2(h1)), train=train)
    y  = model.l3(h2)
    return F.softmax_cross_entropy(y, t), F.accuracy(y, t)

具体的には、まず、F.Linearは、2つの層の間にある重み行列Wのサイズを設定し、バイアスbとともに初期化している。例えば、l1=F.Linear(784,1000)では、784x1000の大きさの重み行列W1と、1000次元のベクトルb1を初期化している。

次に、forward関数では、各層の処理を入力層から順番に記述している。例えば、「h1 = F.dropout(F.relu(model.l1(x)), train=train)」では、変数xが与えられた下で、W1^Tx+bを計算し、次にReLUをかけて、その後dropoutしたものを、h1変数に入力する処理を記述している。

MNISTのサンプルコードでは、学習したモデルは保存されていないが、imagenetのサンプルコード、examples/imagenet/train_imagenet.pyでは、最後に、pickleダンプを使って保存している。

# Save final model
pickle.dump(model, open('model', 'wb'), -1)

まさに、最初から最後までpythonで簡潔するので、非常にわかりやすいコードである。ちなみに、私は学生の頃に書いたことがある自分のニューラルネットワークのコードを思い出した。ということで、Chainerは学生には受けそうである(企業ではどうだろうか?)。