前回、Neural Network Consoleで設計したモデルを、keras/tensorflowに書きかえて実行してみました。
そうすると。
同じモデル・同じデータ・同じバッチサイズ・同じエポック数・・等々の条件が同じとき、Neural Network Consoleとkeras/tensorflowで精度が違ったりするのだろうか?
違うとしたら、どちらが上なのだろうか?
などという疑問がわいてきました。
じゃあ、試してみよう・・今回はそういう話です。
前回のKerasのソースを変更する
前回、kerasに書き換えたのは、Neural Network Consoleの「LeNet」サンプルです。
Neural Network Consoleでは、データにMNISTを使ってます。
だから、前回Kerasに書き換えたソースのモデル部分は変更せず、MNISTを使うようにすれば良いわけです。
早速やってみます。
KerasでMNISTを利用する
MNISTはKerasに付属しています。
だから、それを使えばよいだけです。
その部分だけのソースはこんな感じ。
num_classes = 10 epochs = 12 img_rows = 28 img_cols = 28 # the data, split between train and test sets (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 y_train = tf.keras.utils.to_categorical(y_train, num_classes) y_test = tf.keras.utils.to_categorical(y_test, num_classes)
意外に長いですが、まあ、コピペでいける定型処理みたいなもんなので。
ちょっとだけ補足します。
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
これは、何故必要かというと、load_data()しただけだと、(60000,28,28)みたいに、チャンネルの ないshapeになってます。
でも、LeNet(CNN)のinput_shapeは、(28,28,1)のように、チャンネル数(1だとグレースケール・3だとRGBカラー・・とか)が後ろに必要("channels_last"といいます)なのです。
なので、上記のようにしてShapeの変更が必要というわけです。
前回のソースを手直しした全体と学習評価の実行
データの部分だけ置き換えて、実行するKerasのソース全体はこうです。
import tensorflow as tf num_classes = 10 epochs = 12 img_rows = 28 img_cols = 28 # the data, split between train and test sets (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 y_train = tf.keras.utils.to_categorical(y_train, num_classes) y_test = tf.keras.utils.to_categorical(y_test, num_classes) model = tf.keras.models.Sequential() model.add(tf.keras.layers.Conv2D(16, kernel_size=(7, 7), activation='relu', input_shape=(img_rows, img_cols, 1))) model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2))) model.add(tf.keras.layers.Conv2D(30, kernel_size=(3, 3))) model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2))) model.add(tf.keras.layers.Activation('tanh')) model.add(tf.keras.layers.Flatten()) model.add(tf.keras.layers.Dense(150, activation='relu')) model.add(tf.keras.layers.Dense(10, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer=tf.keras.optimizers.Adam(), metrics=['accuracy']) model.fit(x_train, y_train, epochs=10,batch_size=64) sc = model.evaluate(x_test, y_test) print("acc=",sc[1])
さて実行してみます。
Accuracy(精度)は、98.88%でした。
今度はNeural Network Consoleでやってみる
こちらは、サンプルプロジェクトを開いて、条件をあわせて学習・評価するだけです。
LeNet.sdcprjを選んで、バッチサイズやMax Epochなどの条件をあわせます。
これで学習・評価してみた結果は。
Accuracyは、98.75%です。
tf.kerasが、98.88%だったので、まあ・・誤差の範囲ですね。
なるほど。
モデル・データ・パラメータなどの条件が同じなら処理系が変わっても、結果は変わらんということですね。
だから。
Neural Network Consoleの方が検討しやすければ、そちらでやって、ブラウザで動かしたくなったら、tf.kerasに書き換えて・・みたいなやり方をしても、それによって結果が変わったりすることはない。
まあ。
当たり前の話ですが、確認できたのはよかったです。
ではでは。