Chainer CNN 解説
前回はChainerをインストールし、サンプルのmnistの手書き文字認識を行いました。今回はそのプログラムの中身を見ていき解説しようと思っておりましたが、既にこんなに詳しいページが見つかりました。
http://qiita.com/kenmatsu4/items/7b8d24d4c5144a686412
http://ameblo.jp/oyasai10/entry-12118095901.html
MNISTの学習は中間層2層のNNでDeep Learningというわけではありませんでした。今回はCNN(Convolutional Nerual Networks) を下記ページを参考に行います。
http://qiita.com/hogefugabar/items/312707a09d29632e7288
# coding:utf-8 #!/usr/bin/env python """Chainer example: train a multi-layer perceptron on MNIST
This is a minimal example to write a feed-forward net.
"""
from __future__ import print_function # python 3.0系のprint関数を使う import argparse # コマンドライン引数の解析
import numpy as np # 行列・ベクトルの演算 import six # python2とpython3の間の違いを吸収すためのもの
import matplotlib.pyplot as plt # 追加
import chainer from chainer import computational_graph # from chainer import cuda # import chainer.links as L # from chainer import optimizers # from chainer import serializers #
import data # minstのデータ読み込み用 import net # ネットワークの記載
""" # 手書き数字データを描画する関数 def draw_digit(data): size = 28 plt.figure(figsize = (2.5,3)) X, Y = np.meshgrid(range(size), range(size)) Z = data.reshape(size, size) # convert from vector to 28x28 matrix Z = Z[::-1,:] # flip vertical % 画像データは原点が左上隅なため plt.xlim(0,27) plt.ylim(0,27) plt.pcolor(X, Y, Z) plt.gray() plt.tick_params(labelbottom = "off") plt.tick_params(labelleft = "off") plt.show() """
SHOW_DATA = 1
plt.style.use('ggplot')
parser = argparse.ArgumentParser(description='Chainer example: MNIST') # パーサーの宣言 parser.add_argument('--initmodel', '-m', default='', help='Initialize the model from given file') # parser.add_argument('--resume', '-r', default='', help='Resume the optimization from snapshot') parser.add_argument('--net', '-n', choices=('simple', 'parallel'), default='simple', help='Network type') parser.add_argument('--gpu', '-g', default=-1, type=int, help='GPU ID (negative value indicates CPU)') parser.add_argument('--epoch', '-e', default=20, type=int, help='number of epochs to learn') parser.add_argument('--unit', '-u', default=1000, type=int, help='number of units') parser.add_argument('--batchsize', '-b', type=int, default=100, help='learning minibatch size') args = parser.parse_args() # コマンドライン引数の解析
# 学習のパラメータ batchsize = args.batchsize # 確率的勾配降下法で学習させる際の1回分のバッチサイズ n_epoch = args.epoch # 学習の繰り返し回数 n_units = args.unit # 中間層の数
print('GPU: {}'.format(args.gpu)) print('# unit: {}'.format(args.unit)) print('# Minibatch-size: {}'.format(args.batchsize)) print('# epoch: {}'.format(args.epoch)) print('Network type: {}'.format(args.net)) print('')
# Prepare dataset print('load MNIST dataset') mnist = data.load_mnist_data() # The mnist dataset consists of 70,000 grayscale images of size 28x28 (i.e. 784 pixels) mnist['data'] = mnist['data'].astype(np.float32) mnist['data'] /= 255 # {0 1}に正規化 mnist['target'] = mnist['target'].astype(np.int32) # mnist.target : 正解データ(教師データ)
# 訓練データとテストデータに分割 N = 60000 # 訓練データの数 x_train, x_test = np.split(mnist['data'], [N]) # x_train:60000デーア、x_test:10000データ y_train, y_test = np.split(mnist['target'], [N]) # y_train:60000デーア、y_test:10000データ N_test = y_test.size #draw_digit(mnist['data'][0])
# Prepare multi-layer perceptron model, defined in net.py if args.net == 'simple': model = L.Classifier(net.MnistMLP(784, n_units, 10)) if args.gpu >= 0: cuda.get_device(args.gpu).use() model.to_gpu() xp = np if args.gpu < 0 else cuda.cupy elif args.net == 'parallel': cuda.check_cuda_available() model = L.Classifier(net.MnistMLPParallel(784, n_units, 10)) xp = cuda.cupy
# Setup optimizer optimizer = optimizers.Adam() optimizer.setup(model)
# Init/Resume if args.initmodel: print('Load model from', args.initmodel) serializers.load_npz(args.initmodel, model) if args.resume: print('Load optimizer state from', args.resume) serializers.load_npz(args.resume, optimizer)
# Learning loop for epoch in six.moves.range(1, n_epoch + 1): print('epoch', epoch)
# training perm = np.random.permutation(N) sum_accuracy = 0 sum_loss = 0 for i in six.moves.range(0, N, batchsize): x = chainer.Variable(xp.asarray(x_train[perm[i:i + batchsize]])) t = chainer.Variable(xp.asarray(y_train[perm[i:i + batchsize]]))
# Pass the loss function (Classifier defines it) and its arguments optimizer.update(model, x, t)
if epoch == 1 and i == 0: with open('graph.dot', 'w') as o: g = computational_graph.build_computational_graph( (model.loss, ), remove_split=True) o.write(g.dump()) print('graph generated')
sum_loss += float(model.loss.data) * len(t.data) sum_accuracy += float(model.accuracy.data) * len(t.data)
print('train mean loss={}, accuracy={}'.format( sum_loss / N, sum_accuracy / N))
# evaluation sum_accuracy = 0 sum_loss = 0 for i in six.moves.range(0, N_test, batchsize): x = chainer.Variable(xp.asarray(x_test[i:i + batchsize]), volatile='on') t = chainer.Variable(xp.asarray(y_test[i:i + batchsize]), volatile='on') loss = model(x, t) sum_loss += float(loss.data) * len(t.data) sum_accuracy += float(model.accuracy.data) * len(t.data)
print('test mean loss={}, accuracy={}'.format( sum_loss / N_test, sum_accuracy / N_test))
# Save the model and the optimizer print('save the model') serializers.save_npz('mlp.model', model) print('save the optimizer') serializers.save_npz('mlp.state', optimizer)