TensorFlow : Keras : 最初のニューラルネットワークを訓練する: 基本分類 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 08/05/2018
* TensorFlow 1.9 でドキュメント構成が変更され、数篇が新規に追加されましたので再翻訳しました。
* 本ページは、TensorFlow の本家サイトの Tutorials – Learn and use ML – Train your first neural network: basic classification を翻訳した上で適宜、補足説明したものです:
* Fashion Mnist については fashion-mnist/README.ja.md を参照してください (弊社スタッフが翻訳しています)。
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
このガイドはスニーカーやシャツのような、衣類の画像を分類するニューラルネットワーク・モデルを訓練します。詳細の総てを理解しなくてもかまいません、これは進むにつれて詳細が説明される完全な TensorFlow プログラムのペースの速い概要です。
このガイドは、TensorFlow でモデルを構築して訓練する高位 API tf.keras を使用します。
# 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__)
1.9.0
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 http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 5us/step Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 7s 0us/step Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 4s 1us/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.gca().grid(False)
ニューラルネットワーク・モデルに供給する前に これらの値を 0 と 1 の範囲にスケールします。このため、画像成分のデータ型を integer から float にキャストし、 255 で除算します。画像を前処理する関数がここにあります。
訓練セットとテストセットが同じ方法で前処理されることは重要です :
train_images = train_images / 255.0 test_images = test_images / 255.0
訓練セットからの最初の 25 画像を表示して各画像の下にクラス名を示します。データが正しいフォーマットにあることを検証すればネットワークを構築して訓練する準備ができます。
import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid('off') plt.imshow(train_images[i], cmap=plt.cm.binary) plt.xlabel(class_names[train_labels[i]])
/usr/local/lib/python3.5/dist-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Passing one of 'on', 'true', 'off', 'false' as a boolean is deprecated; use an actual boolean (True/False) instead. warnings.warn(message, mplDeprecation, stacklevel=1)
モデルを構築する
ニューラルネットワークの構築はモデルの層を configure することを必要とし、それからモデルをコンパイルします。
層をセットアップする
ニューラルネットワークの基本的なビルディングブロックは層です。層はそれらに供給されるデータから表現を抽出します。そして、望ましいのは、これらの表現が手元の問題のためにより意味があることです。
深層学習の殆どは単純な層を一緒に連鎖することで構成されます。tf.keras.layers.Dense のような、殆どの層は訓練の間に学習されるパラメータを持ちます。
model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), keras.layers.Dense(128, activation=tf.nn.relu), keras.layers.Dense(10, activation=tf.nn.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=tf.train.AdamOptimizer(), 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 [==============================] - 2s 36us/step - loss: 0.4975 - acc: 0.8247 Epoch 2/5 60000/60000 [==============================] - 2s 35us/step - loss: 0.3732 - acc: 0.8662 Epoch 3/5 60000/60000 [==============================] - 2s 34us/step - loss: 0.3376 - acc: 0.8764 Epoch 4/5 60000/60000 [==============================] - 2s 34us/step - loss: 0.3127 - acc: 0.8851 Epoch 5/5 60000/60000 [==============================] - 2s 34us/step - loss: 0.2960 - acc: 0.8920
モデルが訓練されるとき、損失と精度メトリクスが表示されます。このモデルは訓練データ上でおよそ 0.88 (or 88%) の精度に達します。
精度を評価する
次に、テストデータセット上でモデルはどのように遂行するか比べます :
test_loss, test_acc = model.evaluate(test_images, test_labels) print('Test accuracy:', test_acc)
10000/10000 [==============================] - 0s 22us/step Test accuracy: 0.8684
テストデータセット上の精度は訓練データセット上の精度よりも少し悪いことが分かります。訓練精度とテスト精度の間のこのギャップは overfitting の例です。overfitting は機械学習モデルが新しいデータ上で訓練データ上よりもより悪く遂行するときを指します。
予測を行なう
訓練されたモデルで、幾つかの画像について予測を行なうためにそれを使用することができます。
predictions = model.predict(test_images)
ここで、モデルはテストセットの各画像に対するラベルを予測しました。最初の予測を見てみましょう :
predictions[0]
array([3.7345725e-07, 2.1462286e-06, 4.2489796e-07, 8.0572853e-08, 1.7010115e-07, 8.7923609e-02, 8.6243728e-07, 2.2786972e-01, 4.5513571e-05, 6.8415713e-01], dtype=float32)
予測は 10 個の数字の配列です。これらは画像が衣料品の 10 個の異なる品目の各々に対応する、モデルの “confidence” を表します。どのラベルが最高の confidence 値を持つかを見ることができます :
np.argmax(predictions[0])
9
従ってモデルはこの画像はアンクルブーツ、または class_names[9] であることを最も信頼しています。そしてこれが正しいことを見るためにテストラベルを確認することができます :
test_labels[0]
9
それらの予測とともに幾つかの画像をプロットしましょう。正しい予測ラベルは緑色で正しくない予測ラベルは赤色です。
# Plot the first 25 test images, their predicted label, and the true label # Color correct predictions in green, incorrect predictions in red plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid('off') plt.imshow(test_images[i], cmap=plt.cm.binary) predicted_label = np.argmax(predictions[i]) true_label = test_labels[i] if predicted_label == true_label: color = 'green' else: color = 'red' plt.xlabel("{} ({})".format(class_names[predicted_label], class_names[true_label]), color=color)
/usr/local/lib/python3.5/dist-packages/matplotlib/cbook/deprecation.py:107: MatplotlibDeprecationWarning: Passing one of 'on', 'true', 'off', 'false' as a boolean is deprecated; use an actual boolean (True/False) instead. warnings.warn(message, mplDeprecation, stacklevel=1)
最後に、単一の画像について予測を行なうために訓練されたモデルを使用します。
# 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 = model.predict(img) print(predictions)
[[3.7345919e-07 2.1462295e-06 4.2490018e-07 8.0573272e-08 1.7010170e-07 8.7923639e-02 8.6243847e-07 2.2787002e-01 4.5513811e-05 6.8415678e-01]]
model.predict はリストのリストを返します、データのバッチの各画像のために一つです。バッチの画像 (だけ) のための予測を把握するためには :
prediction = predictions[0] np.argmax(prediction)
9
そして、前のように、モデルは 9 のラベルを予測します。
以上