このページは Cloud Translation API によって翻訳されました。
Switch to English

既製の推定量

TensorFlow.orgで表示 GoogleColabで実行 GitHubでソースを表示ノートブックをダウンロード

このチュートリアルでは、Estimatorを使用してTensorFlowのアイリス分類問題を解決する方法を示します。 Estimatorは、TensorFlowによる完全なモデルの高レベルの表現であり、簡単なスケーリングと非同期トレーニング用に設計されています。詳細については、 Estimatorsを参照してください。

TensorFlow 2.0では、Keras APIはこれらの同じタスクの多くを実行でき、習得が容易なAPIであると考えられていることに注意してください。新しく始める場合は、Kerasから始めることをお勧めします。 TensorFlow 2.0で利用可能な高レベルAPIの詳細については、Kerasでの標準化を参照してください。

まず最初に

開始するには、最初にTensorFlowと必要ないくつかのライブラリをインポートします。

import tensorflow as tf

import pandas as pd

データセット

このドキュメントのサンプルプログラムは、がく花びらのサイズに基づいて、アイリスの花を3つの異なる種に分類するモデルを構築してテストします。

アイリスデータセットを使用してモデルをトレーニングします。アイリスデータセットには、4つの機能と1つのラベルが含まれています。 4つの特徴は、個々のアイリスの花の次の植物学的特徴を識別します。

  • がく片の長さ
  • がく片の幅
  • 花びらの長さ
  • 花びらの幅

この情報に基づいて、データを解析するためのいくつかの有用な定数を定義できます。

CSV_COLUMN_NAMES = ['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth', 'Species']
SPECIES = ['Setosa', 'Versicolor', 'Virginica']

次に、KerasとPandasを使用してIrisデータセットをダウンロードして解析します。トレーニングとテストのために個別のデータセットを保持していることに注意してください。

train_path = tf.keras.utils.get_file(
    "iris_training.csv", "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv")
test_path = tf.keras.utils.get_file(
    "iris_test.csv", "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv")

train = pd.read_csv(train_path, names=CSV_COLUMN_NAMES, header=0)
test = pd.read_csv(test_path, names=CSV_COLUMN_NAMES, header=0)

データを調べて、4つのfloat特徴列と1つのint32ラベルがあることを確認できます。

train.head()

データセットごとに、モデルが予測するようにトレーニングされるラベルを分割します。

train_y = train.pop('Species')
test_y = test.pop('Species')

# The label column has now been removed from the features.
train.head()

Estimatorを使用したプログラミングの概要

データを設定したので、TensorFlowEstimatorを使用してモデルを定義できます。 Estimatorは、 tf.estimator.Estimatorから派生した任意のクラスtf.estimator.Estimator 。 TensorFlowは、一般的なMLアルゴリズムを実装するためのtf.estimatorコレクション(たとえば、 LinearRegressor )を提供します。それらを超えて、独自のカスタムEstimatorを作成できます。開始するときは、事前に作成されたEstimatorを使用することをお勧めします。

事前に作成されたEstimatorに基づいてTensorFlowプログラムを作成するには、次のタスクを実行する必要があります。

  • 1つ以上の入力関数を作成します。
  • モデルのフィーチャ列を定義します。
  • 特徴列とさまざまなハイパーパラメータを指定して、Estimatorをインスタンス化します。
  • Estimatorオブジェクトで1つ以上のメソッドを呼び出し、適切な入力関数をデータのソースとして渡します。

これらのタスクがアイリス分類のためにどのように実装されているかを見てみましょう。

入力関数を作成する

トレーニング、評価、および予測のためのデータを提供するための入力関数を作成する必要があります。

入力関数は、次の2要素タプルを出力するtf.data.Datasetオブジェクトを返す関数です。

  • features -Python辞書:
    • 各キーは機能の名前です。
    • 各値は、その機能のすべての値を含む配列です。
  • labelすべての例のラベルの値を含む配列。

入力関数のフォーマットを示すために、簡単な実装を次に示します。

def input_evaluation_set():
    features = {'SepalLength': np.array([6.4, 5.0]),
                'SepalWidth':  np.array([2.8, 2.3]),
                'PetalLength': np.array([5.6, 3.3]),
                'PetalWidth':  np.array([2.2, 1.0])}
    labels = np.array([2, 1])
    return features, labels

入力関数は、 features辞書とlabelリストを好きなように生成できます。しかし、我々はTensorFlowの使用をお勧めしますデータセットのAPIデータのすべての種類を解析することができ、。

Dataset APIは、多くの一般的なケースを処理できます。たとえば、Dataset APIを使用すると、ファイルの大規模なコレクションからレコードを簡単に並行して読み込み、単一のストリームに結合できます。

この例では物事を単純にするために、パンダを使用してデータをロードし、このメモリ内データから入力パイプラインを構築します。

def input_fn(features, labels, training=True, batch_size=256):
    """An input function for training or evaluating"""
    # Convert the inputs to a Dataset.
    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))

    # Shuffle and repeat if you are in training mode.
    if training:
        dataset = dataset.shuffle(1000).repeat()

    return dataset.batch(batch_size)

フィーチャ列を定義する

特徴列は、モデルが特徴ディクショナリからの生の入力データをどのように使用するかを説明するオブジェクトです。 Estimatorモデルを作成するときは、モデルで使用する各機能を説明する機能列のリストを渡します。 tf.feature_columnモジュールは、モデルにデータを表すための多くのオプションを提供します。

Irisの場合、4つの生の特徴は数値であるため、特徴列のリストを作成して、4つの特徴のそれぞれを32ビット浮動小数点値として表すようにEstimatorモデルに指示します。したがって、機能列を作成するコードは次のとおりです。

# Feature columns describe how to use the input.
my_feature_columns = []
for key in train.keys():
    my_feature_columns.append(tf.feature_column.numeric_column(key=key))

特徴列は、ここで示しているものよりもはるかに洗練されている可能性があります。このガイドで特徴列の詳細を読むことができます。

モデルに生の特徴をどのように表現させるかについての説明ができたので、推定量を作成できます。

推定量をインスタンス化する

虹彩問題は古典的な分類問題です。幸い、TensorFlowには、次のようないくつかの事前に作成された分類子推定器が用意されています。

アイリスの問題については、 tf.estimator.DNNClassifierが最良の選択のようです。このEstimatorをインスタンス化した方法は次のとおりです。

# Build a DNN with 2 hidden layers with 30 and 10 hidden nodes each.
classifier = tf.estimator.DNNClassifier(
    feature_columns=my_feature_columns,
    # Two hidden layers of 30 and 10 nodes respectively.
    hidden_units=[30, 10],
    # The model must choose between 3 classes.
    n_classes=3)
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpbhg2uvbr
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpbhg2uvbr', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

トレーニング、評価、および予測

Estimatorオブジェクトができたので、メソッドを呼び出して次のことを実行できます。

  • モデルをトレーニングします。
  • トレーニング済みモデルを評価します。
  • トレーニング済みモデルを使用して予測を行います。

モデルをトレーニングする

次のようにEstimatorのtrainメソッドを呼び出して、モデルをtrainします。

# Train the Model.
classifier.train(
    input_fn=lambda: input_fn(train, train_y, training=True),
    steps=5000)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Layer dnn is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/optimizer_v2/adagrad.py:83: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpbhg2uvbr/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 1.1140382, step = 0
INFO:tensorflow:global_step/sec: 312.415
INFO:tensorflow:loss = 0.8781501, step = 100 (0.321 sec)
INFO:tensorflow:global_step/sec: 375.535
INFO:tensorflow:loss = 0.80712265, step = 200 (0.266 sec)
INFO:tensorflow:global_step/sec: 372.712
INFO:tensorflow:loss = 0.7615077, step = 300 (0.268 sec)
INFO:tensorflow:global_step/sec: 368.782
INFO:tensorflow:loss = 0.733555, step = 400 (0.271 sec)
INFO:tensorflow:global_step/sec: 372.689
INFO:tensorflow:loss = 0.6983943, step = 500 (0.268 sec)
INFO:tensorflow:global_step/sec: 370.308
INFO:tensorflow:loss = 0.67940104, step = 600 (0.270 sec)
INFO:tensorflow:global_step/sec: 373.374
INFO:tensorflow:loss = 0.65386146, step = 700 (0.268 sec)
INFO:tensorflow:global_step/sec: 368.335
INFO:tensorflow:loss = 0.63730353, step = 800 (0.272 sec)
INFO:tensorflow:global_step/sec: 371.575
INFO:tensorflow:loss = 0.61313766, step = 900 (0.269 sec)
INFO:tensorflow:global_step/sec: 371.975
INFO:tensorflow:loss = 0.6123625, step = 1000 (0.269 sec)
INFO:tensorflow:global_step/sec: 369.615
INFO:tensorflow:loss = 0.5957534, step = 1100 (0.270 sec)
INFO:tensorflow:global_step/sec: 374.054
INFO:tensorflow:loss = 0.57203, step = 1200 (0.267 sec)
INFO:tensorflow:global_step/sec: 369.713
INFO:tensorflow:loss = 0.56556034, step = 1300 (0.270 sec)
INFO:tensorflow:global_step/sec: 366.202
INFO:tensorflow:loss = 0.547443, step = 1400 (0.273 sec)
INFO:tensorflow:global_step/sec: 361.407
INFO:tensorflow:loss = 0.53326523, step = 1500 (0.277 sec)
INFO:tensorflow:global_step/sec: 367.461
INFO:tensorflow:loss = 0.51837724, step = 1600 (0.272 sec)
INFO:tensorflow:global_step/sec: 364.181
INFO:tensorflow:loss = 0.5281174, step = 1700 (0.275 sec)
INFO:tensorflow:global_step/sec: 368.139
INFO:tensorflow:loss = 0.5139683, step = 1800 (0.271 sec)
INFO:tensorflow:global_step/sec: 366.277
INFO:tensorflow:loss = 0.51073176, step = 1900 (0.273 sec)
INFO:tensorflow:global_step/sec: 366.634
INFO:tensorflow:loss = 0.4949246, step = 2000 (0.273 sec)
INFO:tensorflow:global_step/sec: 364.732
INFO:tensorflow:loss = 0.49381495, step = 2100 (0.274 sec)
INFO:tensorflow:global_step/sec: 365.006
INFO:tensorflow:loss = 0.48916715, step = 2200 (0.274 sec)
INFO:tensorflow:global_step/sec: 366.902
INFO:tensorflow:loss = 0.48790723, step = 2300 (0.273 sec)
INFO:tensorflow:global_step/sec: 362.232
INFO:tensorflow:loss = 0.47671652, step = 2400 (0.276 sec)
INFO:tensorflow:global_step/sec: 368.592
INFO:tensorflow:loss = 0.47324088, step = 2500 (0.271 sec)
INFO:tensorflow:global_step/sec: 371.611
INFO:tensorflow:loss = 0.46822113, step = 2600 (0.269 sec)
INFO:tensorflow:global_step/sec: 362.345
INFO:tensorflow:loss = 0.4621966, step = 2700 (0.276 sec)
INFO:tensorflow:global_step/sec: 362.788
INFO:tensorflow:loss = 0.47817266, step = 2800 (0.275 sec)
INFO:tensorflow:global_step/sec: 368.473
INFO:tensorflow:loss = 0.45853442, step = 2900 (0.271 sec)
INFO:tensorflow:global_step/sec: 360.944
INFO:tensorflow:loss = 0.44062576, step = 3000 (0.277 sec)
INFO:tensorflow:global_step/sec: 370.982
INFO:tensorflow:loss = 0.4331399, step = 3100 (0.269 sec)
INFO:tensorflow:global_step/sec: 366.248
INFO:tensorflow:loss = 0.45120597, step = 3200 (0.273 sec)
INFO:tensorflow:global_step/sec: 371.703
INFO:tensorflow:loss = 0.4403404, step = 3300 (0.269 sec)
INFO:tensorflow:global_step/sec: 362.176
INFO:tensorflow:loss = 0.42405623, step = 3400 (0.276 sec)
INFO:tensorflow:global_step/sec: 363.283
INFO:tensorflow:loss = 0.41672814, step = 3500 (0.275 sec)
INFO:tensorflow:global_step/sec: 363.529
INFO:tensorflow:loss = 0.42626005, step = 3600 (0.275 sec)
INFO:tensorflow:global_step/sec: 367.348
INFO:tensorflow:loss = 0.4089098, step = 3700 (0.272 sec)
INFO:tensorflow:global_step/sec: 363.067
INFO:tensorflow:loss = 0.41276374, step = 3800 (0.275 sec)
INFO:tensorflow:global_step/sec: 364.771
INFO:tensorflow:loss = 0.4112524, step = 3900 (0.274 sec)
INFO:tensorflow:global_step/sec: 363.167
INFO:tensorflow:loss = 0.39261794, step = 4000 (0.275 sec)
INFO:tensorflow:global_step/sec: 362.082
INFO:tensorflow:loss = 0.41160905, step = 4100 (0.276 sec)
INFO:tensorflow:global_step/sec: 364.979
INFO:tensorflow:loss = 0.39620766, step = 4200 (0.274 sec)
INFO:tensorflow:global_step/sec: 363.323
INFO:tensorflow:loss = 0.39696264, step = 4300 (0.275 sec)
INFO:tensorflow:global_step/sec: 361.25
INFO:tensorflow:loss = 0.38196522, step = 4400 (0.277 sec)
INFO:tensorflow:global_step/sec: 365.666
INFO:tensorflow:loss = 0.38667366, step = 4500 (0.274 sec)
INFO:tensorflow:global_step/sec: 361.202
INFO:tensorflow:loss = 0.38149032, step = 4600 (0.277 sec)
INFO:tensorflow:global_step/sec: 365.038
INFO:tensorflow:loss = 0.37832782, step = 4700 (0.274 sec)
INFO:tensorflow:global_step/sec: 366.375
INFO:tensorflow:loss = 0.3726803, step = 4800 (0.273 sec)
INFO:tensorflow:global_step/sec: 366.474
INFO:tensorflow:loss = 0.37167495, step = 4900 (0.273 sec)
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 5000...
INFO:tensorflow:Saving checkpoints for 5000 into /tmp/tmpbhg2uvbr/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 5000...
INFO:tensorflow:Loss for final step: 0.36297452.

<tensorflow_estimator.python.estimator.canned.dnn.DNNClassifierV2 at 0x7fc9983ed470>

Estimatorが期待するように、引数をとらない入力関数を提供しながら、 input_fn呼び出しをlambdaでラップして引数をキャプチャすることに注意してください。 steps引数は、いくつかのトレーニングステップの後にトレーニングを停止する方法を指示します。

トレーニング済みモデルを評価する

モデルがトレーニングされたので、そのパフォーマンスに関するいくつかの統計を取得できます。次のコードブロックは、テストデータでトレーニングされたモデルの精度を評価します。

eval_result = classifier.evaluate(
    input_fn=lambda: input_fn(test, test_y, training=False))

print('\nTest set accuracy: {accuracy:0.3f}\n'.format(**eval_result))
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Layer dnn is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2020-09-10T01:40:47Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpbhg2uvbr/model.ckpt-5000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Inference Time : 0.21153s
INFO:tensorflow:Finished evaluation at 2020-09-10-01:40:47
INFO:tensorflow:Saving dict for global step 5000: accuracy = 0.96666664, average_loss = 0.42594802, global_step = 5000, loss = 0.42594802
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 5000: /tmp/tmpbhg2uvbr/model.ckpt-5000

Test set accuracy: 0.967


trainメソッドの呼び出しとは異なり、評価するためにsteps引数を渡しませんでした。 evalのinput_fnは、データの単一のエポックのみを生成します。

eval_resultディクショナリには、 average_loss (サンプルあたりの平均損失)、 loss (ミニバッチあたりの平均損失)、および推定量のglobal_step値(実行されたトレーニングの反復回数)も含まれています。

訓練されたモデルから予測(推論)を行う

これで、良好な評価結果を生成するトレーニング済みモデルができました。これで、トレーニング済みモデルを使用して、ラベルのない測定値に基づいてアイリスの花の種を予測できます。トレーニングと評価と同様に、単一の関数呼び出しを使用して予測を行います。

# Generate predictions from the model
expected = ['Setosa', 'Versicolor', 'Virginica']
predict_x = {
    'SepalLength': [5.1, 5.9, 6.9],
    'SepalWidth': [3.3, 3.0, 3.1],
    'PetalLength': [1.7, 4.2, 5.4],
    'PetalWidth': [0.5, 1.5, 2.1],
}

def input_fn(features, batch_size=256):
    """An input function for prediction."""
    # Convert the inputs to a Dataset without labels.
    return tf.data.Dataset.from_tensor_slices(dict(features)).batch(batch_size)

predictions = classifier.predict(
    input_fn=lambda: input_fn(predict_x))

predictメソッドはPythonの反復可能オブジェクトを返し、各例の予測結果のディクショナリを生成します。次のコードは、いくつかの予測とその確率を出力します。

for pred_dict, expec in zip(predictions, expected):
    class_id = pred_dict['class_ids'][0]
    probability = pred_dict['probabilities'][class_id]

    print('Prediction is "{}" ({:.1f}%), expected "{}"'.format(
        SPECIES[class_id], 100 * probability, expec))
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpbhg2uvbr/model.ckpt-5000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Prediction is "Setosa" (91.3%), expected "Setosa"
Prediction is "Versicolor" (52.0%), expected "Versicolor"
Prediction is "Virginica" (63.5%), expected "Virginica"