TensorFlow 2.0 Alpha : Beginner Tutorials : ML 基本 :- 最初のニューラルネットワークを訓練する: 基本分類 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/26/2019
* 本ページは、TensorFlow の本家サイトの TF 2.0 Alpha – Beginner Tutorials – ML basics の以下のページを翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
最初のニューラルネットワークを訓練する: 基本分類
このガイドはスニーカーやシャツのような、衣類の画像を分類するニューラルネットワーク・モデルを訓練します。詳細の総てを理解しなくてもかまいません、これは進むにつれて詳細が説明される完全な TensorFlow プログラムのペースの速い概要です。
このガイドは、TensorFlow でモデルを構築して訓練する高位 API tf.keras を使用します。
!pip install -q tensorflow==2.0.0-alpha0
from __future__ import absolute_import, division, print_function # 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-alpha0
Fashion MNIST データセットをインポートする
このガイドは Fashion MNIST データセットを使用します、これは 10 カテゴリーの 70,000 グレースケール画像を含みます。この画像は、ここで見られるように衣料品の個々の品目を低解像度 (28 x 28 ピクセル) で示します :
Figure 1. Fashion-MNIST サンプル (by Zalando, MIT License).
Fashion MNIST は (コンピュータビジョンのための機械学習プログラムの “Hello, World” としてしばしば使用される) 古典的な MNIST データセットの差し込み式の (= drop-in) 置き換えとして意図されています。MNIST データセットはここで使用する衣料品の品目と同一の手書き数字 (0, 1, 2, etc) の画像を含みます。
このガイドは Fashion MNIST を多様性のために利用します、そしてそれは通常の MNIST よりも僅かばかり挑戦的な問題だからです。両者のデータセットは比較的小さくそしてアルゴリズムが期待どおりに動作するかを検証するために使用されます。それらはコードをテストしてデバッグするための良い開始点です。
ネットワークを訓練するために 60,000 画像を使用してネットワークが画像を分類することをどの程度正確に学習したかを評価するために 10,000 画像を使用します。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()
モデルを構築する
ニューラルネットワークの構築はモデルの層を configure することを必要とし、それからモデルをコンパイルします。
層をセットアップする
ニューラルネットワークの基本的なビルディングブロックは層です。層はそれらに供給されるデータから表現を抽出します。そして、望ましいのは、これらの表現が手元の問題のためにより意味があることです。
深層学習の殆どは単純な層を一緒に連鎖することで構成されます。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 ピクセルの) 2d 配列から 28 * 28 = 784 ピクセルの 1d 配列に変換します。この層を画像のピクセルの行をアンスタックしてそれらを並べるものとして考えてください。この層は学習するパラメータを持ちません; それはデータを再フォーマットするだけです。
ピクセルが平坦化された後は、ネットワークは 2 つの tf.keras.layers.Dense 層のシークエンスから成ります。これらは密結合、または完全結合、ニューラル層です。最初の Dense 層は 128 ノード (またはニューロン) を持ちます。2 番目 (そして最後の) 層は 10-ノード softmax 層です — これは総計が 1 になる 10 個の確率スコアの配列を返します。各ノードは現在の画像が 10 クラスの一つに属する確率を示すスコアを含みます。
モデルをコンパイルする
モデルが訓練のために準備が整う前に、それは幾つかの更なる設定を必要とします。これらはモデルのコンパイル段階の間に追加されます :
- 損失関数 — これはモデルが訓練の間どのくらい正確かを測ります。モデルを正しい方向に「操縦する (= 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=5)
Epoch 1/5 60000/60000 [==============================] - 5s 84us/sample - loss: 0.5039 - accuracy: 0.8214 Epoch 2/5 60000/60000 [==============================] - 4s 74us/sample - loss: 0.3768 - accuracy: 0.8633 Epoch 3/5 60000/60000 [==============================] - 5s 78us/sample - loss: 0.3385 - accuracy: 0.8758 Epoch 4/5 60000/60000 [==============================] - 5s 76us/sample - loss: 0.3131 - accuracy: 0.8838 Epoch 5/5 60000/60000 [==============================] - 5s 79us/sample - loss: 0.2930 - accuracy: 0.8914 <tensorflow.python.keras.callbacks.History at 0x7f9fc269b278>
モデルが訓練されるとき、損失と精度メトリクスが表示されます。このモデルは訓練データ上でおよそ 0.88 (or 88%) の精度に達します。
精度を評価する
次に、テストデータセット上でモデルがどのように遂行するか比較します :
test_loss, test_acc = model.evaluate(test_images, test_labels) print('\nTest accuracy:', test_acc)
10000/10000 [==============================] - 0s 46us/sample - loss: 0.3595 - accuracy: 0.8740 Test accuracy: 0.874
テストデータセット上の精度は訓練データセット上の精度よりも少し悪いことが分かります。訓練精度とテスト精度の間のこの隔たりは overfitting の例です。overfitting は機械学習モデルが新しいデータ上で訓練データ上よりもより悪く遂行するときです。
予測を行なう
訓練されたモデルで、幾つかの画像について予測を行なうためにそれを使用することができます。
predictions = model.predict(test_images)
ここで、モデルはテストセットの各画像のためにラベルを予測しました。最初の予測を見てみましょう :
predictions[0]
array([1.1913482e-05, 2.5270497e-08, 9.4376639e-07, 5.6023836e-10, 3.0359536e-07, 4.5878277e-03, 1.3910754e-06, 1.4167473e-01, 1.1293515e-05, 8.5371155e-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[i], 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[i], true_label[i] plt.grid(False) plt.xticks([]) 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 番目の画像、予測そして予測配列を見てみましょう。
i = 0 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions, test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions, test_labels) plt.show()
i = 12 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions, test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions, test_labels) plt.show()
幾つかの画像をそれらの予測とともにプロットしましょう。正しい予測ラベルは青色で正しくない予測ラベルは赤色です。数字は予測ラベルに対する (100 からの) パーセントです。非常に確信されてる時でもそれが間違う可能性があることに注意してください。
# Plot the first X test images, their predicted label, and the true label # Color correct predictions in blue, 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, test_labels, test_images) plt.subplot(num_rows, 2*num_cols, 2*i+2) plot_value_array(i, predictions, test_labels) plt.show()
最後に、訓練されたモデルを使用して単一画像について予測を行ないます。
# Grab an image from the test dataset img = test_images[0] 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)
[[1.1913485e-05 2.5270452e-08 9.4376657e-07 5.6023952e-10 3.0359516e-07 4.5878240e-03 1.3910718e-06 1.4167461e-01 1.1293518e-05 8.5371172e-01]]
plot_value_array(0, predictions_single, test_labels) _ = plt.xticks(range(10), class_names, rotation=45)
model.predict はリストのリストを返します、データのバッチの各画像に対して一つです。バッチの (唯一の) 画像のための予測を掴みます :
np.argmax(predictions_single[0])
9
そして、前のように、モデルは 9 のラベルを予測します。
以上