0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

畳み込みニューラルネットワークを用いた画像判別(cifar10)モデルを作った

Last updated at Posted at 2020-03-08

はじめに

 
 機械学習初学者のfumioです。機械学習プログラミングの面白さにのめりこんで、日々学んでいます。

 koshian2さんが書かれた「モザイク除去から学ぶ 最先端のディープラーニング」を学んでいます。自身が学んだ内容の理解を深めるため、畳み込みニューラルネットワーク(CNN)を画像判別に適用した例をまとめていきたいと思います。
https://qiita.com/koshian2/items/aefbe4b26a7a235b5a5e

 要点は下記になります。

  • 畳み込みニューラルネットワークの構造を理解する。
  • 層の畳み込み+1層のDenseの計10層の畳み込みニューラルネットワークモデルを作る。
  • そのモデルによりCIFAR-10データセットの判別を行う。

##畳み込みニューラルネットワーク構造

 畳み込みニューラルネットワーク(CNN)は、畳み込み層とプーリング層という2種類の層を含む順伝搬型ネットワークで、画像認識に応用されています。

※順伝搬型ニューラルネットワークとはネットワークにループする結合を持たず、入力層→中間層→出力層というように単一方向へのみ信号が伝播するものを指します。一方で、再帰型ニューラルネットワークはその逆で可逆的なものです。

##データセットの読み込み

cifar10.ipynb

import matplotlib.pyplot as plt

cifar_classes = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]

(X_train, y_train),(X_test,y_test) = tf.keras.datasets.cifar10.load_data()
print(X_train.shape,y_train.shape)
print(X_test.shape,y_test.shape)

Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 13s 0us/step
(50000, 32, 32, 3) (50000, 1)
(10000, 32, 32, 3) (10000, 1)

 Kerasのデータセットから直接読み込みます。訓練データの次元を確認すると、5万枚の32×32×3のデータであることが分かります。カラー画像なので3次元となっていますね。

cifar10.ipynb

fig = plt.figure(figsize=(14,14))
for i in range(100):
  ax = plt.subplot(10,10,i+1)
  ax.imshow(X_train[i])
  ax.axis('off')
  ax.set_title(cifar_classes[y_train[i,0]])

010.png

 画像はこのようになっております。既に最初からぼやけていますが、なんとなくそれぞれの名前と写真の意味が分かります。ただ、判別が難しい種類のものも含まれていることが分かります(deer と horseとか、automobileとtruckとか)。

##プーリングとは

image.png

 

 CNNにおけるプーリングとは、情報を圧縮してダウンサンプリングすることを指します。通常、畳み込み層の後にプーリング層として適用されます。主な効果は下記になります。

  1. 微小な位置変化に対応できる
  2. ある程度過学習を抑制できる
  3. 計算コストを下げられる

 
 1.の位置変化に対応している多少特徴の位置がずれていてもプーリング層での出力を一定になるようにできます。つまり、手書き数字を例にとると少し位置がずれたものでも同じ数字だと認識させることができます。
 

##10層のニューラルネットワークモデルを作る

 今回のCIFAR-10判別を行うために、9層の畳み込み+1層の全結合層の計10層のモデルを作ります。

  • 畳み込み(Conv) 64ch -> バッチ正規化(BN) -> 活性化(ReLU)) repeat x3 -> プーリング(Pooling)
  • (Conv 128ch -> BN -> ReLU) repeat x3 -> Pooling
  • (Conv 256ch -> BN -> ReLU) repeat x3
  • Global Average Pooling -> Dense 10 -> Softmax

このような順番でモデルを作ります。活性化関数としてはReLUを用いています。

cifar10.ipynb

inputs = layers.Input((32,32,3))
x = inputs

for ch in [64, 128, 256]:
    for i in range(3):
        x = layers.Conv2D(ch, 3, padding="same")(x)
        x = layers.BatchNormalization()(x)
        x = layers.ReLU()(x)
    if ch != 256:
        x = layers.AveragePooling2D()(x)
        
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(10, activation="softmax")(x)
model = tf.keras.models.Model(inputs, x)
model.summary()

conv2d_12 (Conv2D) (None, 8, 8, 256) 590080
batch_normalization_12 (Batc (None, 8, 8, 256) 1024
re_lu_12 (ReLU) (None, 32, 32, 256) 0
average_pooling2d_3 (Average (None, 8, 8, 256) 0
global_average_pooling2d_1 ( (None, 256) 0
dense_1 (Dense) (None, 10) 2570

出力される最後の部分だけ抽出しました。
次元としては、下記のように変わります。
(None,32,32,3)→(None,32,32,64)→(None, 16, 16, 128)
→(None, 8, 8, 256)→(None, 256)→(None, 10)
プーリング層を通ると次元が半分になっていることが分かります。

##データセットの下準備

cifar10.ipynb

X_train = X_train.astype(np.float32) / 255.0
X_test = X_test.astype(np.float32) / 255.0
y_train = y_train.astype(np.float32)
y_test = y_test.astype(np.float32)

 次に、元々のデータはunit8型で、[0,255]スケールであることから、データの型をfloat32及びスケールを[0,1]に変換します。

##モデル学習

cifar10.ipynb

model.fit(X_train,y_train, validation_data=(X_test, y_test),epochs=10)

 PCスペックによってはかなり時間がかかるものと思われます(私のPCスペックだとepochごとに10分程度かかりました)。従って、Google Colabの力を借りて進めることをお勧めします。
 
 下記画像が予測した結果と正解です。赤で書かれているところが誤っているところです。
 10回しかepochを取らなかったので、大よそ誤答率38%でした。

011.png

プログラム全文はこちらに置いています。
https://github.com/Fumio-eisan/cifar10_20200308

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?