Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Estimadores prediseñados

Ver en TensorFlow.org Ejecutar en Google Colab Ver fuente en GitHub Descargar cuaderno

Este instructivo le muestra cómo resolver el problema de clasificación de iris en TensorFlow usando Estimators. Un estimador es la representación de alto nivel de TensorFlow de un modelo completo y se ha diseñado para facilitar el escalado y el entrenamiento asincrónico. Para obtener más detalles, consulte Estimadores .

Tenga en cuenta que en TensorFlow 2.0, la API de Keras puede realizar muchas de estas mismas tareas y se cree que es una API más fácil de aprender. Si está comenzando de nuevo, le recomendamos que comience con Keras. Para obtener más información sobre las API de alto nivel disponibles en TensorFlow 2.0, consulte Estandarización en Keras .

Lo primero es lo primero

Para comenzar, primero importará TensorFlow y una serie de bibliotecas que necesitará.

import tensorflow as tf

import pandas as pd

El conjunto de datos

El programa de muestra de este documento crea y prueba un modelo que clasifica las flores de Iris en tres especies diferentes según el tamaño de sus sépalos y pétalos .

Entrenarás un modelo usando el conjunto de datos Iris. El conjunto de datos Iris contiene cuatro características y una etiqueta . Las cuatro características identifican las siguientes características botánicas de las flores de Iris individuales:

  • longitud del sépalo
  • ancho del sépalo
  • longitud del pétalo
  • ancho de pétalo

Con base en esta información, puede definir algunas constantes útiles para analizar los datos:

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

A continuación, descargue y analice el conjunto de datos de Iris utilizando Keras y Pandas. Tenga en cuenta que mantiene distintos conjuntos de datos para entrenamiento y pruebas.

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)

Puede inspeccionar sus datos para ver que tiene cuatro columnas de características flotantes y una etiqueta int32.

train.head()

Para cada uno de los conjuntos de datos, divida las etiquetas, que el modelo será entrenado para predecir.

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

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

Descripción general de la programación con estimadores

Ahora que tiene los datos configurados, puede definir un modelo con un Estimador de TensorFlow. Un estimador es cualquier clase derivada de tf.estimator.Estimator . TensorFlow proporciona una colección de tf.estimator (por ejemplo, LinearRegressor ) para implementar algoritmos de LinearRegressor comunes. Más allá de eso, puede escribir sus propios estimadores personalizados . Recomendamos utilizar Estimadores prefabricados cuando recién comienza.

Para escribir un programa de TensorFlow basado en Estimadores prediseñados, debe realizar las siguientes tareas:

  • Cree una o más funciones de entrada.
  • Defina las columnas de características del modelo.
  • Cree una instancia de un Estimador, especificando las columnas de características y varios hiperparámetros.
  • Llame a uno o más métodos en el objeto Estimator, pasando la función de entrada adecuada como fuente de los datos.

Veamos cómo se implementan esas tareas para la clasificación Iris.

Crear funciones de entrada

Debe crear funciones de entrada para proporcionar datos para el entrenamiento, la evaluación y la predicción.

Una función de entrada es una función que devuelve un objetotf.data.Dataset que genera la siguiente tupla de dos elementos:

  • features : un diccionario de Python en el que:
    • Cada tecla es el nombre de una función.
    • Cada valor es una matriz que contiene todos los valores de esa característica.
  • label : una matriz que contiene los valores de la etiqueta para cada ejemplo.

Solo para demostrar el formato de la función de entrada, aquí hay una implementación simple:

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

Su función de entrada puede generar el diccionario de features y la lista de label forma que desee. Sin embargo, recomendamos usar la API de conjunto de datos de TensorFlow, que puede analizar todo tipo de datos.

La API de conjunto de datos puede manejar muchos casos comunes por usted. Por ejemplo, con la API de conjunto de datos, puede leer fácilmente los registros de una gran colección de archivos en paralelo y unirlos en una sola secuencia.

Para simplificar las cosas en este ejemplo, cargará los datos con pandas y creará una canalización de entrada a partir de estos datos en memoria:

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)

Definir las columnas de características

Una columna de características es un objeto que describe cómo el modelo debe utilizar los datos de entrada sin procesar del diccionario de características. Cuando crea un modelo de Estimator, le pasa una lista de columnas de características que describe cada una de las características que desea que utilice el modelo. El módulo tf.feature_column proporciona muchas opciones para representar datos en el modelo.

Para Iris, las 4 características sin procesar son valores numéricos, por lo que crearemos una lista de columnas de características para indicarle al modelo Estimator que represente cada una de las cuatro características como valores de punto flotante de 32 bits. Por lo tanto, el código para crear la columna de características es:

# 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))

Las columnas de funciones pueden ser mucho más sofisticadas que las que mostramos aquí. Puede leer más sobre las columnas de funciones en esta guía .

Ahora que tiene la descripción de cómo desea que el modelo represente las características sin procesar, puede construir el estimador.

Crear una instancia de un estimador

El problema del Iris es un problema de clasificación clásico. Afortunadamente, TensorFlow proporciona varios estimadores de clasificadores prefabricados, que incluyen:

Para el problema de Iris, tf.estimator.DNNClassifier parece ser la mejor opción. Así es como creó una instancia de este Estimador:

# 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}

Entrenar, evaluar y predecir

Ahora que tiene un objeto Estimator, puede llamar a métodos para hacer lo siguiente:

  • Entrena al modelo.
  • Evalúe el modelo entrenado.
  • Utilice el modelo entrenado para hacer predicciones.

Entrena el modelo

Entrene el modelo llamando al método de train del Estimador de la siguiente manera:

# 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>

Tenga en cuenta que envuelve su llamada input_fn en un lambda para capturar los argumentos mientras proporciona una función de entrada que no toma argumentos, como esperaba el Estimador. El argumento de steps le dice al método que detenga el entrenamiento después de varios pasos de entrenamiento.

Evaluar el modelo entrenado

Ahora que se ha entrenado el modelo, puede obtener algunas estadísticas sobre su rendimiento. El siguiente bloque de código evalúa la precisión del modelo entrenado en los datos de prueba:

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


A diferencia de la llamada al método train , no pasó el argumento de steps para evaluar. input_fn para eval solo produce una única época de datos.

El diccionario eval_result también contiene average_loss (pérdida media por muestra), la loss ( loss media por mini-lote) y el valor del global_step del estimador (el número de iteraciones de entrenamiento que experimentó).

Hacer predicciones (inferir) a partir del modelo entrenado

Ahora tiene un modelo entrenado que produce buenos resultados de evaluación. Ahora puede utilizar el modelo entrenado para predecir la especie de una flor de Iris basándose en algunas medidas sin etiquetar. Al igual que con el entrenamiento y la evaluación, realiza predicciones utilizando una única llamada de función:

# 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))

El método de predict devuelve un iterable de Python, produciendo un diccionario de resultados de predicción para cada ejemplo. El siguiente código imprime algunas predicciones y sus probabilidades:

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"