TensorFlow 2.0 : 上級 Tutorials : 画像 :- 畳み込みニューラルネットワーク (CNN) (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 11/02/2019
* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Images の以下のページを翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
画像 :- 畳み込みニューラルネットワーク
このチュートリアルは CIFAR 画像 を分類するために単純な 畳み込みニューラルネットワーク (CNN) の訓練を実演します。このチュートリアルは Keras Sequential API を使用しますので、モデルの作成と訓練は単にコードの数行かかるだけです。
Import TensorFlow
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf from tensorflow.keras import datasets, layers, models import matplotlib.pyplot as plt
CIFAR10 データセットをダウンロードして準備する
CIFAR10 データセットは 10 クラスの 60,000 カラー画像を含みます、各クラスに 6,000 画像です。データセットは 50,000 訓練画像と 10,000 テスト画像に分割されます。クラスは手動で排他的でありそれらの間に重複はありません。
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data() # Normalize pixel values to be between 0 and 1 train_images, test_images = train_images / 255.0, test_images / 255.0
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 170500096/170498071 [==============================] - 11s 0us/step
データを確認する
データセットが正しく見えるかを確認するため、訓練セットからの最初の 25 画像をプロットして各画像の下にクラス名を表示しましょう。
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid(False) plt.imshow(train_images[i], cmap=plt.cm.binary) # The CIFAR labels happen to be arrays, # which is why you need the extra index plt.xlabel(class_names[train_labels[i][0]]) plt.show()
畳み込みベースを作成する
下の 6 行のコードは一般的なパターン: Conv2D と MaxPooling2D 層のスタックを使用して畳み込みベースを定義しています。
入力として、CNN は shape (image_height, image_width, color_channels) の tensor を取り、バッチサイズは無視します。カラーチャネルに馴染みがないのであれば、color_channels は (R,G,B) に言及しています。この例では、CIFAR 画像のフォーマットである、shape (32, 32, 3) の入力を処理する CNN を構成します。引数 input_shape を最初の層に渡すことによりこれを行なうことができます。
model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu'))
ここまでのモデルのアーキテクチャを表示しましょう。
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 30, 30, 32) 896 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 13, 13, 64) 18496 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 4, 4, 64) 36928 ================================================================= Total params: 56,320 Trainable params: 56,320 Non-trainable params: 0 _________________________________________________________________
上で、総ての Conv2D と MaxPooling2D 層の出力が shape (height, width, channels) の 3D tensor であることを見ることができます。幅と高さの次元はネットワークで深くなるにつれて縮小する傾向にあります。各 Conv2D 層の出力チャネル数は最初の引数 (e.g., 32 or 64) により制御されます。典型的には、幅と高さが縮小するにつれて、各 Conv2D 層でより多くの出力チャネルを追加する能力が (計算的に) あります。
上に Dense 層を追加する
モデルを完成するために、分類を遂行するために (shape (3, 3, 64) の) 畳み込みベースからの最後の出力 tensor を一つかそれ以上の Dense 層に供給します。Dense 層は入力としてベクトル (それは 1D です) を取りますが、その一方で現在の出力は 3D tensor です。最初に、3D 出力を 1D に平坦化 (or 展開) して、それから一つかそれ以上の Dense 層を上に追加します。CIFAR は 10 出力クラスを持ちますので、10 出力と softmax 活性を持つ最後の Dense 層を使用します。
model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10, activation='softmax'))
ここにモデルの完全なアーキテクチャがあります。
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 30, 30, 32) 896 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 13, 13, 64) 18496 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 4, 4, 64) 36928 _________________________________________________________________ flatten (Flatten) (None, 1024) 0 _________________________________________________________________ dense (Dense) (None, 64) 65600 _________________________________________________________________ dense_1 (Dense) (None, 10) 650 ================================================================= Total params: 122,570 Trainable params: 122,570 Non-trainable params: 0 _________________________________________________________________
見れるように、2 つの Dense 層を通り抜ける前に (3, 3, 64) 出力は shape (576) のベクトルに平坦化されます。
モデルをコンパイルして訓練する
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) history = model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels))
Train on 50000 samples, validate on 10000 samples Epoch 1/10 50000/50000 [==============================] - 11s 222us/sample - loss: 1.5684 - accuracy: 0.4266 - val_loss: 1.2367 - val_accuracy: 0.5543 Epoch 2/10 50000/50000 [==============================] - 7s 130us/sample - loss: 1.1648 - accuracy: 0.5879 - val_loss: 1.1616 - val_accuracy: 0.5853 Epoch 3/10 50000/50000 [==============================] - 6s 130us/sample - loss: 1.0314 - accuracy: 0.6379 - val_loss: 1.0190 - val_accuracy: 0.6374 Epoch 4/10 50000/50000 [==============================] - 6s 129us/sample - loss: 0.9382 - accuracy: 0.6711 - val_loss: 0.9656 - val_accuracy: 0.6617 Epoch 5/10 50000/50000 [==============================] - 6s 129us/sample - loss: 0.8650 - accuracy: 0.6970 - val_loss: 0.9005 - val_accuracy: 0.6870 Epoch 6/10 50000/50000 [==============================] - 6s 129us/sample - loss: 0.8054 - accuracy: 0.7183 - val_loss: 0.9217 - val_accuracy: 0.6748 Epoch 7/10 50000/50000 [==============================] - 7s 131us/sample - loss: 0.7557 - accuracy: 0.7356 - val_loss: 0.9336 - val_accuracy: 0.6858 Epoch 8/10 50000/50000 [==============================] - 7s 132us/sample - loss: 0.7145 - accuracy: 0.7514 - val_loss: 0.9107 - val_accuracy: 0.6906 Epoch 9/10 50000/50000 [==============================] - 7s 134us/sample - loss: 0.6758 - accuracy: 0.7647 - val_loss: 0.8696 - val_accuracy: 0.7077 Epoch 10/10 50000/50000 [==============================] - 6s 130us/sample - loss: 0.6410 - accuracy: 0.7757 - val_loss: 0.8684 - val_accuracy: 0.7076
モデルを評価する
plt.plot(history.history['accuracy'], label='accuracy') plt.plot(history.history['val_accuracy'], label = 'val_accuracy') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.ylim([0.5, 1]) plt.legend(loc='lower right') test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
10000/1 - 1s - loss: 0.8927 - accuracy: 0.7076
print(test_acc)
0.7076
単純な CNN は 70% を越えるテスト精度を達成しました。数行のコードとしては悪くないです!もう一つの CNN スタイルについては、Keras subclassing API と tf.GradientTape を使用するサンプルを ここ で見てください。
以上