プロクラシスト

今日の寄り道 明日の近道

DeepLearning系ライブラリ、Kerasがあまりにも便利だったので使い方メモ


スポンサーリンク

こんにちは、ほけきよです。

以前練習として、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 モジュール内
    • PReLU
    • LearkyReLU
    • 詳しくはこちら web
    • ReLUの活性化関数の違いを知りたい方は私のQiita記事へどうぞ

関数の違いは下図 f:id:imslotter:20170107153956p:plain

コード

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_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を参考に
  • 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)

こんなのが出てくる
f:id:imslotter:20170107113053p:plain

学習の様子を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)

こんな感じに

f:id:imslotter:20170107151009p:plain

正解率98%とかって半端ないですね。人間と同じかそれ以上の識別性能かも!

まとめ

実際にモデルを動かしてる部分って、たかだか十数行とかですものね。こりゃすごい! いろいろな実験がしやすそうだし、これからどんどん使っていきたいと思います。ではでは!

今日のポイントは
・Kerasを使うと、簡単にディープラーニングができる
・可視化も簡単にできるので、実験にはもってこい
・ただ、便利・簡単すぎるので、中身の仕組み知りたい人は一から書いてみるのもいいかも!

### 関連記事 活性化関数の効用について調べてみました!

www.procrasist.com

深層学習 Deep Learning (監修:人工知能学会)

深層学習 Deep Learning (監修:人工知能学会)

*1:日本語があると怒られる方は、ファイル先頭に#coding:utf-8をつけておきましょう。

*2:順を追ってimportしているので、そのまま使うとものすごく見にくいかもです。コピペした後は適当に体裁を整えてください

PROCRASIST