【最終更新 : 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のラッパーで、簡単にディープ系の実験環境を整えられるようになっている。
実際に使ってみましたが、かなり直感的にネットワークを構成することが出来る
使ってみる
インストール
前に記事でも少し書いた。
www.procrasist.com
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')
X_train /= 255.0
X_test /= 255.0
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次元ベクトルに変換してから入力している
- デフォである活性化関数
- より高度な活性化関数 :
keras.layers.advanced_activations
モジュール内
関数の違いは下図
コード
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 よくわかんない
- 引数の詳細な設計も可能(こちらを参考 web)
- 新しい最適化関数を作りたいなら GitHubを参考に
指標の参考には以前書いたこちらの記事もどうぞ
コード
from keras.optimizers import 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()
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に関しては丁寧に書かれているので!
明日はKerasを用いたRNN実装にチャレンジしてみる(予定)です!お楽しみに!