CNNを用いたpython画像処理入門①
今回は、画像認識に有効なCNNを用いた簡単な画像認識タスクをpythonで実施する。 まずはtensorflowで用意されているデータセットのFasion MNISTを読み込む。
import tensorflow as tf fashion_mnist = tf.keras.datasets.fashion_mnist (x_train, y_train), (x_test, y_test) = fashion_mnist.load_data() print(x_train.shape) # (画像数,縦の画素数,横の画素数)
実際に画像を出力してみる
%matplotlib inline import matplotlib.pyplot as plt # Fasion MNISTのラベル名 class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] #表示領域を設定(行,列) fig, ax = plt.subplots(2, 5,figsize=(10,4)) for i in range(10): plt.subplot(2,5,i+1) plt.tick_params(color='white') #メモリを消す plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False) plt.imshow(x_train[i],cmap='gray') plt.title(class_names[y_train[i]]) #図が重ならないようにする plt.tight_layout() #図を表示 plt.show()
画像の次元を(画像数,縦の画素数,横の画素数)->(画像数,縦の画素数,横の画素数,チャンネル数)に変換する
num_train_pic = x_train.shape[0] num_test_pic = x_test.shape[0] height = x_train[0].shape[0] width = x_train[0][0].shape[0] x_train = x_train.reshape(num_train_pic,height,width,1) x_test = x_test.reshape(num_test_pic,height,width,1)
画素数を0-1に正規化する
x_train = x_train /255. x_test = x_test /255.
モデルを定義・コンパイルし、サマリを表示。 Conv2Dで2次元畳み込み層を設定し、MaxPool2Dでプーリング処理を行う。 MNISTのラベルは10クラス存在するため、最終的な全結合層の出力次元数を「10」にする。 Softmax関数で総和が1となるように、各出力の予測確率を計算。 (例. 出力クラス=[0.1,0,0,0,0,0,0.1,0,0,0.8]⇔0の確率10%, 6の確率10%,9の確率80%)
model = tf.keras.Sequential([ # 入力画像 (縦の画素数,横の画素数,チャンネル数) # 28x28x1 -> 24x24x16 layers.Conv2D(16,kernel_size=(5,5),activation='relu', kernel_initializer='he_normal',input_shape=(height,width,1)), # 24x24x16 -> 12x12x16 layers.MaxPool2D(pool_size=(2,2)), # 12x12x16 -> 8x8x64 layers.Conv2D(64,kernel_size=(5,5),activation='relu', kernel_initializer='he_normal',input_shape=(height,width,1)), # 8x8x64 -> 4x4x64 layers.MaxPool2D(pool_size=(2,2)), # 4x4x64 -> 1024 layers.Flatten(), # 2024 -> 10 layers.Dense(10, activation='softmax') ]) model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'] ) model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 24, 24, 16) 416 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 12, 12, 16) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 8, 8, 64) 25664 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 4, 4, 64) 0 _________________________________________________________________ flatten (Flatten) (None, 1024) 0 _________________________________________________________________ dense (Dense) (None, 10) 10250 ================================================================= Total params: 36,330 Trainable params: 36,330 Non-trainable params: 0 _________________________________________________________________
モデルの学習
early_stopping = tf.keras.callbacks.EarlyStopping(patience=1,verbose=1) history = model.fit(x=x_train,y=y_train,batch_size=128,epochs=100,verbose=1, validation_data = (x_test,y_test),callbacks=[early_stopping])
2乗誤差の推移表示
plt.figure(figsize=(16, 8)) key='loss' ax = plt.plot(history.epoch, history.history[key], label=f'Train {key}') plt.plot(history.epoch, history.history[f'val_{key}'], '--', color=ax[0].get_color(), label=f'Val {key}') plt.xlabel('Epochs') plt.ylabel(key.title()) plt.legend() plt.xlim([0,max(history.epoch)])
最後にソースコード全体を示す
%matplotlib inline import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.keras import layers # データセットの読み込み fashion_mnist = tf.keras.datasets.fashion_mnist (x_train, y_train), (x_test, y_test) = fashion_mnist.load_data() # Fasion MNISTのラベル名 class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] #表示領域を設定(行,列) fig, ax = plt.subplots(2, 5,figsize=(10,4)) for i in range(10): plt.subplot(2,5,i+1) plt.tick_params(color='white') #メモリを消す plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False) plt.imshow(x_train[i],cmap='gray') plt.title(class_names[y_train[i]]) #図が重ならないようにする plt.tight_layout() #図を表示 plt.savefig('../output/fashion_mnist_pic1.png') plt.show() # (画像数,縦の画素数,横の画素数)->(画像数,縦の画素数,横の画素数,チャンネル数)に変換 num_train_pic = x_train.shape[0] num_test_pic = x_test.shape[0] height = x_train[0].shape[0] width = x_train[0][0].shape[0] x_train = x_train.reshape(num_train_pic,height,width,1) x_test = x_test.reshape(num_test_pic,height,width,1) # 画素数を0-1に正規化する x_train = x_train /255. x_test = x_test /255. # モデルの定義 model = tf.keras.Sequential([ # 入力画像 (縦の画素数,横の画素数,チャンネル数) # 28x28x1 -> 24x24x16 layers.Conv2D(16,kernel_size=(5,5),activation='relu', kernel_initializer='he_normal',input_shape=(height,width,1)), # 24x24x16 -> 12x12x16 layers.MaxPool2D(pool_size=(2,2)), # 12x12x16 -> 8x8x64 layers.Conv2D(64,kernel_size=(5,5),activation='relu', kernel_initializer='he_normal',input_shape=(height,width,1)), # 8x8x64 -> 4x4x64 layers.MaxPool2D(pool_size=(2,2)), # 4x4x64 -> 1024 layers.Flatten(), # 2024 -> 10 layers.Dense(10, activation='softmax') ]) model.compile( optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'] ) print(model.summary()) # モデルの学習 early_stopping = tf.keras.callbacks.EarlyStopping(patience=1,verbose=1) history = model.fit(x=x_train,y=y_train,batch_size=128,epochs=100,verbose=1, validation_data = (x_test,y_test),callbacks=[early_stopping]) # 2乗誤差の推移表示 plt.figure(figsize=(16, 8)) key='loss' ax = plt.plot(history.epoch, history.history[key], label=f'Train {key}') plt.plot(history.epoch, history.history[f'val_{key}'], '--', color=ax[0].get_color(), label=f'Val {key}') plt.xlabel('Epochs') plt.ylabel(key.title()) plt.legend() plt.xlim([0,max(history.epoch)])