The sky is the limit

Vue.js、PHP、Java、Cordova、Monacaを中心にハイブリッドアプリ開発、PWA開発など効率的なWEB、iOS、Androidアプリ開発の情報を共有します。

【機械学習】TensorFlowの基本分類チュートリアル「Fashion MNIST」を実行しながら解説 - Part3 -【TensorFlow】

【機械学習】TensorFlowの基本分類チュートリアル「Fashion MNIST」を実行しながら解説 - Part3 -【TensorFlow】

モデルの訓練

ここからモデルの学習・訓練です。
訓練は次のようになります。

1:モデルにデータを投入する
2:モデルに画像とラベルの関係性を学習させる
3:テストデータの画像とラベルが一致することをモデルに確認させる

これらを以下の一文で実行しています。

# train model
model.fit(train_images, train_labels, epochs=5)

fitの引数には「train_images」、「train_labels」、「epochs=5」があります。
「train_images」、「train_labels」は訓練用画像とラベルであり、「epochs=5」とはモデルを訓練するエポック数が5という意味です。
エポック数とは訓練データを繰り返し学習させる回数であり、エポック数を増やしたり、減らすことで精度に影響を与えます。
エポック数をどのようにすれば精度が高くなるのかを試行錯誤してみると、面白いのでここで実験してみましょう。

まずはチュートリアルで実行されている、エポック数が5の時の結果です。

Epoch 1/5
60000/60000 [==============================] - 5s 83us/step - loss: 0.4919 - acc: 0.8274
Epoch 2/5
60000/60000 [==============================] - 5s 75us/step - loss: 0.3699 - acc: 0.8664
Epoch 3/5
60000/60000 [==============================] - 4s 73us/step - loss: 0.3318 - acc: 0.8794
Epoch 4/5
60000/60000 [==============================] - 4s 72us/step - loss: 0.3096 - acc: 0.8871
Epoch 5/5
60000/60000 [==============================] - 4s 69us/step - loss: 0.2941 - acc: 0.8918

lossというのが損失関数であり、accは精度を表します。
損失関数を小さくすることがニューラルネットワークの目的であり、それによって精度が高くなっていきます。
上記の例でも試行回数が増えていくにつれて、損失関数が小さくなり、精度が高くなっているのがわかります。
この訓練の最終的な精度は89%程度になりました。

エポック数を1、500とした時の結果も見てみましょう。

エポック数を1にする
# train model
model.fit(train_images, train_labels, epochs=1)

結果は以下の通りです。

Epoch 1/1
60000/60000 [==============================] - 5s 81us/step - loss: 0.4953 - acc: 0.8263

制度は82%程度となり、エポック数が5の場合に比べて精度は低くなってしまいました。

エポック数を500にする
# train model
model.fit(train_images, train_labels, epochs=100)

試行回数が増えるのでかなり時間がかかります。
チュートリアルの100倍の時間。。。
結果は省略して記載します。

Epoch 100/500
60000/60000 [==============================] - 5s 87us/step - loss: 0.0577 - acc: 0.9782
Epoch 200/500
60000/60000 [==============================] - 5s 85us/step - loss: 0.0292 - acc: 0.9901
Epoch 300/500
60000/60000 [==============================] - 5s 86us/step - loss: 0.0203 - acc: 0.9935
Epoch 400/500
60000/60000 [==============================] - 5s 80us/step - loss: 0.0161 - acc: 0.9950
Epoch 500/500
60000/60000 [==============================] - 5s 83us/step - loss: 0.0180 - acc: 0.9948

これは精度が99%程度まで上昇しました。
損失関数も0.018と、かなり小さくなっています。

これだけをみるとエポック数が大きければ大きいほど精度が高くなると言えるかもしれませんが、この精度はあくまで訓練データに対しての値になります。
この精度をテストデータでも出すことができるでしょうか?
確かめるために、モデルの評価を行いましょう。

モデルの評価

10000件あるテストデータを使って、訓練されたモデルの評価を行います。

test_loss, test_acc = model.evaluate(test_images, test_labels)

テストデータを投入して、損失関数と精度を算出できます。
各エポック数におけるそれぞれの値は以下の通りです。

エポック数5

損失関数:0.37083422453403475
精度:0.8636

エポック数1

損失関数:0.4242110157966614
精度:0.8493

エポック数500

損失関数:1.1986104100959207
精度:0.8858

このようにエポック数が500の場合、損失関数の値が大きくなってしまっています。
ディープラーニングでは損失関数の値を小さくすることが求められますので、これでは意味がありません。
また、訓練データに対する精度には大きな差がありましたが、テストデータに関する精度はあまり変わりません。
単にエポック数を大きくすれば良いという訳ではなさそうです。

ちなみにエポック数に関わらず、「訓練データに関する精度 > テストデータに関する精度」となっていますが、これは過学習の一種と言えます。

少し本筋からずれてしましましたので戻します。
チュートリアルで実施しているように、エポック数を5として進めます。
最後に、予測とある画像データに対する予測結果がどのようになるか確認してみましょう。

予測

ここまでで訓練と評価が終わったので、実際に予測をします。

予測結果の取得

test_imagesに対する予測結果を配列で返します。

# prediction
predictions = model.predict(test_images)

前述した通りで、返却値は「画像が各分類クラスである確率」の配列です。
ここではテストデータ全てに関する予測を取得しました。
次は、テストデータから任意のデータを取り出して、予測させた場合の結果を確認します。

単一画像データの予測結果

まずはテストデータの1番目を用意します。

img = test_images[0]


続いて、上記のデータをリストに追加した上で予測します

# add list
img = (np.expand_dims(img,0))

# predict 
predictions = model.predict(img)
prediction = predictions[0]

最後に、配列の中で最も大きな値(最も確率の高い)のラベルを取得します。

result = np.argmax(prediction)
print(result)

ここでは最終的な結果が「9」と表示され、以下の分類と比較すると、このデータはアングルブーツであると予測されていることがわかります。

0 => Tシャツ/トップ
1 => ズボン
2 => セーター
3 => ドレス
4 => コート
5 => サンダル
6 => シャツ
7 => スニーカー
8 => バッグ
9 => アンクルブーツ

以上になります。
次回からは、チュートリアルの回帰問題(住宅価格の予測)について解説していきたいと思います。

https://www.tensorflow.org/tutorials/keras/basic_regression?hl=ja