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

既製の見積もり

TensorFlow.orgで見る Google Colabで実行 GitHubでソースを表示する ノートブックをダウンロード

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

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

まず最初に

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

import tensorflow as tf

import pandas as pd

データセット

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

Irisデータセットを使用してモデルをトレーニングします。 Irisデータセットには、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を使用したプログラミングの概要

データを設定したので、TensorFlow Estimatorを使用してモデルを定義できます。 Estimatorは、 tf.estimator.Estimatorから派生した任意のクラスtf.estimator.Estimator 。 TensorFlowは、一般的なMLアルゴリズムを実装するためのtf.estimator (たとえば、 LinearRegressor )のコレクションを提供します。それ以外に、独自のカスタムEstimatorsを作成できます。始めたばかりの場合は、既成の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のDataset APIの使用をお勧めします。

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

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

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 input_fn呼び出しをラップすることに注意してください。 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方法は、各実施例について、予測結果の辞書を得、反復可能パイソンを返します。次のコードは、いくつかの予測とその確率を出力します。

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"