【最終更新 : 2017.12.17】
※以前書いた記事がObsoleteになったため、2.xできちんと動くように書き直しました。
データ分析ガチ勉強アドベントカレンダー 17日目。
16日目に、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のラッパーで、簡単にディープ系の実験環境を整えられるようになっている。 実際に使ってみましたが、かなり直感的にネットワークを構成することが出来る
使ってみる
インストール
前に記事でも少し書いた。
pip install tensorflow pip install keras
で入ると思います。その他のライブラリ(opencvとか)は必要に応じて入れてください。
データを用意
とりあえずMNIST(デフォルトでmnistデータセットは利用可能)
from keras.datasets import hogehoge
でhogehogeのデータセットを読み込める。以下は読み込めるデータセット一覧
データセット | 内容 | trainデータ数 | testデータ数 |
---|---|---|---|
mnist |
28×28の手書き数字(白黒)を10個に分類 | 60000 | 10000 |
cifar10 |
32×32のカラー画像を10に分類 | 50000 | 10000 |
cifar100 |
32×32のカラー画像を100に分類 | 50000 | 10000 |
imdb |
25000の映画のレビューのデータセット、ラベルは肯定否定の2種 | 25000 | 25000 |
reuters |
11228個のニュースデータセットを46トピックに分類 | 8972 | 2246 |
fashion_mnist |
28×28の白黒画像を10種類のカテゴリに分類 | 60000 | 10000 |
求めたいものがあれば各々で利用すれば良い。データの渡し方の参考にこれらのデータセットの型を知っておくのがいいかも。
コード
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次元, 活性化関数-Selu
- 二層目:IN-default(多分64次元) OUT-10次元 活性化関数-SoftMax関数
入力のイメージは下図。MNISTは28×28の図だが、784次元の1次元ベクトルに変換してから入力している
- デフォである活性化関数
softplus
softsign
relu
tanh
sigmoid
hard_sigmoid
linear
elu
(Keras2.xより追加)selu
(Keras2.xより追加) 参考:Self-Normalizing Neural Networks
- より高度な活性化関数 :
keras.layers.advanced_activations
モジュール内PReLU
LearkyReLU
- 詳しくはこちら advanced_activations
【ReLU, PReLU, シグモイド etc...】ニューラルネットでよく使う活性化関数の効果をKerasで調べてみた - プロクラシスト
関数の違いは下図
コード
from keras.models import Sequential from keras.layers import Dense model = Sequential() model.add(Dense( activation="selu", units=64,input_dim=784)) model.add(Dense(activation="softmax", units=10))
学習プロセス
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 |
スパースラベルを取る |
kullback_leibler_divergence , kld |
確率を分布とみなした時の差 |
poisson |
予測-正解*log(予測) の平均 |
cosine_proximity |
予測と正解間のコサイン近似の負の平均 |
詳しい実装例はこちら GitHub
optimizer : 最適化
デフォで用意されている関数
- SGD
- RMSprop(デフォルトパラメータ推奨)
- Adagrad(デフォルトパラメータ推奨)
- Adadelta(デフォルトパラメータ推奨)
- Adam(デフォルトは提案論文通り)
- Adamax Adamの拡張(無限ノルム)
- Nadam Adam+RMSprop with momentumらしい
- TFOptimizer よくわかんない
指標の参考には以前書いたこちらの記事もどうぞ
コード
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個ずつに分けて、重みを更新するepochs
: 学習の繰り返し。60000個を何回学習するかvalidation_split
: 学習データの何パーセントをvalidation用データにするか(各エポックのテスト。validationの説明はこの記事を参考にどうぞ : 【Day-10】Cross 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, epochs=20, validation_split=0.2, batch_size=32, callbacks=[check])
モデルの評価
model.evaluate()
という関数で、テストデータを用いたモデルの評価が可能。lossとaccuracyを見ている
コード
loss, accuracy = model.evaluate(X_test, y_test) print("\nloss:{} accuracy:{}".format(loss, accuracy))
モデルの可視化
可視化(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 1.xからKeras 2.xの変更点
詳しくはこちらの公式記事を参考
Layerを作る際に、活性化関数も一緒に入れるようになった
from keras.layers import Dense, Activation model = Sequential() model.add(Dense(output_dim=64, input_dim=784)) model.add(Activation("relu"))
出力
UserWarning: Update your `Dense` call to the Keras 2 API: `Dense(input_dim=784, units=64)
変更後
model = Sequential() model.add(Dense( activation="relu", units=64,input_dim=784))
nb_epoch -> epochs
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])
出力
UserWarning: The `nb_epoch` argument in `fit` has been renamed `epochs`. warnings.warn('The `nb_epoch` argument in `fit` '
変更後
from keras.callbacks import ModelCheckpoint check = ModelCheckpoint("model.hdf5") history = model.fit(X_train, y_train, epochs=20, validation_split=0.2, batch_size=32, callbacks=[check])
show_accuracyの廃止 : defalutでaccuracyが出力されるようになった。
model.evaluate(X_test, y_test, show_accuracy=True)
出力
TypeError: evaluate() got an unexpected keyword argument 'show_accuracy'
変更後
model.evaluate(X_test, y_test)
まとめ
今日のポイントは
・Kerasを使うと、簡単にディープラーニングができる
・可視化も簡単にできるので、実験にはもってこい
・ただ、便利・簡単すぎるので、中身の仕組み知りたい人は一から書いてみるのもいいかも!
実際にモデルを動かしてる部分って、たかだか十数行とかですものね。すごい。 いろいろな実験がしやすそうだし、これからどんどん使っていきたい。
なお、Kerasを書籍で勉強したい方はこちらがオススメです。特にRNNに関しては丁寧に書かれているので!
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~
- 作者: 巣籠悠輔
- 出版社/メーカー: マイナビ出版
- 発売日: 2017/05/30
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
明日はKerasを用いたRNN実装にチャレンジしてみる(予定)です!お楽しみに!