TensorFlow 2.0 Beta : Tutorials : ML 基本 :- 最初のニューラルネットワークを訓練する: 基本分類 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 06/21/2019
* 本ページは、TensorFlow の本家サイトの TF 2.0 Beta – Beginner Tutorials – ML basics の以下のページを翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
Tutorials : ML 基本 :- 最初のニューラルネットワークを訓練する: 基本分類
このガイドはスニーカーやシャツのような、衣類の画像を分類するニューラルネットワーク・モデルを訓練します。詳細の総てを理解しなくてもかまいません、これは進むにつれて詳細が説明される完全な TensorFlow プログラムのペースの速い概要です。
このガイドは、TensorFlow でモデルを構築して訓練する高位 API tf.keras を使用します。
!pip install -q tensorflow==2.0.0-beta1
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-beta1
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 にアクセスできます。TensorFlow から直接 Fashion MNIST データをインポートしてロードすることができます :
fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
データセットのロードは 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)
WARNING: Logging before flag parsing goes to stderr. W0614 17:29:10.846302 140495257376512 deprecation.py:323] From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow/python/ops/math_grad.py:1250: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.where in 2.0, which has the same broadcast rule as np.where Train on 60000 samples Epoch 1/10 60000/60000 [==============================] - 4s 69us/sample - loss: 0.5003 - accuracy: 0.8231 Epoch 2/10 60000/60000 [==============================] - 4s 67us/sample - loss: 0.3734 - accuracy: 0.8649 Epoch 3/10 60000/60000 [==============================] - 4s 63us/sample - loss: 0.3391 - accuracy: 0.8755 Epoch 4/10 60000/60000 [==============================] - 4s 62us/sample - loss: 0.3141 - accuracy: 0.8842 Epoch 5/10 60000/60000 [==============================] - 4s 64us/sample - loss: 0.2960 - accuracy: 0.8901 Epoch 6/10 60000/60000 [==============================] - 4s 61us/sample - loss: 0.2814 - accuracy: 0.8961 Epoch 7/10 60000/60000 [==============================] - 4s 62us/sample - loss: 0.2691 - accuracy: 0.8996 Epoch 8/10 60000/60000 [==============================] - 4s 63us/sample - loss: 0.2581 - accuracy: 0.9046 Epoch 9/10 60000/60000 [==============================] - 4s 62us/sample - loss: 0.2504 - accuracy: 0.9068 Epoch 10/10 60000/60000 [==============================] - 4s 66us/sample - loss: 0.2419 - accuracy: 0.9095 <tensorflow.python.keras.callbacks.History at 0x7fc73ff97e48>
モデルが訓練されるとき、損失と精度メトリクスが表示されます。このモデルは訓練データ上でおよそ 0.88 (or 88%) の精度に到達します。
精度を評価する
次に、テストデータセット上でモデルがどのように遂行するか比較します :
test_loss, test_acc = model.evaluate(test_images, test_labels) print('\nTest accuracy:', test_acc)
10000/10000 [==============================] - 0s 38us/sample - loss: 0.3343 - accuracy: 0.8822 Test accuracy: 0.8822
テストデータセット上の精度は訓練データセット上の精度よりも少し悪いことが分かります。訓練精度とテスト精度の間のこの隔たりは overfitting を表します。overfitting は機械学習モデルが訓練データ上よりも新しい、未見の入力上でより悪く遂行するときのことです。
予測を行なう
訓練されたモデルで、幾つかの画像について予測を行なうためにそれを使用することができます。
predictions = model.predict(test_images)
ここで、モデルはテストセットの各画像のためにラベルを予測しました。最初の予測を見てみましょう :
predictions[0]
array([1.6820312e-08, 1.2007975e-10, 1.7058468e-07, 1.1677981e-09, 8.4652679e-10, 4.4132438e-03, 4.1356127e-08, 1.2666054e-02, 1.5807228e-07, 9.8292035e-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 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, 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.6820247e-08 1.2007975e-10 1.7058436e-07 1.1677960e-09 8.4652357e-10 4.4132336e-03 4.1355889e-08 1.2666019e-02 1.5807197e-07 9.8292035e-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 のラベルを予測します。
以上