こんにちは、ほけきよです。
以前練習として、1からニューラルネットをプログラムで書いたことがあります。 それはそれでデータの流れだとか、活性化関数の働きだとか得るものは多かったのですが、 今回Kerasと言うものを使ってみて、何て素晴らしいんだと感動してしまいました!
今まで苦労して数十行書いていたものが、わずか3行で書ける! 正直、スクラッチで書く意味って、理解にはいいけど研究には必要あんまないんですよね。車輪の再発明になるし。 と言うわけで、使えるものはどんどん使っていこうスタンスで、今回はKerasの紹介です
Tutorial+気になった引数を掘り下げて補足のような感じで書いています。 ちなみに、各部のコード以下をつなぎ合わせるとmnistの分類器が動くようになっているはずです。 *1 *2
Kerasとは?
Keras is a high-level neural networks library, written in Python and capable of running on top of either TensorFlow or Theano. It was developed with a focus on enabling fast experimentation. Being able to go from idea to result with the least possible delay is key to doing good research. (Documentationより)
TensorFlowやTheanoのラッパーです。簡単にディープ系の実験環境を整えられるようになっています。 実際に使ってみましたが、かなり直感的にネットワークを構成することが出来ます!
使ってみる
インストール
前に記事でも少し書きました www.procrasist.com
pip install tensorflow pip install keras
で入ると思います。その他のライブラリ(opencvとか)は必要に応じて入れてください。
データを用意
とりあえずMNIST(デフォルトでmnistデータセットは利用可能)
- デフォで使えるもの
from keras.datasets import mnist
- 28×28の手書き数字(白黒)を10個に分類
- train 60000, test 10000
from keras.datasets import cifar10
- 32×32のカラー画像を10に分類
- train 50000, test 10000
from keras.datasets import mnist
- 32×32のカラー画像を100種に分類
- train 50000, test 10000
from keras.datasets import imdb
- 25000の映画のレビューのデータセット、ラベルは肯定否定の2種
from keras.datasets import reuters
- 11228個のニュースデータセットを46トピックに分類
求めたいものがあれば各々で利用すれば良い。データの渡し方の参考にこれらのデータセットの型を知っておくのがいいかも。
コード
from keras.datasets import mnist from keras.utils import np_utils (X_train, y_train),(X_test,y_test) = mnist.load_data() X_train = X_train.reshape(60000,784).astype('float32') X_test = X_test.reshape(10000,784).astype('float32') #[0,255]の値を[0,1]に正規化 X_train /= 255.0 X_test /= 255.0 # 1 of Kのベクトルに変換 y_train = np_utils.to_categorical(y_train, 10) y_test = np_utils.to_categorical(y_test, 10)
modelを作る
model = Sequential()
で初期化
model.add()
で層を積んでいく
- 一層目:IN-784次元, OUT-64次元, 活性化関数-ReLU
二層目:IN-default(多分64次元) OUT-10次元 活性化関数-SoftMax関数
デフォである活性化関数
softplus
softsign
relu
tanh
sigmoid
hard_sigmoid
linear
- より高度な活性化関数 :
keras.layers.advanced_activations
モジュール内
関数の違いは下図
コード
from keras.models import Sequential from keras.layers import Dense, Activation model = Sequential() model.add(Dense(output_dim=64, input_dim=784)) model.add(Activation("relu")) model.add(Dense(output_dim=10)) model.add(Activation("softmax"))
学習プロセス
model.compile
- loss : 損失関数
- デフォで用意されている関数
mean_squared_error
,mse
: 二乗誤差mean_absolute_error
,mae
: 絶対誤差mean_absolute_percentage_error
,make
: 正解とのズレ(絶対値)の割合mean_squared_logarithmic_error
,msle
: 正解とのズレ(二乗誤差)の割合squared_hinge
: マイナスのところは0, プラスは二乗誤差hinge
: マイナスのところは0, プラスは絶対値binary_crossentropy
: loglossとしても知られているcategorical_crossentropy
: マルチクラスloglossとして知られている(ラベルがバイナリ配列であることが必要)sparse_categorical_crossentropy
: スパースラベルを取る categorical_crossentropykullback_leibler_divergence
,kld
: 確率を分布とみなした時の差poisson
:予測-正解*log(予測)
の平均cosine_proximity
: 予測と正解間のコサイン近似の負の平均
- 詳しい実装例はこちら GitHub
- デフォで用意されている関数
- optimizer : 最適化関数
- metrics : 指標(評価時とかに表示するやつ)
コード
from keras.optimizers import SGD # optimizer = "sgd"でも、簡単に最適化関数の設定ができる #(その場合パラメータはデフォルト値) model.compile(loss="categorical_crossentropy", optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True), metrics=["accuracy"])
モデルの学習
学習
model.fit()
でモデルを学習。引数は以下
- X_train : データ(MNISTだと、どこに何個データが入っているか)
- y_train : ラベル(1-10)
- batch_size : ミニバッチにデータを分けるこの場合60000個ある学習データを、32個ずつに分けて、重みを更新する
- nb_epoch : 学習の繰り返し。60000個を何回学習するか
- validation_split : 学習データの何パーセントをvalidation用データにするか(各エポックのテスト。なくても良い)
また、学習の様子も保存されている
model.fit
内の変数を見てみるとこんな感じ
print(history.__dict__) >>> {'model': <keras.models.Sequential object at 0x110c78510>, 'params': {'verbose': 1, 'nb_epoch': 3, 'batch_size': 32, 'metrics': ['loss', 'acc', 'val_loss', 'val_acc'], 'nb_sample': 48000, 'do_validation': True}, 'epoch': [0, 1, 2], 'history': {'acc': [0.89862500000000001, 0.94735416666666672, 0.96150000000000002], 'loss': [0.35020409799863894, 0.18034435256198048, 0.132605804043822], 'val_acc': [0.94125000000000003, 0.95816666666666672, 0.96499999999999997], 'val_loss': [0.20651897403846184, 0.14732480475058157, 0.1263637450747192]}}
コールバック関数
keras.callbacks
内の関数を使ってモデルの保存ができる。
check = ModelCheckpoint("modelname.hdf5")
で、学習済みモデルの重みを保存する- その場合、
model.fit(hogehoge,callbacks=[check])
としてやる
- その場合、
- tensorboardなどとも連携可能
- 自分でcallbackしたい関数を作ることも可能
- 詳しくはドキュメント参照
コード
from keras.callbacks import ModelCheckpoint check = ModelCheckpoint("model.hdf5") history = model.fit(X_train, y_train, nb_epoch=20, validation_split=0.2, batch_size=32, callbacks=[check])
モデルの評価
model.evaluate()
という関数で、テストデータを用いたモデルの評価が可能。ここではlossとaccuracyを見ている
コード
loss_and_metrics = model.evaluate(X_test,y_test,show_accuracy=True) print("\nloss:{} accuracy:{}".format(loss_and_metrics[0],loss_and_metrics[1]))
モデルの可視化
可視化(tensorflow)
モデルの可視化
ニューラルネットのネットワークを可視化するとき
keras.utils.visualize_util
手順(Mac, Homebrew有り)
$brew install graphviz
$pip install pydot
とすれば使える
- to_file : 出力の画像ファイルの名前
- show_shapes : グラフ中に出力形状を書くか(デフォはFalse)
- show_layer_names : レイヤー名を書くか(デフォはTrue)
コード
from keras.utils.visualize_util import plot plot(model, to_file="model.png", show_shapes=True, show_layer_names=True)
こんなのが出てくる
学習の様子をplot
matplotlibで可視化
コード
import matplotlib.pyplot as plt def plot_history(history): # 精度の履歴をプロット plt.plot(history.history['acc'],"o-",label="accuracy") plt.plot(history.history['val_acc'],"o-",label="val_acc") plt.title('model accuracy') plt.xlabel('epoch') plt.ylabel('accuracy') plt.legend(loc="lower right") plt.show() # 損失の履歴をプロット plt.plot(history.history['loss'],"o-",label="loss",) plt.plot(history.history['val_loss'],"o-",label="val_loss") plt.title('model loss') plt.xlabel('epoch') plt.ylabel('loss') plt.legend(loc='lower right') plt.show() # modelに学習させた時の変化の様子をplot plot_history(history)
こんな感じに
正解率98%とかって半端ないですね。人間と同じかそれ以上の識別性能かも!
まとめ
実際にモデルを動かしてる部分って、たかだか十数行とかですものね。こりゃすごい! いろいろな実験がしやすそうだし、これからどんどん使っていきたいと思います。ではでは!
今日のポイントは
・Kerasを使うと、簡単にディープラーニングができる
・可視化も簡単にできるので、実験にはもってこい
・ただ、便利・簡単すぎるので、中身の仕組み知りたい人は一から書いてみるのもいいかも!