TensorFlow 2.0 : Tutorials : Keras ML 基本 :- 衣料品画像を予測する : 基本分類 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 10/01/2019
* 本ページは、TensorFlow org サイトの TF 2.0 – Beginner Tutorials – ML basics with Keras の以下のページを
翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
Tutorials : Keras ML 基本 :- 衣料品画像を予測する : 基本分類
このガイドはスニーカーやシャツのような、衣類の画像を分類するニューラルネットワーク・モデルを訓練します。詳細の総てを理解しなくてもかまいません、これは進むにつれて詳細が説明される完全な TensorFlow プログラムのペースの速いペースの概要です。
このガイドは、TensorFlow でモデルを構築して訓練する高位 API tf.keras を使用します。
from __future__ import absolute_import, division, print_function, unicode_literals # TensorFlow and tf.keras import tensorflow as tf from tensorflow import keras # Helper libraries import numpy as np import matplotlib.pyplot as plt print(tf.__version__)
2.0.0-rc2
Fashion MNIST データセットをインポートする
このガイドは Fashion MNIST データセットを使用します、これは 10 カテゴリーの 70,000 グレースケール画像を含みます。この画像は、ここで見られるように衣料品の個々の品目を低解像度 (28 x 28 ピクセル) で示します :
Fashion MNIST は (コンピュータビジョンのための機械学習プログラムの “Hello, World” としてしばしば使用される) 古典的な MNIST データセットの差し込み式の (= drop-in) 置き換えとして意図されています。MNIST データセットはここで使用する衣料品の品目と同一の形式の手書き数字 (0, 1, 2, etc) の画像を含みます。
このガイドは Fashion MNIST を変化をつけるために利用します、そしてそれは通常の MNIST よりも僅かばかり挑戦的な問題だからです。両者のデータセットは比較的小さくそしてアルゴリズムが期待どおりに動作するかを検証するために使用されます。それらはコードをテストしてデバッグするための良い開始点です。
ここでは、ネットワークを訓練するために 60,000 画像が使用されて、ネットワークが画像を分類することをどの程度正確に学習したかを評価するために 10,000 画像が使用されます。TensorFlow から直接 Fashion MNIST にアクセスできます。TensorFlow から直接 Fashion MNIST データをインポートしてロードしてください :
fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step
データセットのロードは 4 つの NumPy 配列を返します :
- train_images と train_labels 配列は訓練セット – モデルが学習するために使用するデータです。
- モデルはテストセット – test_images と test_labels 配列に対してテストされます。
画像は 28×28 NumPy 配列で、 0 から 255 の範囲のピクセル値を持ちます。ラベルは整数の配列で、0 から 9 の範囲です。これらは画像が表わす衣料品のクラスに対応します :
ラベル | クラス |
0 | T-シャツ/トップ (T-shirt/top) |
1 | ズボン (Trouser) |
2 | プルオーバー (Pullover) |
3 | ドレス (Dress) |
4 | コート (Coat) |
5 | サンダル (Sandal) |
6 | シャツ (Shirt) |
7 | スニーカー (Sneaker) |
8 | バッグ (Bag) |
9 | アンクルブーツ (Ankle boot) |
各画像は単一のラベルにマップされます。クラス名はデータセットには含まれませんので、後で画像をプロットするときに使用するためにそれらをここでストアします :
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
データを調査する
モデルを訓練する前にデータセットのフォーマットを調べてみましょう。以下は訓練セットに 60,000 画像があることを示しており、各画像は 28 x 28 ピクセルとして表わされます :
train_images.shape
(60000, 28, 28)
同様に、訓練セットに 60,000 ラベルがあります :
len(train_labels)
60000
各ラベルは 0 と 9 の間の整数です :
train_labels
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)
テストセットには 10,000 画像があります。再び、各画像は 28 x 28 ピクセルとして表わされます :
test_images.shape
(10000, 28, 28)
そしてテストセットは 10,000 画像ラベルを含みます :
len(test_labels)
10000
データを前処理する
ネットワークを訓練する前にデータは前処理されなければなりません。訓練セットの最初の画像を調べれば、ピクセル値が 0 から 255 の範囲に収まることを見るでしょう:
plt.figure() plt.imshow(train_images[0]) plt.colorbar() plt.grid(False) plt.show()
ニューラルネットワーク・モデルに供給する前にこれらの値を 0 と 1 の範囲にスケールします。このため、値を 255 で除算します。訓練セットとテストセットが同じ方法で前処理されることは重要です :
train_images = train_images / 255.0 test_images = test_images / 255.0
データが正しいフォーマットにあってネットワークを構築して訓練する準備ができていることを検証するために、訓練セットからの最初の 25 画像を表示して各画像の下にクラス名を表示しましょう。
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) plt.xlabel(class_names[train_labels[i]]) plt.show()
モデルを構築する
ニューラルネットワークの構築はモデルの層を構成して、それからモデルをコンパイルすることが必要です。
層をセットアップする
ニューラルネットワークの基本的なビルディングブロックは層です。層はそれらに供給されるデータから表現を抽出します。望ましいのは、これらの表現が手元の問題のために意味があることです。
深層学習の殆どは単純な層を一緒に連鎖することで構成されます。tf.keras.layers.Dense のような、殆どの層は訓練の間に学習されるパラメータを持ちます。
model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), keras.layers.Dense(128, activation='relu'), keras.layers.Dense(10, activation='softmax') ])
ネットワークの最初の層、tf.keras.layers.Flatten は画像のフォーマットを (28 x 28 ピクセルの) 2 次元配列から (28 * 28 = 784 ピクセルの) 1 次元配列に変換します。この層を画像のピクセルの行をアンスタックしてそれらを並べるものとして考えてください。この層は学習するパラメータを持ちません; それはデータを再フォーマットするだけです。
ピクセルが平坦化された後は、ネットワークは 2 つの tf.keras.layers.Dense 層のシークエンスから成ります。これらは密結合、または完全結合な、ニューラル層です。最初の Dense 層は 128 ノード (またはニューロン) を持ちます。2 番目 (そして最後の) 層は 10-ノード softmax 層です、これは総計が 1 になる 10 個の確率スコアの配列を返します。各ノードは現在の画像が 10 クラスの一つに属する確率を示すスコアを含みます。
モデルをコンパイルする
モデルが訓練のために準備が整う前に、それは幾つかのより多くの設定を必要とします。これらはモデルの compile ステップの間に追加されます :
- 損失関数 — これはモデルが訓練の間どのくらい正確かを測ります。モデルを正しい方向に「操縦する (= steer)」ためにこの関数を最小化することを望みます。
- Optimizer — これはモデルがそれが見るデータとその損失関数に基づいてどのように更新されるかです。
- メトリクス — 訓練とテストステップを監視するために使用されます。次のサンプルは accuracy (精度)、正しく分類された画像の比率を使用します。
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
モデルを訓練する
ニューラルネットワーク・モデルの訓練は次のステップを必要とします :
- 訓練データをモデルに供給します。この例では、train_images と train_labels 配列にあります。
- モデルは画像とラベルを関連付けることを学習します。
- モデルにテストセットについて予測を行なうことを求めます — この例では test_images 配列です。予測が test_labels 配列からのラベルに適合するかを検証します。
訓練を開始するためには、model.fit メソッドを呼び出します — モデルは訓練データに “fit” しますのでそのように呼ばれます :
model.fit(train_images, train_labels, epochs=10)
Train on 60000 samples Epoch 1/10 60000/60000 [==============================] - 5s 77us/sample - loss: 0.4944 - accuracy: 0.8262 Epoch 2/10 60000/60000 [==============================] - 4s 60us/sample - loss: 0.3750 - accuracy: 0.8658 Epoch 3/10 60000/60000 [==============================] - 3s 58us/sample - loss: 0.3373 - accuracy: 0.8759 Epoch 4/10 60000/60000 [==============================] - 4s 59us/sample - loss: 0.3130 - accuracy: 0.8854 Epoch 5/10 60000/60000 [==============================] - 4s 58us/sample - loss: 0.2951 - accuracy: 0.8911 Epoch 6/10 60000/60000 [==============================] - 3s 58us/sample - loss: 0.2793 - accuracy: 0.8972 Epoch 7/10 60000/60000 [==============================] - 4s 64us/sample - loss: 0.2682 - accuracy: 0.8997 Epoch 8/10 60000/60000 [==============================] - 4s 60us/sample - loss: 0.2595 - accuracy: 0.9040 Epoch 9/10 60000/60000 [==============================] - 3s 58us/sample - loss: 0.2479 - accuracy: 0.9062 Epoch 10/10 60000/60000 [==============================] - 3s 58us/sample - loss: 0.2390 - accuracy: 0.9105 <tensorflow.python.keras.callbacks.History at 0x7f9316b17390>
モデルが訓練されるとき、損失と精度メトリクスが表示されます。このモデルは訓練データ上でおよそ 0.88 (or 88%) の精度に到達します。
精度を評価する
次に、テストデータセット上でモデルがどのように遂行するか比較します :
test_loss, test_acc = model.evaluate(test_images, test_labels) print('\nTest accuracy:', test_acc)
10000/1 [================================================================] - 1s 56us/sample - loss: 0.2327 - accuracy: 0.8860 Test accuracy: 0.886
テストデータセット上の精度は訓練データセット上の精度よりも少し悪いことが分かります。訓練精度とテスト精度の間のこの隔たりは overfitting を表します。overfitting は機械学習モデルが訓練データ上よりも新しい、未見の入力上でより悪く (パフォーマンスが) 遂行するときのことです。
予測を行なう
訓練されたモデルで、幾つかの画像について予測を行なうためにそれを使用することができます。
predictions = model.predict(test_images)
ここで、モデルはテストセットの各画像のためのラベルを予測しました。最初の予測を見てみましょう :
predictions[0]
array([5.2581032e-07, 1.4517748e-09, 2.5350946e-08, 9.0922248e-09, 1.5219296e-08, 2.0876075e-03, 2.2626289e-06, 6.2742099e-02, 8.7106038e-08, 9.3516731e-01], dtype=float32)
予測は 10 個の配列です。これらは画像が衣料品の 10 の異なる品目の各々に対応するモデルの「確信度 (= 信頼度, confidence)」を表しています。どのラベルが最高の確信度値を持つかを見ることができます :
np.argmax(predictions[0])
9
従ってモデルはこの画像がアンクルブーツ、あるいは class_names[9] であると最も確信しています。テストラベルがこの分類が正しいことを示しているか調べます :
test_labels[0]
9
10 クラス予測の完全なセットを見るためにこれをグラフ化できます。
def plot_image(i, predictions_array, true_label, img): predictions_array, true_label, img = predictions_array, true_label[i], img[i] plt.grid(False) plt.xticks([]) plt.yticks([]) plt.imshow(img, cmap=plt.cm.binary) predicted_label = np.argmax(predictions_array) if predicted_label == true_label: color = 'blue' else: color = 'red' plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label], 100*np.max(predictions_array), class_names[true_label]), color=color) def plot_value_array(i, predictions_array, true_label): predictions_array, true_label = predictions_array, true_label[i] plt.grid(False) plt.xticks(range(10)) plt.yticks([]) thisplot = plt.bar(range(10), predictions_array, color="#777777") plt.ylim([0, 1]) predicted_label = np.argmax(predictions_array) thisplot[predicted_label].set_color('red') thisplot[true_label].set_color('blue')
0 番目の画像、予測そして予測配列を見てみましょう。正しい予測ラベルは青色で不正な予測ラベルは赤色です。数字は予測ラベルのための (100 からの) パーセンテージを与えます。
i = 0 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions[i], test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions[i], test_labels) plt.show()
i = 12 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions[i], test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions[i], test_labels) plt.show()
幾つかの画像をそれらの予測とともにプロットしましょう。非常に確信されてる時でもモデルが間違う可能性があることに注意してください。
# Plot the first X test images, their predicted labels, and the true labels. # Color correct predictions in blue and incorrect predictions in red. num_rows = 5 num_cols = 3 num_images = num_rows*num_cols plt.figure(figsize=(2*2*num_cols, 2*num_rows)) for i in range(num_images): plt.subplot(num_rows, 2*num_cols, 2*i+1) plot_image(i, predictions[i], test_labels, test_images) plt.subplot(num_rows, 2*num_cols, 2*i+2) plot_value_array(i, predictions[i], test_labels) plt.tight_layout() plt.show()
最後に、訓練されたモデルを使用して単一画像について予測を行ないます。
# Grab an image from the test dataset. img = test_images[1] print(img.shape)
(28, 28)
tf.keras モデルはサンプルのバッチ、あるいはコレクションについて一度に予測を行なうように最適化されています。そのため単一画像を使用していてさえも、それをリストに追加する必要があります :
# Add the image to a batch where it's the only member. img = (np.expand_dims(img,0)) print(img.shape)
(1, 28, 28)
さてこの画像のための正しいラベルを予測します :
predictions_single = model.predict(img) print(predictions_single)
[[5.0687635e-05 3.4319962e-13 9.9877065e-01 3.5758646e-10 1.4342026e-04 2.3974990e-15 1.0347982e-03 5.4287661e-18 3.5426123e-07 4.4112422e-14]]
plot_value_array(1, predictions_single[0], test_labels) _ = plt.xticks(range(10), class_names, rotation=45)
model.predict はリストのリストを返します — データのバッチの各画像に対して一つのリストです。バッチの (唯一の) 画像のための予測を掴みます :
np.argmax(predictions_single[0])
2
そしてモデルは予想どおりにラベルを予測します。
以上