TensorFlow : Get Started : tf.estimator クイックスタート (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 09/18/2017
* 本ページは、TensorFlow の本家サイトの Get Started – tf.estimator Quickstart を翻訳した上で
適宜、補足説明したものです
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
TensorFlow の高位な機械学習 API (tf.estimator) は様々な機械学習モデルを構成し、訓練し、そして評価することを容易にします。このチュートリアルでは、花弁 (petal) / ガク片 (sepal) の形状をもとに花の種を予測するために、tf.estimator を使用して ニューラルネットワーク 分類器を構築しそれを アイリス・データセット で訓練します。コードを書いて次の5つのステップを実行します :
- アイリス訓練/テストデータを含む CSV を TensorFlow データセットにロードする
- ニューラルネットワーク分類器を構築する
- 訓練データを使用してモデルを訓練する
- モデルの精度を評価する
- 新しいサンプルを分類する
NOTE: このチュートリアルで開始する前に 貴方のマシン上に TensorFlow をインストールする ことを忘れないでください。
完全なニューラルネットワーク・ソースコード
ニューラルネットワーク分類器のための完全なコードがここにあります :
from __future__ import absolute_import from __future__ import division from __future__ import print_function import os import urllib import numpy as np import tensorflow as tf # Data sets IRIS_TRAINING = "iris_training.csv" IRIS_TRAINING_URL = "http://download.tensorflow.org/data/iris_training.csv" IRIS_TEST = "iris_test.csv" IRIS_TEST_URL = "http://download.tensorflow.org/data/iris_test.csv" def main(): # If the training and test sets aren't stored locally, download them. if not os.path.exists(IRIS_TRAINING): raw = urllib.urlopen(IRIS_TRAINING_URL).read() with open(IRIS_TRAINING, "w") as f: f.write(raw) if not os.path.exists(IRIS_TEST): raw = urllib.urlopen(IRIS_TEST_URL).read() with open(IRIS_TEST, "w") as f: f.write(raw) # Load datasets. training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float32) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TEST, target_dtype=np.int, features_dtype=np.float32) # Specify that all features have real-value data feature_columns = [tf.feature_column.numeric_column("x", shape=[4])] # Build 3 layer DNN with 10, 20, 10 units respectively. classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns, hidden_units=[10, 20, 10], n_classes=3, model_dir="/tmp/iris_model") # Define the training inputs train_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": np.array(training_set.data)}, y=np.array(training_set.target), num_epochs=None, shuffle=True) # Train model. classifier.train(input_fn=train_input_fn, steps=2000) # Define the test inputs test_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": np.array(test_set.data)}, y=np.array(test_set.target), num_epochs=1, shuffle=False) # Evaluate accuracy. accuracy_score = classifier.evaluate(input_fn=test_input_fn)["accuracy"] print("\nTest Accuracy: {0:f}\n".format(accuracy_score)) # Classify two new flower samples. new_samples = np.array( [[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=np.float32) predict_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": new_samples}, num_epochs=1, shuffle=False) predictions = list(classifier.predict(input_fn=predict_input_fn)) predicted_classes = [p["classes"] for p in predictions] print( "New Samples, Class Predictions: {}\n" .format(predicted_classes)) if __name__ == "__main__": main()
次のセクションでコードを詳細に通り抜けます。
アイリス CSV データを TensorFlow にロードする
アイリス・データセット は 150 行のデータを含み、3つの関連アイリス種 : アイリス・セトサ (setosa)、アイリス・バージニカ (virginica)、アイリス・バージカラー (versicolor) の各々からの 50 サンプルから成ります。
左から右へ、アイリス・セトサ (by Radomil, CC BY-SA 3.0)、アイリス・バージカラー (by Dlanglois, CC BY-SA 3.0)、そして アイリス・バージニカ (by Frank Mayfield, CC BY-SA 2.0) です。
各行は各花のサンプルのための次のデータを含みます : がく片 (= sepal) 長さ、がく片幅、花弁 (= petal) 長さ、花弁幅、そして花の種。花の種は整数として表され、0 はアイリス・セトサを示し、1 はアイリス・バージカラーを示し、そして 2 はアイリス・バージニカを示します。
がく片長さ | がく片幅 | 花弁長さ | 花弁幅 | 種 |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | 0 |
4.9 | 3.0 | 1.4 | 0.2 | 0 |
4.7 | 3.2 | 1.3 | 0.2 | 0 |
… | … | … | … | … |
7.0 | 3.2 | 4.7 | 1.4 | 1 |
6.4 | 3.2 | 4.5 | 1.5 | 1 |
6.9 | 3.1 | 4.9 | 1.5 | 1 |
… | … | … | … | … |
6.5 | 3.0 | 5.2 | 2.0 | 2 |
6.2 | 3.4 | 5.4 | 2.3 | 2 |
5.9 | 3.0 | 5.1 | 1.8 | 2 |
このチュートリアルのために、アイリス・データはランダム化されて2つの別の CSV に分割されています :
- 120 サンプルの訓練セット ( iris_training.csv )
- 30 サンプルのテストセット ( iris_test.csv ).
始めるには、最初に全ての必要なモジュールをインポートして、データセットをどこにダウンロードしてストアするかを定義します :
from __future__ import absolute_import from __future__ import division from __future__ import print_function import os import urllib import tensorflow as tf import numpy as np IRIS_TRAINING = "iris_training.csv" IRIS_TRAINING_URL = "http://download.tensorflow.org/data/iris_training.csv" IRIS_TEST = "iris_test.csv" IRIS_TEST_URL = "http://download.tensorflow.org/data/iris_test.csv"
そして、訓練とテストセットがまだローカルにストアされていないならば、それらをダウンロードします。
if not os.path.exists(IRIS_TRAINING): raw = urllib.urlopen(IRIS_TRAINING_URL).read() with open(IRIS_TRAINING,'w') as f: f.write(raw) if not os.path.exists(IRIS_TEST): raw = urllib.urlopen(IRIS_TEST_URL).read() with open(IRIS_TEST,'w') as f: f.write(raw)
次に、訓練とテストセットを learn.datasets.base の load_csv_with_header() メソッドを使用してデータセットにロードします。load_csv_with_header() は3つの必要な引数を取ります :
- filename, これは CSV ファイルへのファイルパスを取ります。
- target_dtype, これはデータセットの目標値 (= target value) の numpy データ型を取ります。
- features_dtype, これはデータセットの特徴値 (= feature values) の numpy データ型を取ります。
ここで、目標 (= target, モデルを訓練して予測するための値) は花の種で、これは 0-2 の整数ですから、妥当な numpy データ型は np.int です :
# Load datasets. training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float32) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename=IRIS_TEST, target_dtype=np.int, features_dtype=np.float32)
tf.contrib.learn のデータセットは named tuples (名前付きタプル) です; データと目標 (target) フィールドを通して特徴データと目標値にアクセスできます。ここで、training_set.data と training_set.target は訓練セットのための特徴データと目標値をそれぞれ含み、そして test_set.data と test_set.target はテストセットのための特徴データと目標値を含みます。
後で、”DNNClassifier をアイリス訓練データにフィットさせる” でモデルを訓練するために training_set.data と training_set.target を使用して、そして “モデル精度を評価する” では test_set.data と test_set.target を使用します。しかしまずは、次のセクションでモデルを構築します。
深層ニューラルネットワーク分類器を構築する
tf.estimator は Estimator と呼ばれる、事前定義されたモデルを各種提供しています、これは貴方のデータ上で訓練と評価演算を実行するために “枠にとらわれない (out of the box)” モデルとして使用できます。 ここで、アイリス・データにフィットさせるために深層ニューラルネットワーク分類器モデルを構成します。tf.estimator を使用して、2、3行のコードで tf.estimator.DNNClassifier をインスタンス化できます :
# Specify that all features have real-value data feature_columns = [tf.feature_column.numeric_column("x", shape=[4])] # Build 3 layer DNN with 10, 20, 10 units respectively. classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns, hidden_units=[10, 20, 10], n_classes=3, model_dir="/tmp/iris_model")
上のコードは最初にモデルの特徴カラムを定義します、これはデータセットの特徴のためのデータ型を指定します。全ての特徴データは連続的ですので、特徴カラムを構成するために使用するのに tf.feature_column.numeric_column が適切な関数になります。データセット (ガク片幅、ガク片長さ、花弁幅、花弁高さ) には4つの特徴があり、従って全てのデータを保持するためには shape は [4] に設定されなければなりません。
それから、コードは次の引数を使用して DNNClassifier モデルを作成します :
- feature_columns=feature_columns. 上で定義された特徴カラムのセット。
- hidden_units=[10, 20, 10]. 3つの 隠れ層 で、10, 20, そして 10 ニューロンをそれぞれ含みます。
- n_classes=3。3つの目標クラスで、3つのアイリス種を表します。
- model_dir=/tmp/iris_model。モデル訓練の間に TensorFlow がチェックポイント・データと TensorBoard 要約をセーブするディレクトリ。
訓練入力パイプラインを記述する
tf.estimator API は入力関数を使用し、これはモデルのためのデータを生成する TensorFlow 演算を作成します。入力パイプラインを生成するためには tf.estimator.inputs.numpy_input_fn が使用できます :
# Define the training inputs train_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": np.array(training_set.data)}, y=np.array(training_set.target), num_epochs=None, shuffle=True)
DNNClassifier をアイリス訓練データにフィットさせる
DNN classifier モデルを構成した今、train メソッドを使用してそれをアイリス訓練データにフィットさせることができます。input_fn として train_input_fn と、訓練のためのステップ数 (ここでは、2000) を渡します :
# Train model. classifier.train(input_fn=train_input_fn, steps=2000)
モデルの状態は classifier に保持されます、これは望むならば繰り返し訓練できることを意味します。例えば、上は次と同値です :
classifier.train(input_fn=train_input_fn, steps=1000) classifier.train(input_fn=train_input_fn, steps=1000)
けれども、訓練の間モデルを追跡することに目を向けるならば、代わりにロギング演算を実行するために TensorFlow SessionRunHook を使用することを望むでしょう。
モデル精度を評価する
アイリス訓練データで DNNClassifier モデルを訓練しました ; 今、evaluate メソッドを使用してアイリス・テストデータでその精度を確認できます。train のように、evaluate はその入力パイプラインを構築する入力関数を取ります。evaluate は評価結果とともに dict を返します。次のコードはアイリス・テストデータ — test_set.data とtest_set.target — を結果から精度を評価して表示するために渡します :
# Define the test inputs test_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": np.array(test_set.data)}, y=np.array(test_set.target), num_epochs=1, shuffle=False) # Evaluate accuracy. accuracy_score = classifier.evaluate(input_fn=test_input_fn)["accuracy"] print("\nTest Accuracy: {0:f}\n".format(accuracy_score))
Note: numpy_input_fn への num_epochs=1 引数はここでは重要です。test_input_fn はデータに渡り一度だけ反復し、そしてそれから OutOfRangeError をあげます。このエラーは分類器に評価を止めるようにシグナルを送ります、従ってそれは入力について一度だけ評価するでしょう。
フル・スクリプトを実行した時、次に近いようなものを出力するでしょう :
Test Accuracy: 0.966667
精度結果は少し様々かもしれませんが、90% より高くなるべきです。比較的小さいデータセットに対しては悪くありません!
新しいサンプルを分類する
新しいサンプルを分類するためには estimator の predict() メソッドを使用します。例えば、これら2つの新しい花のサンプルがあるとします :
がく片長さ | がく片幅 | 花弁長 | 花弁幅 |
---|---|---|---|
6.4 | 3.2 | 4.5 | 1.5 |
5.8 | 3.1 | 5.0 | 1.7 |
predict() メソッドを使用してこれらの種を予測できます。predict は dict の generator を返し、これは簡単にリストに変換されます。次のコードはクラス予測を取得して出力します :
# Classify two new flower samples. new_samples = np.array( [[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=np.float32) predict_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": new_samples}, num_epochs=1, shuffle=False) predictions = list(classifier.predict(input_fn=predict_input_fn)) predicted_classes = [p["classes"] for p in predictions] print( "New Samples, Class Predictions: {}\n" .format(predicted_classes))
結果は次のように見れるはずです :
New Samples, Class Predictions: [1 2]
モデルはこうして最初のサンプルはアイリス・バージカラーであることを、そして2つ目のサンプルはアイリス・バージニカであることを予測します。
以上