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:
-
tf.estimator.DNNClassifier
per modelli profondi che eseguono la classificazione multiclasse. -
tf.estimator.DNNLinearCombinedClassifier
per modelli ampi e profondi. -
tf.estimator.LinearClassifier
per classificatori basati su modelli lineari.
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"