Kerasで定番のMNISTをやりました
ディープラーニングやってみたいな~と思い、実践系のテキストを買ってテキストを写経コーディング ちゃんと学習した実行結果が得られたが、コードの意味を一行ずつ理解するのに時間が掛かる…
MNISTはこんな手書き数字の画像
テキスト:Kerasによるディープラーニング:実践テクニック&チューニング技法
データ前処理で画像を255で割るのはなんで?
Kerasを使ってMNIST手書き数字画像を「0~9のクラスに分類」するコードの前処理
1. MNISTデータをダウンロードするmnist.load_data()
1. 学習データ、テストデータの画像をそれぞれreshape
する
→ 1枚の画像が一次元配列になる(全結合層に投入する準備)
1. 配列をfloat32型にして、255で割る(なんで??)
# ???何してるんだ??? num_gray_scale_max = 255 x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= num_gray_scale_max x_test /= num_gray_scale_max
RGB値を255で割って画像を正規化している
画像のピクセル値を255で割って「0~1」の間の数値に正規化する → グレースケールにしている
グレースケール画像はカラー画像より計算効率が高いということなので、 正規化すると学習予測がきちんとできる
正規化 VS 非正規化
正規化した画像データと、正規化していない画像データで学習予測(分類)してみた!
正規化した時
正規化していない時
正規化していない時はガッタガタ。。。なぜか学習よりテストのほうが正解率が高い
import numpy as np import keras from keras.datasets import mnist import pickle from matplotlib import pyplot as plt %matplotlib inline # MNISTデータセット読み込み # (学習画像,学習ラベル),(テスト画像,テストラベル) (x_train, y_train), (x_test, y_test) = mnist.load_data() # 行数を保存 num_train_data = x_train.shape[0] num_test_data = x_test.shape[0] # 画像の行と列を掛け算して一次元配列にする時の要素数を求める # 28×28なので784 num_flatten_data = x_train.shape[1] * x_train.shape[2] # 画像データを行列に変換 x_train = x_train.reshape(num_train_data, num_flatten_data) x_test = x_test.reshape(num_test_data, num_flatten_data) # 画像データを0~1に正規化 num_gray_scale_max = 255 x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= num_gray_scale_max x_test /= num_gray_scale_max num_classes = 10 y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) from keras.models import Sequential from keras.layers import Dense, Dropout from keras.optimizers import RMSprop model = Sequential() # ノード512個、活性化関数ReLU、入力値は一次配列で784要素(28×28) model.add(Dense(512, activation='relu', input_shape=(784,))) # 20%の学習データを間引く model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) # 0~9の10クラス分類 model.add(Dense(10, activation='softmax')) model.summary() model.compile(loss='categorical_crossentropy', optimizer='RMSprop', metrics=['accuracy']) batch_size = 128 epochs = 50 # 学習画像、学習ラベル、バッチサイズ、エポック数、進捗を表示、テストデータ history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test,y_test)) # 重みをpickleファイルに保存 with open('./weight_keras_mnist.pkl', 'wb') as h_file: pickle.dump(history.history, h_file) # 学習結果をグラフにする plt.figure(figsize=(10,6)) plt.plot(history.history['accuracy'], color='b') plt.plot(history.history['val_accuracy'], color='r') plt.tick_params(labelsize=18) plt.title('epoch - accuracy graph') plt.ylabel('accuracy') plt.xlabel('epoch') plt.legend(['train','test']) plt.show()