FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

TensorFlow+Kerasに入門(4. Keras2のConvolution2DとConv2Dの違い?)

f:id:msyksphinz:20180701195704p:plain

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の中身の実装を見てみる必要性があるか...