EeBlog(テクニカルブログ)

AI(人工知能)実践 第8回 TensorFlow(アヤメの分類)3

AI(人工知能)実践 第8回です。
第6回、第7回の続きとなり、
今回でTensorFlowのEstimatorを利用したアヤメの分類については終了となります。
 

第6回で記載したソース全文

import pandas as pd
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)
    
#データ読み込み用のメソッド作成
def read_file(file_name):
    data=pd.read_csv(file_name, usecols = [0, 1, 2, 3])
    label = pd.read_csv(file_name, usecols = [4])
    return data.values, label.values

#データ読み込み
training_x, training_y = read_file(IRIS_TRAINING)
test_x, test_y = read_file(IRIS_TEST)

# すべてのfeatureが実数値データであることを指定する
feature_columns = [tf.feature_column.numeric_column("x", shape=[4])]

# 10, 20, 10のノードを持つ3層のDNNを作成
classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns,
                                        hidden_units=[10, 20, 10],
                                        n_classes=3,
                                        model_dir="./iris_model")

# 学習用データ(辞書)を返す関数の作成
train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": np.array(training_x)},
    y=np.array(training_y),
    num_epochs=None,
    shuffle=True)

# 学習の実行。stepsを分割して実行しても同様の結果を得られる
classifier.train(input_fn=train_input_fn, steps=2000)

# 評価用データ(辞書)を返す関数の作成
test_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": np.array(test_x)},
    y=np.array(test_y),
    num_epochs=1,
    shuffle=False)

# 評価
accuracy_score = classifier.evaluate(input_fn=test_input_fn)["accuracy"]

print("\nTest Accuracy: {0:f}\n".format(accuracy_score))

第7回では、Estimatorsに学習用データを渡すための準備まで解説しましたので、
続きから解説していきます。
 

学習の実行

# 学習の実行。stepsを分割して実行しても同様の結果を得られる
classifier.train(input_fn=train_input_fn, steps=2000)

作成済みのDNN分類器にデータ取得用の関数と、繰り返し回数を指定して学習を実行しています。
ここでは学習回数を2000回としていますが、パラメータ数によって増減させる必要があります。
少なすぎる場合、データ量に対して十分に学習が進まず、
多すぎる場合、過学習となり、訓練データに関しては正答率が上がるものの、
訓練データに含まれていないデータに関しての正答率が下がることになります。

tf.estimator.DNNClassifier.train(https://www.tensorflow.org/api_docs/python/tf/estimator/DNNClassifier#train)は下記のように定義されています。
train(
input_fn,
hooks=None,
steps=None,
max_steps=None,
saving_listeners=None
)
return : self, for chaining.
 

Estimatorsに評価用データを渡すための準備

# 評価用データ(辞書)を返す関数の作成
test_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": np.array(test_x)},
    y=np.array(test_y),
    num_epochs=1,
    shuffle=False)

Estimatorsに学習用データを渡すための準備と同様ですので、説明は省略します。
思い出せない方は第7回の記事を参照してください。
 

評価の実行

accuracy_score = classifier.evaluate(input_fn=test_input_fn)["accuracy"]

学習した結果、どの程度の精度が出るようになったかの評価を実行します。
tf.estimator.DNNClassifier.evaluateメソッド自体は、戻り値が辞書型となっており、
‘accuracy’,’average_loss’,’global_step’,’loss’を含む辞書となります。
今回は精度のみ取得したかったので、evaluateメソッドの後ろに[“accuracy”]と記述し
accuracy_score変数の中には精度の値のみ格納しています。

tf.estimator.DNNClassifier.evaluate(https://www.tensorflow.org/api_docs/python/tf/estimator/DNNClassifier#evaluate)は下記のように定義されています。
evaluate(
input_fn,
steps=None,
hooks=None,
checkpoint_path=None,
name=None
)
return :A dict containing the evaluation metrics specified in model_fn keyed by name, as well as an entry global_step which contains the value of the global step for which this evaluation was performed
 

結果出力

print("\nTest Accuracy: {0:f}\n".format(accuracy_score))

評価の実行で出た結果を出力しています。

以上で、TensorFlowでのアヤメの分類についての説明は終了です。
今回は、学習用データ、評価用データが少なかったということもありますが、
短時間で大凡96%の精度が出るコードとなっています。
学習データを増やしてみたり、学習のステップ数を変えて、
精度にどこまで影響するか試してみるのも面白いかもしれません。

次回からは、簡単なものの自由度の低いEstimatorではなく、
もう少し自由度の高いKerasでの実装について触れていきます。