FPGAの部屋のmarseeさんの記事を見て、TensorFlow+Kerasに入門してみた。 というかmarseeさんの記事で掲載されているソースコードをほとんどCopy & Pasteして実行してみているだけだが...
TensorFlow+KerasでCifar10を学習するサンプルプログラムを実行して、そこから得られたモデルを使ってKeras2cppでモデルの変換を行ってみた。
最終的な目標は、Keras2cppを使ってC++のコードを出力し、それをネイティブC++環境で実行することだ。
前回のcifar10のサンプルコードはKeras2のコードで、"Conv2D"と"Convolutional2D"の記述が異なる。 あまりメンテナンスのされていないkeras2cppは"Convolutional2D"しか読み取れないらしく、仕方がないので以下のようにkeras2cppのコードを修正して動作させてみたのだが、自宅の環境ではメモリ不足で途中終了。 急遽メモリの多いマシンを用意して実行してみたのだが、それでもなぜか終了せずに途中で止まってしまった。
keras2cpp/keras_model.cc
--- a/machine_learning/tensorflow/keras/keras_model/keras_model.cc +++ b/machine_learning/tensorflow/keras/keras_model/keras_model.cc @@ -420,6 +420,8 @@ void keras::KerasModel::load_weights(const string &input_fname) { Layer *l = 0L; if(layer_type == "Convolution2D") { l = new LayerConv2D(); + } else if(layer_type == "Conv2D") { + l = new LayerConv2D(); } else if(layer_type == "Activation") { l = new LayerActivation(); } else if(layer_type == "MaxPooling2D") { diff --git a/machine_learning/tensorflow/keras/machine-learning b/machine_learning/tensorflow/keras/machine-learning
これはやはり適当にConvolutional2DとConv2Dを変換したからなのかな?よく分からないので、万全を期すために全部Convolutional2Dに変換して実行してみたい。
そこで、Keras2のサンプルコードを以下のように書き換えて再度学習させた。これでまた再学習だ。3時間程度かかる...
keras/example/cifar10_cnn.py
diff --git a/examples/cifar10_cnn.py b/examples/cifar10_cnn.py index 1daed4ab..dbc28d3d 100644 --- a/examples/cifar10_cnn.py +++ b/examples/cifar10_cnn.py @@ -10,7 +10,8 @@ from keras.datasets import cifar10 from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten -from keras.layers import Conv2D, MaxPooling2D +# from keras.layers import Conv2D, MaxPooling2D +from keras.layers import Convolution2D, MaxPooling2D import os batch_size = 32 @@ -32,17 +33,17 @@ y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) model = Sequential() -model.add(Conv2D(32, (3, 3), padding='same', +model.add(Convolution2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:])) model.add(Activation('relu')) -model.add(Conv2D(32, (3, 3))) +model.add(Convolution2D(32, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) -model.add(Conv2D(64, (3, 3), padding='same')) +model.add(Convolution2D(64, (3, 3), padding='same')) model.add(Activation('relu')) -model.add(Conv2D(64, (3, 3))) +model.add(Convolution2D(64, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25))
結果のモデルを保存して、モデル情報と重みファイルを抽出したのだが、やはりConv2Dが使用されているぞ? Keras2をつかったからかしら。Keras2のConvolution2DとConv2Dって根本的にいっしょなのかなあ。
ちなみにコンパイル後の動作も変わらず、最後まで実行できなかった。 うーん、Kerasの中身の実装を見てみる必要性があるか...