keras2とchainerの使い方をCNNでくらべてみる
目的:keras2とchainerの使い方の違いを知る
まとめ:
keras2はmodelの最初の層以外の入力は記述しなくても良い。バックエンドがtheanoとtensorflowで入力の配列が異なる。
chainerはmodelの層追加時、入力と出力の数を記入。入力でNoneと記述すると自動的に計算してくれる。Conv->Linearの際に便利。
参考:
出力ノード数を手計算せずにConvolutionの出力をLinearに入力する(chainer 1.15) - Qiita
わかりやすい↓
Chainer: ビギナー向けチュートリアル Vol.1 - Qiita
わかりやすい↓
Keras tips: 様々な画像の前処理をカンタンにやってくれるkeras.preprocessingのまとめ - MATHGRAM
keras2
mnistをcnnで学習するサンプル
'''Trains a simple convnet on the MNIST dataset. Gets to 99.25% test accuracy after 12 epochs (there is still a lot of margin for parameter tuning). 16 seconds per epoch on a GRID K520 GPU. ''' from __future__ import print_function import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D from keras import backend as K batch_size = 128 num_classes = 10 epochs = 12 # input image dimensions img_rows, img_cols = 28, 28 # the data, shuffled and split between train and test sets (x_train, y_train), (x_test, y_test) = mnist.load_data() # backendがtensorflowとtheanoで配列のshapeが異なる if K.image_data_format() == 'channels_first': x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) # theano x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) # tensorflow x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 print('x_train shape:', x_train.shape) print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # convert class vectors to binary class matrices y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), # 32:出力を与える activation='relu', input_shape=input_shape)) # input_shape = x_train.shape[1:]としてもよい。最初のみ入力の値(img_rows, img_cols, 1)が必要。 model.add(Conv2D(64, (3, 3), activation='relu')) # 畳み込み。32:出力だけ与える model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) # 全結合相。2:出力だけ与える model.add(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) # 活性化関数 model.compile(loss=keras.losses.categorical_crossentropy, # 損失関数 optimizer=keras.optimizers.Adadelta(), # 最適化 metrics=['accuracy']) model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) # 学習 score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) model.save('./model.hdf5')
参考: keras/mnist_cnn.py at master · fchollet/keras · GitHub
予測するサンプル * 写真を一枚指定しそのクラスを出力
# coding: UTF-8 from __future__ import print_function import keras from keras.models import load_model from keras.preprocessing import image import numpy as np import sys model = load_model('model.hdf5') if len(sys.argv) != 2: print("usage: python [image file]") sys.exit(1) filename = sys.argv[1] img = image.load_img(filename, target_size=(32, 32)) x = image.img_to_array(img) #x = x / 255.0 #この操作を行うと正しく予測されない(TBD) # rows, cols, channels) -> (samples, rows, cols, channels) x = np.expand_dims(x, axis=0) pred = model.predict(x) print(pred)
参考: KerasでVGG16を使う - 人工知能に関する断創録
chainer
mnistをcnnで学習するサンプル
# -*- coding: utf-8 -* import numpy as np import matplotlib.pylab as plt from sklearn.datasets import fetch_mldata import chainer import chainer.links as L import chainer.functions as F from chainer import Chain, optimizers, Variable, serializers mnist = fetch_mldata('MNIST original', data_home='.') mnist.data = mnist.data.astype(np.float32) # image data 784*70000 [[0-255, 0-255, ...], [0-255, 0-255, ...], ... ] mnist.data /= 255 # to 0-1 mnist.target = mnist.target.astype(np.int32) # label data 70000 N = 60000 x_train, x_test = np.split(mnist.data, [N]) t_train, t_test = np.split(mnist.target, [N]) # to (n_sample, channel, height, width) x_train = x_train.reshape((len(x_train), 1, 28, 28)) x_test = x_test.reshape((len(x_test), 1, 28, 28)) class CNN(Chain): def __init__(self): super(CNN, self).__init__( conv1 = L.Convolution2D(1, 20, 5), # 入力:1 , 出力:20。両方記述。filter 5 conv2 = L.Convolution2D(20, 50, 5), # 入力:1 , 出力:20。両方記述。filter 5 l1 = L.Linear(800, 500), # ここの入力の計算は以下の参考HPを参照。 l2 = L.Linear(500, 500), l3 = L.Linear(500, 10, initialW=np.zeros((10, 500), dtype=np.float32)) ) def forward(self, x): h = F.max_pooling_2d(F.relu(self.conv1(x)), 2) h = F.max_pooling_2d(F.relu(self.conv2(h)), 2) h = F.relu(self.l1(h)) h = F.relu(self.l2(h)) h = self.l3(h) return h model = CNN() optimizer = optimizers.Adam() # 最適化関数 optimizer.setup(model) n_epoch = 5 batch_size = 1000 for epoch in range(n_epoch): sum_loss = 0 sum_accuracy = 0 perm = np.random.permutation(N) for i in range(0, N, batch_size): x = Variable(x_train[perm[i:i+batch_size]]) t = Variable(t_train[perm[i:i+batch_size]]) y = model.forward(x) model.zerograds() loss = F.softmax_cross_entropy(y, t) # 活性化関数と損失関数 acc = F.accuracy(y, t) loss.backward() optimizer.update() sum_loss += loss.data*batch_size sum_accuracy += acc.data*batch_size print("epoch: {}, mean loss: {}, mean accuracy: {}".format(epoch, sum_loss/N, sum_accuracy/N)) cnt = 0 for i in range(10000): x = Variable(np.array([x_test[i]], dtype=np.float32)) t = t_test[i] y = model.forward(x) y = np.argmax(y.data[0]) if t == y: cnt += 1 print("accuracy: {}".format(cnt/10000)) serializers.save_npz("model.npz", model)
予測するサンプル1(TBD)
import numpy as np %matplotlib inline import matplotlib.pylab as plt from sklearn.datasets import fetch_mldata import chainer import chainer.links as L import chainer.functions as F from chainer import Chain, optimizers, Variable, serializers mnist = fetch_mldata('MNIST original', data_home='.') mnist.data = mnist.data.astype(np.float32) # image data 784*70000 [[0-255, 0-255, ...], [0-255, 0-255, ...], ... ] mnist.data /= 255 # to 0-1 mnist.target = mnist.target.astype(np.int32) # label data 70000 N = 60000 x_train, x_test = np.split(mnist.data, [N]) t_train, t_test = np.split(mnist.target, [N]) # to (n_sample, channel, height, width) x_train = x_train.reshape((len(x_train), 1, 28, 28)) x_test = x_test.reshape((len(x_test), 1, 28, 28)) class CNN(Chain): def __init__(self): super(CNN, self).__init__( conv1 = L.Convolution2D(1, 20, 5), # 入力:1 , 出力:20。両方記述。filter 5 conv2 = L.Convolution2D(20, 50, 5), # 入力:1 , 出力:20。両方記述。filter 5 l1 = L.Linear(800, 500), # ここの入力の計算は以下の参考HPを参照。 l2 = L.Linear(500, 500), l3 = L.Linear(500, 10, initialW=np.zeros((10, 500), dtype=np.float32)) ) def forward(self, x): h = F.max_pooling_2d(F.relu(self.conv1(x)), 2) h = F.max_pooling_2d(F.relu(self.conv2(h)), 2) h = F.relu(self.l1(h)) h = F.relu(self.l2(h)) h = self.l3(h) return h model = CNN() serializers.load_npz("model.npz", model) image_data = (TBD) x = Variable(np.array([image_data], dtype=np.float32)) y = model.forward(x) y = np.argmax(y.data[0])
予測するサンプル2 : 機械学習フレームワークchainerを使って1からコードをかいてみる(mnist編) - Qiita
def forwardではなくdef callにすると
class MLP(Chain): def __init__(self): super(MLP, self).__init__( l1=L.Linear(784, 100), l2=L.Linear(100, 100), l3=L.Linear(100, 10), ) def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) y = self.l3(h2) return y
以下のようにpredictorで予測することができる
def predict(model, x_data): x = Variable(x_data.astype(np.float32)) y = model.predictor(x) return np.argmax(y.data, axis = 1)
答え合わせ。モデルの保存
def predict(model, x_data): x = Variable(x_data.astype(np.float32)) y = model.predictor(x) return np.argmax(y.data, axis = 1)
予測サンプル3 : Chainer: ビギナー向けチュートリアル Vol.1 - Qiita
import numpy as np from chainer import serializers from chainer.cuda import to_gpu from chainer.cuda import to_cpu model = MLP() serializers.load_npz('mnist_result/model_epoch-10', model) model.to_gpu(gpu_id) %matplotlib inline import matplotlib.pyplot as plt x, t = test[0] plt.imshow(x.reshape(28, 28), cmap='gray') plt.show() print('label:', t) x = to_gpu(x[None, ...]) y = model(x) y = to_cpu(y.data) print('predicted_label:', y.argmax(axis=1)[0])
参考:
Chainerでニューラルネットワーク及び畳み込みニューラルネットワークを実装してみた – データ分析エンジニアが気まぐれに更新するブログ
https://github.com/nocotan/chainer-examples/blob/master/examples/mnist-cnn.py
Convolutional Neural Networkを実装する - Qiita
機械学習フレームワークchainerを使って1からコードをかいてみる(mnist編) - Qiita
Chainer: ビギナー向けチュートリアル Vol.1 - Qiita
わかりやすい ↓