ManningのMEAP(出版前の本のできた部分から読めるサービス)でTensorFlowとTheanoの両方に対応したラッパーツールkerasの作者Francois Chollet氏の「Deep Learning with Python」が発売されました。
1章は、Francois Chollet氏のDeep Learningへの思いの丈が詰まっており、2章からDeep Learningの紹介が始まります。
ここでは、2章の例題をSageのjupyterノートブックで試しながら、Deep Learningへの理解を深めたいと思います。
kerasにも例題を試すためにデータセットが容易されています。
MNISTは手書き数字の画像データセットで、70000の手書き数字データが収録されおり、ここでは、60000のトレーニング用データ(train_images, train_labels)と10000の検証用データ(test_images, test_labels)に分割しています。
from keras.datasets import mnist
Using TensorFlow backend.
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_imagesのshapeをみると、60000のデータは28x28の画像情報からなり、グレースケールを0〜255で表現しています。
print train_images.shape
# 画像データの例として5行目の値を表示
print train_images[0][5]
(60000, 28, 28) [ 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136 175 26 166 255 247 127 0 0 0 0]
ラベルには、0〜9の値がセットされています。
len(train_labels)
60000
train_labels
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
画像の例として5番目の数字を表示します。
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
digit = train_images[4]
plt.imshow(digit.reshape(28,28), cmap=plt.cm.binary)
plt.show()
いきなり、kerasを使った例題がでてきます。
ここでは、処理の詳細を理解する必要はなく、kerasでニューラルネットがまるでレゴのようにニューラルネットを積み重ねるだけで、ネットワークができることを示しています。
以下の例では、以下の様なnetworkを生成しています。
from keras.models import Sequential
from keras.layers import Dense
network = Sequential()
network.add(Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(Dense(10, activation='softmax'))
次にセットするのは、どのようにニューラルネットワークを学習させるかをcompileメソッドで指定します。
network.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
イメージデータは、reshapeメソッドを使って(60000, 28, 28)から(60000, 784)の2次元データに変換し、値も整数から0〜1の実数(float32)に変換します。
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255
ラベルも0〜9の数字から数字をインデックスとして、1とし、他は0となるone-hot形式に変換します。これには、kerasのユーティリティto_categoricalを使用します。
from keras.utils.np_utils import to_categorical
# 変換前のラベル
print train_labels[0]
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# 変換後のラベル(one-hot形式)
print train_labels[0]
5 [ 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
後は、fitメソッドでnetworkを学習させるだけです。全データに対して5回繰り返し(nb_epoch)、ミニバッチのサイズ(batch_size)を128としています。
network.fit(train_images, train_labels, nb_epoch=5, batch_size=128)
Epoch 1/5 60000/60000 [==============================] - 9s - loss: 0.2559 - acc: 0.9253 Epoch 2/5 60000/60000 [==============================] - 9s - loss: 0.1044 - acc: 0.9693 Epoch 3/5 60000/60000 [==============================] - 9s - loss: 0.0694 - acc: 0.9792 Epoch 4/5 60000/60000 [==============================] - 9s - loss: 0.0513 - acc: 0.9846 Epoch 5/5 60000/60000 [==============================] - 9s - loss: 0.0382 - acc: 0.9886
<keras.callbacks.History at 0x7f39a4766610>
検証用データで学習したモデル(network)を評価してみましょう。 evaluateメソッドで評価することができます。
検証結果の精度はなんと98%(0.98)と精度が高い結果となっているのですが、本文はこれをOverfitting(過学習)だと説明しています。
test_loss, test_acc = network.evaluate(test_images, test_labels)
9696/10000 [============================>.] - ETA: 0s
print('test_acc:', test_acc)
('test_acc:', 0.97889999999999999)