Stimatori Premade

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza l'origine su GitHub Scarica quaderno

Questo tutorial mostra come risolvere il problema di classificazione dell'iride in TensorFlow utilizzando gli stimatori. Uno stimatore è una rappresentazione di alto livello TensorFlow legacy di un modello completo. Per maggiori dettagli vedere Stimatori .

Cominciando dall'inizio

Per iniziare, importerai prima TensorFlow e una serie di librerie di cui avrai bisogno.

import tensorflow as tf

import pandas as pd

Il set di dati

Il programma di esempio in questo documento costruisce e testa un modello che classifica i fiori di Iris in tre specie diverse in base alle dimensioni dei loro sepali e petali .

Addestrerai un modello utilizzando il set di dati Iris. Il set di dati Iris contiene quattro funzioni e un'etichetta . Le quattro caratteristiche identificano le seguenti caratteristiche botaniche dei singoli fiori di Iris:

  • lunghezza del sepalo
  • larghezza del sepalo
  • lunghezza del petalo
  • larghezza del petalo

Sulla base di queste informazioni, è possibile definire alcune costanti utili per l'analisi dei dati:

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

Quindi, scarica e analizza il set di dati Iris utilizzando Keras e Pandas. Tieni presente che mantieni set di dati distinti per l'addestramento e il test.

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)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv
16384/2194 [================================================================================================================================================================================================================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv
16384/573 [=========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================] - 0s 0us/step

Puoi esaminare i tuoi dati per vedere che hai quattro colonne di funzionalità float e un'etichetta int32.

train.head()

Per ciascuno dei set di dati, suddividi le etichette, che il modello verrà addestrato a prevedere.

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

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

Panoramica della programmazione con Estimatori

Ora che hai impostato i dati, puoi definire un modello utilizzando un TensorFlow Estimator. Uno stimatore è qualsiasi classe derivata da tf.estimator.Estimator . TensorFlow fornisce una raccolta di tf.estimator (ad esempio, LinearRegressor ) per implementare algoritmi ML comuni. Oltre a questi, puoi scrivere i tuoi stimatori personalizzati . Si consiglia di utilizzare stimatori predefiniti all'inizio.

Per scrivere un programma TensorFlow basato su stimatori predefiniti, è necessario eseguire le seguenti attività:

  • Crea una o più funzioni di input.
  • Definire le colonne delle caratteristiche del modello.
  • Istanziare uno stimatore, specificando le colonne delle caratteristiche e vari iperparametri.
  • Chiama uno o più metodi sull'oggetto Estimator, passando la funzione di input appropriata come origine dei dati.

Vediamo come vengono implementate queste attività per la classificazione dell'iride.

Crea funzioni di input

È necessario creare funzioni di input per fornire dati per l'addestramento, la valutazione e la previsione.

Una funzione di input è una funzione che restituisce un oggetto tf.data.Dataset che restituisce la seguente tupla a due elementi:

  • features - Un dizionario Python in cui:
    • Ogni chiave è il nome di una caratteristica.
    • Ogni valore è una matrice contenente tutti i valori di quella caratteristica.
  • label - Una matrice contenente i valori dell'etichetta per ogni esempio.

Solo per dimostrare il formato della funzione di input, ecco una semplice implementazione:

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

La tua funzione di input può generare il dizionario delle features e l'elenco delle label in qualsiasi modo desideri. Tuttavia, si consiglia di utilizzare l' API del set di dati di TensorFlow, che può analizzare tutti i tipi di dati.

L'API del set di dati può gestire molti casi comuni per te. Ad esempio, utilizzando l'API del set di dati, puoi facilmente leggere i record da un'ampia raccolta di file in parallelo e unirli in un unico flusso.

Per semplificare le cose, in questo esempio caricherai i dati con pandas e costruirai una pipeline di input da questi dati in 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)

Definisci le colonne delle caratteristiche

Una colonna di funzionalità è un oggetto che descrive come il modello dovrebbe utilizzare i dati di input grezzi dal dizionario delle funzionalità. Quando crei un modello Estimator, gli passi un elenco di colonne di funzionalità che descrivono ciascuna delle funzionalità che desideri venga utilizzata dal modello. Il modulo tf.feature_column fornisce molte opzioni per rappresentare i dati nel modello.

Per Iris, le 4 feature grezze sono valori numerici, quindi creerai un elenco di colonne di feature per indicare al modello Estimator di rappresentare ciascuna delle quattro feature come valori a virgola mobile a 32 bit. Pertanto, il codice per creare la colonna caratteristica è:

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

Le colonne delle funzionalità possono essere molto più sofisticate di quelle mostrate qui. Puoi leggere ulteriori informazioni sulle colonne delle funzionalità in questa guida .

Ora che hai la descrizione di come vuoi che il modello rappresenti le caratteristiche grezze, puoi costruire lo stimatore.

Istanziare uno stimatore

Il problema dell'iride è un classico problema di classificazione. Fortunatamente, TensorFlow fornisce diversi stimatori di classificatori predefiniti, tra cui:

Per il problema dell'iride, tf.estimator.DNNClassifier sembra la scelta migliore. Ecco come hai creato un'istanza di questo stimatore:

# 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/tmpxdgumb2t
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpxdgumb2t', '_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, '_checkpoint_save_graph_def': True, '_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}

Addestrare, valutare e prevedere

Ora che hai un oggetto Estimator, puoi chiamare i metodi per eseguire le seguenti operazioni:

  • Allena il modello.
  • Valuta il modello addestrato.
  • Usa il modello addestrato per fare previsioni.

Allena il modello

Addestra il modello chiamando il metodo del train di Estimator come segue:

# 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.7/site-packages/tensorflow/python/training/training_util.py:397: 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:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/optimizer_v2/adagrad.py:84: 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/tmpxdgumb2t/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 1.6787335, step = 0
INFO:tensorflow:global_step/sec: 305.625
INFO:tensorflow:loss = 1.1945828, step = 100 (0.328 sec)
INFO:tensorflow:global_step/sec: 375.48
INFO:tensorflow:loss = 1.0221117, step = 200 (0.266 sec)
INFO:tensorflow:global_step/sec: 376.21
INFO:tensorflow:loss = 0.9240805, step = 300 (0.266 sec)
INFO:tensorflow:global_step/sec: 377.968
INFO:tensorflow:loss = 0.85917354, step = 400 (0.265 sec)
INFO:tensorflow:global_step/sec: 376.297
INFO:tensorflow:loss = 0.81545967, step = 500 (0.265 sec)
INFO:tensorflow:global_step/sec: 367.549
INFO:tensorflow:loss = 0.7771524, step = 600 (0.272 sec)
INFO:tensorflow:global_step/sec: 378.887
INFO:tensorflow:loss = 0.74371505, step = 700 (0.264 sec)
INFO:tensorflow:global_step/sec: 379.26
INFO:tensorflow:loss = 0.717993, step = 800 (0.264 sec)
INFO:tensorflow:global_step/sec: 370.102
INFO:tensorflow:loss = 0.6952705, step = 900 (0.270 sec)
INFO:tensorflow:global_step/sec: 373.034
INFO:tensorflow:loss = 0.68044865, step = 1000 (0.268 sec)
INFO:tensorflow:global_step/sec: 372.193
INFO:tensorflow:loss = 0.65181077, step = 1100 (0.269 sec)
INFO:tensorflow:global_step/sec: 339.238
INFO:tensorflow:loss = 0.6319051, step = 1200 (0.295 sec)
INFO:tensorflow:global_step/sec: 334.252
INFO:tensorflow:loss = 0.63433766, step = 1300 (0.299 sec)
INFO:tensorflow:global_step/sec: 343.436
INFO:tensorflow:loss = 0.61748827, step = 1400 (0.291 sec)
INFO:tensorflow:global_step/sec: 346.575
INFO:tensorflow:loss = 0.606356, step = 1500 (0.288 sec)
INFO:tensorflow:global_step/sec: 351.362
INFO:tensorflow:loss = 0.59807724, step = 1600 (0.285 sec)
INFO:tensorflow:global_step/sec: 366.628
INFO:tensorflow:loss = 0.5832784, step = 1700 (0.273 sec)
INFO:tensorflow:global_step/sec: 367.034
INFO:tensorflow:loss = 0.5664347, step = 1800 (0.273 sec)
INFO:tensorflow:global_step/sec: 372.339
INFO:tensorflow:loss = 0.5684726, step = 1900 (0.268 sec)
INFO:tensorflow:global_step/sec: 368.957
INFO:tensorflow:loss = 0.56011164, step = 2000 (0.271 sec)
INFO:tensorflow:global_step/sec: 373.128
INFO:tensorflow:loss = 0.5483226, step = 2100 (0.268 sec)
INFO:tensorflow:global_step/sec: 377.334
INFO:tensorflow:loss = 0.5447233, step = 2200 (0.265 sec)
INFO:tensorflow:global_step/sec: 370.421
INFO:tensorflow:loss = 0.5358016, step = 2300 (0.270 sec)
INFO:tensorflow:global_step/sec: 367.076
INFO:tensorflow:loss = 0.53145075, step = 2400 (0.273 sec)
INFO:tensorflow:global_step/sec: 373.596
INFO:tensorflow:loss = 0.50931674, step = 2500 (0.268 sec)
INFO:tensorflow:global_step/sec: 368.939
INFO:tensorflow:loss = 0.5253717, step = 2600 (0.271 sec)
INFO:tensorflow:global_step/sec: 354.814
INFO:tensorflow:loss = 0.52558273, step = 2700 (0.282 sec)
INFO:tensorflow:global_step/sec: 372.243
INFO:tensorflow:loss = 0.51422054, step = 2800 (0.269 sec)
INFO:tensorflow:global_step/sec: 366.891
INFO:tensorflow:loss = 0.49747026, step = 2900 (0.272 sec)
INFO:tensorflow:global_step/sec: 370.952
INFO:tensorflow:loss = 0.49974674, step = 3000 (0.270 sec)
INFO:tensorflow:global_step/sec: 364.158
INFO:tensorflow:loss = 0.4978399, step = 3100 (0.275 sec)
INFO:tensorflow:global_step/sec: 365.383
INFO:tensorflow:loss = 0.5030147, step = 3200 (0.273 sec)
INFO:tensorflow:global_step/sec: 366.791
INFO:tensorflow:loss = 0.4772169, step = 3300 (0.273 sec)
INFO:tensorflow:global_step/sec: 372.438
INFO:tensorflow:loss = 0.46993533, step = 3400 (0.269 sec)
INFO:tensorflow:global_step/sec: 371.25
INFO:tensorflow:loss = 0.47242266, step = 3500 (0.269 sec)
INFO:tensorflow:global_step/sec: 369.725
INFO:tensorflow:loss = 0.46513358, step = 3600 (0.271 sec)
INFO:tensorflow:global_step/sec: 371.002
INFO:tensorflow:loss = 0.4762191, step = 3700 (0.270 sec)
INFO:tensorflow:global_step/sec: 369.304
INFO:tensorflow:loss = 0.44923267, step = 3800 (0.271 sec)
INFO:tensorflow:global_step/sec: 369.344
INFO:tensorflow:loss = 0.45467538, step = 3900 (0.271 sec)
INFO:tensorflow:global_step/sec: 375.58
INFO:tensorflow:loss = 0.46056622, step = 4000 (0.266 sec)
INFO:tensorflow:global_step/sec: 347.461
INFO:tensorflow:loss = 0.4489282, step = 4100 (0.288 sec)
INFO:tensorflow:global_step/sec: 368.435
INFO:tensorflow:loss = 0.45647347, step = 4200 (0.272 sec)
INFO:tensorflow:global_step/sec: 369.159
INFO:tensorflow:loss = 0.4444633, step = 4300 (0.271 sec)
INFO:tensorflow:global_step/sec: 371.995
INFO:tensorflow:loss = 0.44425523, step = 4400 (0.269 sec)
INFO:tensorflow:global_step/sec: 373.586
INFO:tensorflow:loss = 0.44025964, step = 4500 (0.268 sec)
INFO:tensorflow:global_step/sec: 373.136
INFO:tensorflow:loss = 0.44341013, step = 4600 (0.269 sec)
INFO:tensorflow:global_step/sec: 369.751
INFO:tensorflow:loss = 0.42856425, step = 4700 (0.269 sec)
INFO:tensorflow:global_step/sec: 364.219
INFO:tensorflow:loss = 0.44144967, step = 4800 (0.275 sec)
INFO:tensorflow:global_step/sec: 372.675
INFO:tensorflow:loss = 0.42951846, step = 4900 (0.268 sec)
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 5000...
INFO:tensorflow:Saving checkpoints for 5000 into /tmp/tmpxdgumb2t/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 5000...
INFO:tensorflow:Loss for final step: 0.42713496.
<tensorflow_estimator.python.estimator.canned.dnn.DNNClassifierV2 at 0x7fad05e33910>

Nota che avvolgi la tua chiamata input_fn in una lambda per acquisire gli argomenti fornendo al contempo una funzione di input che non accetta argomenti, come previsto da Estimator. L'argomento steps indica al metodo di interrompere l'allenamento dopo un certo numero di passaggi di addestramento.

Valuta il modello addestrato

Ora che il modello è stato addestrato, puoi ottenere alcune statistiche sulle sue prestazioni. Il blocco di codice seguente valuta l'accuratezza del modello addestrato sui dati di test:

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.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2022-01-26T06:41:28
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpxdgumb2t/model.ckpt-5000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Inference Time : 0.40087s
INFO:tensorflow:Finished evaluation at 2022-01-26-06:41:28
INFO:tensorflow:Saving dict for global step 5000: accuracy = 0.8666667, average_loss = 0.49953422, global_step = 5000, loss = 0.49953422
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 5000: /tmp/tmpxdgumb2t/model.ckpt-5000

Test set accuracy: 0.867

A differenza della chiamata al metodo train , non hai passato l'argomento steps da valutare. input_fn per eval restituisce solo una singola epoca di dati.

Il dizionario eval_result contiene anche la average_loss (perdita media per campione), la loss (perdita media per mini-batch) e il valore del global_step dello stimatore (il numero di iterazioni di addestramento a cui è stato sottoposto).

Fare previsioni (inferire) dal modello addestrato

Ora hai un modello addestrato che produce buoni risultati di valutazione. È ora possibile utilizzare il modello addestrato per prevedere la specie di un fiore di iris sulla base di alcune misurazioni senza etichetta. Come per l'addestramento e la valutazione, si effettuano previsioni utilizzando un'unica chiamata di funzione:

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

Il metodo predict restituisce un iterabile Python, fornendo un dizionario di risultati di previsione per ogni esempio. Il codice seguente stampa alcune previsioni e le relative probabilità:

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/tmpxdgumb2t/model.ckpt-5000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Prediction is "Setosa" (84.4%), expected "Setosa"
Prediction is "Versicolor" (49.3%), expected "Versicolor"
Prediction is "Virginica" (57.7%), expected "Virginica"