LoginSignup
23
22

More than 5 years have passed since last update.

Keras as wrapper of Theano & TensorFlow

Posted at

Kerasは,元々Deep LearningフレームワークTheanoと組み合わせて使うライブラリであったが,最近のアップデートでGoogle製のTensorFlowもバックエンドとして使えるようになっている.

Keras: Deep Learning library for Theano and TensorFlow

You have just found Keras.

Keras is a minimalist, highly modular neural networks library, written in Python and capable of running either 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.

Theanoは,テンソル演算の基本部分を中心にサポートしていることから,Theanoをベースに,より抽象化を図ったライブラリがいくつかあるのはリーズナブルであるのに対し,より広範囲な機能をサポートするTensorFlowをKerasがサポートしたことについては,個人的に少し意外だった.以下,簡単なコードを作成しながら状況を調べてみた.

(プログラム環境は,Linux Ubuntu 14.04, Python 2.7.11, Theano ver.0.7.0, TensorFlow ver.0.6.0, Keras ver.0.3.0 になります.)

インストールから'mnist_mlp.py'を動かすまで

Theano, ThensorFlowは,前にGPUを使える環境にインストールしてある.今回は,"Keras"を追加した.

> git clone https://github.com/fchollet/keras.git
> cd keras
> python setup.py install

examplesのディレクトリをのぞくと代表的な問題についてサンプルコードが用意されている.

> ls examples
addition_rnn.py  imdb_bidirectional_lstm.py  kaggle_otto_nn.py        mnist_mlp.py
babi_memnn.py    imdb_cnn.py                 lstm_text_generation.py  mnist_transfer_cnn.py
babi_rnn.py      imdb_cnn_lstm.py            mnist_cnn.py             reuters_mlp.py
cifar10_cnn.py   imdb_lstm.py                mnist_irnn.py

この中で'mnist_mlp.py'がMNIST(手書き数字の分類問題)の例題であったので,これを実行したところ,最初,エラーが発生した.

Traceback (most recent call last):
  File "mnist_mlp.py", line 50, in <module>
    model.compile(loss='categorical_crossentropy', optimizer=rms)
...
(中略)
...
  File "build/bdist.linux-x86_64/egg/keras/activations.py", line 25, in relu
  File "build/bdist.linux-x86_64/egg/keras/backend/theano_backend.py", line 463, in relu
AttributeError: 'module' object has no attribute 'relu'

これは,'minist_mlp.py'の中で活性化関数として 'relu' を指定していたが,もともとAnacondaでインストールしていたTheano version ver.0.7.0ではサポートされていないものであったためである.(Thenoのドキュメント上は,ver.0.7.1から'relu'をサポートと書かれている.)但し,GitHubに置かれているTheanoでは(ver.0.7.0ながら)'relu'があるとのことなので,これにupgadeしたところ上記エラーは解消した.

(前略)
...
Epoch 20/20
1s - loss: 0.0092 - acc: 0.9974 - val_loss: 0.0555 - val_acc: 0.9842
Test score: 0.0554862711126
Test accuracy: 0.9842

Testの分類精度は,約98.4 %となっている.

バックエンドを'Theano'から’TensorFlow'に変更

バンクエンドを変更するにあたり,方法は2つある.
1. ホームディレクトリ下にある環境ファイル("$HOME/.keras/keras.json")の変更
"keras.json"は,{"epsilon": 1e-07, "floatx": "float32", "backend": "theano"} の一行のファイルなので,一番最後の項,"theano"を"thensorfolw"に変更してあげればよい.
2. 環境変数 "KERAS_BACKEND" を変更.
環境変数が定義されていなければ,上記keras.jsonの値が設定される.環境変数が設定されればそちらの設定が優先される.

export KERAS_BACKEND=tensorflow

これだけで,同じKeras用コードがTensorFlowライブラリを使って実行されるようになった.(とっても簡単!)2つの方法の比較では,環境変数設定の方が手軽な印象である.(もちろん,theonoに戻すには上記環境変数をunsetするか,'theano'に設定すればよい.)

因みにこちらにパフォーマンスに関するベンチマークテストの結果が掲載されているので引用する.
https://github.com/fchollet/keras/wiki/Keras,-now-running-on-TensorFlow

Task TensorFlow Theano
mnist_mlp.py: compilation (s) 0.6 5.9
mnist_mlp.py: runtime/epoch (s) 7.5 6.3
imdb_lstm.py: compilation (s) 39.3 38.3
imdb_lstm.py: runtime/epoch (s) 283 123
mnist_cnn.py: compilation (s) 0.8 11.4
mnist_cnn.py: runtime/epoch (s) 190 3230

同じ問題に対し同じコードを走らせても,バンクエンドにより結構,所要時間が変わることがわかる.(CPU演算によるものだそうです.)

自分のコードで試してみる

最近投稿の記事で扱った,TensorFlow版/Theano版のWine分類MLPコードをKeras版にしてみた.Tutorial用として書いた短いコードだが,Keras版ではさらにコンパクトなコードとなった.
(元のコードは,TensorFlow版, Theano版 を参照ください.)

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
np.random.seed(1337)  # for reproducibility

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.regularizers import l2
from keras.optimizers import SGD, Adagrad

from input_winedata import load_data

if __name__ == '__main__':
    WineData = '../../Data/Wine/wine.data'
    train_x, train_y, test_x, test_y = load_data(WineData)
    print(train_x.shape[0], 'train samples')
    print(test_x.shape[0], 'test samples')

    model = Sequential()
    model.add(Dense(20, input_shape=(13,), W_regularizer=l2(0.001)))
    model.add(Activation('sigmoid'))
    model.add(Dropout(0.05))
    model.add(Dense(20, W_regularizer=l2(0.001)))
    model.add(Activation('sigmoid'))
    model.add(Dropout(0.05))
    model.add(Dense(3, W_regularizer=l2(0.001)))
    model.add(Activation('softmax'))

    adagrad = Adagrad(lr=0.01, epsilon=1e-08)
    model.compile(loss='categorical_crossentropy', optimizer=adagrad)

    batch_size = 16
    nb_epoch = 1000

    print('Train...')
    model.fit(train_x, train_y,
          batch_size=batch_size, nb_epoch=nb_epoch,
          show_accuracy=False, verbose=2,
          validation_data=(test_x, test_y))
    score = model.evaluate(test_x, test_y,
                       show_accuracy=True, verbose=0)
    print('Test score:', score[0])
    print('Test accuracy:', score[1])

以下,詳細を確認していく.

初めにデータを入力した後,行っているのが,ネットワークモデル(MLP)の定義である.Theano,TensorFlowでも隠れ層のレイヤーClass,出力層レイヤーClassを定義しておけば,メインのMLP定義部分はかなり簡潔にまとめることができるが,Kerasでは自分でClassを作成することなく,以下のコードでネットワークが定義できてしまう.

    model = Sequential()
    model.add(Dense(20, input_shape=(13,), W_regularizer=l2(0.001)))
    model.add(Activation('sigmoid'))
    model.add(Dropout(0.05))
    model.add(Dense(20, W_regularizer=l2(0.001)))
    model.add(Activation('sigmoid'))
    model.add(Dropout(0.05))
    model.add(Dense(3, W_regularizer=l2(0.001)))
    model.add(Activation('softmax'))

最初の model=Sequential() で順伝搬型のネットワークを定義することを選択する.その後,入力側から(隠れ層1の定義),(隠れ層2の定義),(出力層の定義)と順番に行っている.活性化(Activation)関数の選択,正則化(Rezularizer)の指定,Dropoutの指定等,とても明確に書くことができる.

因みに順伝搬ネットワークモデル model=Sequential() は,CNN(Convolutional Neural Network)まで対応可能で,より複雑な構造をもつRNN(Recurrent Neural Net)等に対してKerasでは,model=Graph() という宣言から始めるGraphモデルで構造を定義することができる.(こちらは今後調査したいと思います.)

MLPコードの後半では,オプティマイザーを指定して,model.fit() のメソッドを呼ぶ.

    adagrad = Adagrad(lr=0.01, epsilon=1e-08)
    model.compile(loss='categorical_crossentropy', optimizer=adagrad)

    batch_size = 16
    nb_epoch = 1000

    print('Train...')
    model.fit(train_x, train_y,
          batch_size=batch_size, nb_epoch=nb_epoch,
          show_accuracy=False, verbose=2,
          validation_data=(test_x, test_y))

以上で,学習までプログラムは実行される.

使ってみての感想

何よりも短いコード,しかも"YAML"や"Lua"といった別スクリプトなしでネットワークを定義して計算を実行できるのはすばらしい.バックエンドが"Theano"と”TensorFlow"の2種類になったことに対しては,今時点で面白い使い方は頭に浮かばないが,ユーザに対する間口が広がることに間違いはない.

またよく言われることだが,抽象度が上がることで柔軟性が失われるトレードオフは,当然 "Keras" にも当てはまる.しかし,プロトタイピングで「自分のモデルをすぐに試してみたい」とか,「ハイパーパラメータの数値的な実験を繰り返し行いたい」という目的に対しては非常に有用なライブラリであると思われる.

(一気にKerasサポーターになってしまいました.)

参考文献 (web site)

23
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
22