話題の記事

KerasではじめるDeepLearning

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、小澤です。

今回はKerasというDeepLearningのライブラリについて書かせていただきます。

Kerasとは

公式のドキュメントによると以下のようになっています。

Kerasは,Pythonで書かれた,TensorFlowまたはTheano上で実行可能な高水準のニューラルネットワークライブラリです. Kerasは,迅速な実験を可能にすることに重点を置いて開発されました. 可能な限り遅れなくアイデアから結果に進められることは,良い研究をする上で重要です.

Keras Documentationより

Kerasを利用するとDeepLearningの背後にある数学的な部分をスクラッチで実装しなくても、各層で利用するアルゴリズムとパラメータを指定するのみなど、比較的短いコードで目的のネットワークを表現することができます。

そのため、研究領域において非常に流れが早く企業などでも素早く最新の実装が取り入れらているという現状にあるDeepLearningの最新手法を素早く試すことが可能になります。

また、Kerasの特徴としてドキュメントが日本語化されていることもあげられ、日本人にとってはその点もありがたいのではないでしょうか。 そのため、今回は公式ドキュメントを読みながら様々なネットワークを実装できるようになるための基本的な部分を紹介していきたいと思います。

実際に触ってみる

では、実際にやってみましょう。

インストール

まずは、インストールを行います。 keras自体のインストールはpipで行えます。 実行環境はTesorFlowかTheanoか選択可能ですが、TensorFlowは依存ライブラリに含まれていないようなのでそちらも合わせてインストールしておきます。

pip install -U tensorflow
pip install -U keras

numpyなど、その他の依存ライブラリは合わせてインストールされます。 以下のようにimportできてればOKです。

$ python
>>> import keras
Using TensorFlow backend.
>>>

モデルの保存を行う際はHDF5が必要になるので、そちらも入れておくといいでしょう

pip install h5py

MLP

まずは基本的な機能を見ていくのもかねて、 中間層が1つのみで全結合のMLP(Multi Layer Perceptron)でMNISTを試してみましょう。

スクリプト

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils import np_utils

# Kerasに含まれるMNISTデータの取得
# 初回はダウンロードが発生するため時間がかかる
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# 配列の整形と、色の範囲を0-255 -> 0-1に変換
X_train = X_train.reshape(60000, 784) / 255
X_test = X_test.reshape(10000, 784) / 255

# 正解データを数値からダミー変数の形式に変換
# これは例えば0, 1, 2の3値の分類の正解ラベル5件のデータが以下のような配列になってるとして
#   [0, 1, 2, 1, 0]
# 以下のような形式に変換する
#   [[1, 0, 0],
#    [0, 1, 0],
#    [0, 0, 1],
#    [0, 1, 0],
#    [1, 0, 0]]
# 列方向が0, 1, 2、行方向が各データに対応し、元のデータで正解となる部分が1、それ以外が0となるように展開してる
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# ネットワークの定義
# 各層や活性関数に該当するレイヤを順に入れていく
# 作成したあとにmodel.add()で追加することも可能
model = Sequential([
        Dense(512, input_shape=(784,)),
        Activation('sigmoid'),
        Dense(10),
        Activation('softmax')
    ])
# 損失関数、 最適化アルゴリズムなどを設定しモデルのコンパイルを行う
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])

# 学習処理の実行
model.fit(X_train, y_train, batch_size=200, verbose=1, epochs=20, validation_split=0.1)

# 予測
score = model.evaluate(X_test, y_test, verbose=1)
print('test accuracy : ', score[1])

非常に簡単に実装できるのがわかるかと思います。

このモデルは簡単のため、最低限のネットワークとなっているため、結果はあまり良くありません(収束もしていません)が、 最後のprintの結果は以下のようになっています。

test accuracy :  0.8905

また、実際に上記のコードを試して頂い方はお気づきかと思いますが、Kerasでは実行中の進捗状況を以下のように随時表示してくれます。 この進捗は、学習時の引数verboseを0にすることで表示させないことも可能です。

Train on 54000 samples, validate on 6000 samples
Epoch 1/20
54000/54000 [==============================] - 3s - loss: 1.0019 - acc: 0.8119 - val_loss: 0.8717 - val_acc: 0.8598
Epoch 2/20
54000/54000 [==============================] - 3s - loss: 0.8861 - acc: 0.8243 - val_loss: 0.7685 - val_acc: 0.8712
Epoch 3/20
54000/54000 [==============================] - 3s - loss: 0.8004 - acc: 0.8339 - val_loss: 0.6917 - val_acc: 0.8750
Epoch 4/20
54000/54000 [==============================] - 3s - loss: 0.7355 - acc: 0.8414 - val_loss: 0.6321 - val_acc: 0.8815
Epoch 5/20
54000/54000 [==============================] - 3s - loss: 0.6847 - acc: 0.8473 - val_loss: 0.5861 - val_acc: 0.8843
...
...

学習状況の可視化

fit関数の戻り値にはこの進捗で表示されている値を保持しているため、matplotlibなどを利用することで可視化することも可能です。

import matplotlib.pyplot as plt

loss = hist.history['loss']
val_loss = hist.history['val_loss']

# lossのグラフ
plt.plot(range(20), loss, marker='.', label='loss')
plt.plot(range(20), val_loss, marker='.', label='val_loss')
plt.legend(loc='best', fontsize=10)
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

acc = hist.history['acc']
val_acc = hist.history['val_acc']

# accuracyのグラフ
plt.plot(range(20), acc, marker='.', label='acc')
plt.plot(range(20), val_acc, marker='.', label='val_acc')
plt.legend(loc='best', fontsize=10)
plt.grid()
plt.xlabel('epoch')
plt.ylabel('acc')
plt.show()

loss

acc

ネットワークの可視化

Kerasは作成したネットワークを可視化する機能も有しています。 こちらはGraphvizを利用しているので、インストールが必要になります。

GraphvizのインストールはMacであればhomebrewを利用するのが楽です。

brew install graphviz
pip install pydot

以下のスクリプトでネットワークを可視化した画像が出力されます。

from keras.utils import plot_model
plot_model(model, to_file='model.png')

また、Jupyter notebookを利用していてインラインで表示させたい場合は以下のようにします。

from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot

SVG(model_to_dot(model).create(prog='dot', format='svg'))

画像は以下のようになります。

model

コールバック関数

Kerasには学習時に利用できるコールバック関数というものがあります。 コールバック関数を利用すると学習時にエポックごとなど適宜その関数が呼ばれることになるため、学習状況の監視やチェックポイントの作成などに役立ちます。

例えば、早期終了を行うためのコールバック関数の設定は以下のようになります。

from keras.callbacks import EarlyStopping

...
...

early_stopping = EarlyStopping(monitor='val_loss')
model.fit(X_train, y_train, batch_size=200, verbose=1, epochs=20, validation_split=0.1, callbacks=[early_stopping])

exampleを見てみる

KerasのGithubにはexampleが含まれています。 MLP以外のネットワークを作れるようになるために、いくつか見てみましょう。

mnist_cnn.py

最初にmnist_cnn.pyを見てみましょう。

まずCNNで利用するためにデータのreshapeを行いますが、こちらはMLPの時と異なっています。

# CNNの入力は特徴を1次元に並べるのではなく、縦x横で渡す
# 色(channel)情報と合わせた時の順番が設定によって異なるので、設定に合わせて分岐している
if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    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)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

学習部分は以下のようになっています。

# ネットワークの作成方法はMLPの時と同じ
model = Sequential()

# レイヤの指定時に全結合(Dense)ではなくConvolutionを指定している。
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))

# Pooling層の設定やドロップアウトもここで指定できる
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

LSTM

別な例として、LSTMも見ていこうかと思ったのですが、こちらもembeddingやLSTMのレイヤが出てくる以外は同じとなります。 手前味噌ながら、だいたいこんなやり方で可能という例を私が以前行ったものを紹介してLSTMの話は終わりにしたいと思います。

たいしたことはしていないので、ここまでの内容を踏まえるとLSTMの使い方もご理解頂けるかと思います。

終わりに

今回は、Deep LearningのライブラリであるKerasの基本的な部分の解説とexampleなどを通して実際のネットワークをくむ方法を解説しました。 機能紹介として網羅性があるわけでばありませんが、Kerasは非常に容易に扱えるようになっているため、ポイントさえ押さえておけばあとはドキュメントを見ながら使いこなせるかと思います。

実際にやってみるとうまくいい感じのモデルが作れなかったり、数学的な理論面も知っていないと困ることも多いかと思いますが、 まずはとにかく動かして見ながらDeep Learningの理解を深めていきたいという人にも便利なライブラリかと思います。