Preelabora i dati con TensorFlow Transform

Il componente di progettazione delle funzionalità di TensorFlow Extended (TFX)

Questo esempio di notebook Colab fornisce un esempio molto semplice di come TensorFlow Transform ( tf.Transform ) può essere utilizzato per preelaborare i dati utilizzando esattamente lo stesso codice sia per l'addestramento di un modello che per la fornitura di inferenze in produzione.

TensorFlow Transform è una libreria per la preelaborazione dei dati di input per TensorFlow, inclusa la creazione di funzionalità che richiedono un passaggio completo sul set di dati di addestramento. Ad esempio, utilizzando TensorFlow Transform è possibile:

  • Normalizzare un valore di input utilizzando la media e la deviazione standard
  • Converti le stringhe in numeri interi generando un vocabolario su tutti i valori di input
  • Converti i float in numeri interi assegnandoli a bucket, in base alla distribuzione dei dati osservata

TensorFlow ha un supporto integrato per le manipolazioni su un singolo esempio o su un batch di esempi. tf.Transform estende queste funzionalità per supportare passaggi completi sull'intero set di dati di addestramento.

L'output di tf.Transform viene esportato come un grafico TensorFlow che puoi utilizzare sia per l'addestramento che per il servizio. L'utilizzo dello stesso grafico sia per l'allenamento che per il servizio può prevenire l'inclinazione, poiché le stesse trasformazioni vengono applicate in entrambe le fasi.

Aggiorna Pip

Per evitare l'aggiornamento di Pip in un sistema durante l'esecuzione in locale, verifica che sia in esecuzione in Colab. I sistemi locali possono ovviamente essere aggiornati separatamente.

try:
  import colab
  !pip install --upgrade pip
except:
  pass

Installa TensorFlow Transform

pip install -q -U tensorflow_transform

Hai riavviato il runtime?

Se stai utilizzando Google Colab, la prima volta che esegui la cella sopra, devi riavviare il runtime (Runtime > Riavvia runtime ...). Ciò è dovuto al modo in cui Colab carica i pacchetti.

Importazioni

import pprint
import tempfile

import tensorflow as tf
import tensorflow_transform as tft

import tensorflow_transform.beam as tft_beam
from tensorflow_transform.tf_metadata import dataset_metadata
from tensorflow_transform.tf_metadata import schema_utils

Dati: crea alcuni dati fittizi

Creeremo alcuni semplici dati fittizi per il nostro semplice esempio:

  • raw_data sono i dati grezzi iniziali che andremo a pre-elaborare
  • raw_data_metadata contiene lo schema che ci dice i tipi di ciascuna delle colonne in raw_data . In questo caso è molto semplice.
raw_data = [
      {'x': 1, 'y': 1, 's': 'hello'},
      {'x': 2, 'y': 2, 's': 'world'},
      {'x': 3, 'y': 3, 's': 'hello'}
  ]

raw_data_metadata = dataset_metadata.DatasetMetadata(
    schema_utils.schema_from_feature_spec({
        'y': tf.io.FixedLenFeature([], tf.float32),
        'x': tf.io.FixedLenFeature([], tf.float32),
        's': tf.io.FixedLenFeature([], tf.string),
    }))

Trasforma: crea una funzione di preelaborazione

La funzione di preelaborazione è il concetto più importante di tf.Transform. Una funzione di preelaborazione è dove avviene realmente la trasformazione del set di dati. Accetta e restituisce un dizionario di tensori, dove un tensore significa un Tensor oSparseTensor . Esistono due gruppi principali di chiamate API che in genere costituiscono il cuore di una funzione di preelaborazione:

  1. TensorFlow Ops: qualsiasi funzione che accetta e restituisce tensori, che di solito significa TensorFlow ops. Questi aggiungono operazioni TensorFlow al grafico che trasforma i dati grezzi in dati trasformati un vettore di funzionalità alla volta. Questi verranno eseguiti per ogni esempio, sia durante l'addestramento che durante il servizio.
  2. Analizzatori/mapper di trasformazioni Tensorflow: qualsiasi analizzatore/mapper fornito da tf.Transform. Questi accettano e restituiscono anche tensori e in genere contengono una combinazione di operazioni Tensorflow e calcolo Beam, ma a differenza delle operazioni TensorFlow vengono eseguite solo nella pipeline Beam durante l'analisi che richiede un passaggio completo sull'intero set di dati di addestramento. Il calcolo Beam viene eseguito solo una volta, durante l'addestramento, e in genere esegue un passaggio completo sull'intero set di dati di addestramento. Creano costanti tensoriali, che vengono aggiunte al tuo grafico. Ad esempio, tft.min calcola il minimo di un tensore sul set di dati di addestramento mentre tft.scale_by_min_max calcola prima il minimo e il massimo di un tensore sul set di dati di addestramento e quindi ridimensiona il tensore in modo che rientri in un intervallo specificato dall'utente, [output_min, output_max]. tf.Transform fornisce un set fisso di tali analizzatori/mapper, ma questo verrà esteso nelle versioni future.
def preprocessing_fn(inputs):
    """Preprocess input columns into transformed columns."""
    x = inputs['x']
    y = inputs['y']
    s = inputs['s']
    x_centered = x - tft.mean(x)
    y_normalized = tft.scale_to_0_1(y)
    s_integerized = tft.compute_and_apply_vocabulary(s)
    x_centered_times_y_normalized = (x_centered * y_normalized)
    return {
        'x_centered': x_centered,
        'y_normalized': y_normalized,
        's_integerized': s_integerized,
        'x_centered_times_y_normalized': x_centered_times_y_normalized,
    }

Mettere tutto insieme

Ora siamo pronti per trasformare i nostri dati. Useremo Apache Beam con un corridore diretto e forniremo tre input:

  1. raw_data - I dati di input grezzi che abbiamo creato sopra
  2. raw_data_metadata - Lo schema per i dati non elaborati
  3. preprocessing_fn - La funzione che abbiamo creato per eseguire la nostra trasformazione
def main():
  # Ignore the warnings
  with tft_beam.Context(temp_dir=tempfile.mkdtemp()):
    transformed_dataset, transform_fn = (  # pylint: disable=unused-variable
        (raw_data, raw_data_metadata) | tft_beam.AnalyzeAndTransformDataset(
            preprocessing_fn))

  transformed_data, transformed_metadata = transformed_dataset  # pylint: disable=unused-variable

  print('\nRaw data:\n{}\n'.format(pprint.pformat(raw_data)))
  print('Transformed data:\n{}'.format(pprint.pformat(transformed_data)))

if __name__ == '__main__':
  main()
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:apache_beam.options.pipeline_options:Discarding unparseable args: ['/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py', '-f', '/tmp/tmp8aif_7w8.json', '--HistoryManager.hist_file=:memory:']
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
2022-02-03 10:18:41.378629: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
Raw data:
[{'s': 'hello', 'x': 1, 'y': 1},
 {'s': 'world', 'x': 2, 'y': 2},
 {'s': 'hello', 'x': 3, 'y': 3}]

Transformed data:
[{'s_integerized': 0,
  'x_centered': -1.0,
  'x_centered_times_y_normalized': -0.0,
  'y_normalized': 0.0},
 {'s_integerized': 1,
  'x_centered': 0.0,
  'x_centered_times_y_normalized': 0.0,
  'y_normalized': 0.5},
 {'s_integerized': 0,
  'x_centered': 1.0,
  'x_centered_times_y_normalized': 1.0,
  'y_normalized': 1.0}]

È questa la risposta giusta?

In precedenza, tf.Transform per fare questo:

x_centered = x - tft.mean(x)
y_normalized = tft.scale_to_0_1(y)
s_integerized = tft.compute_and_apply_vocabulary(s)
x_centered_times_y_normalized = (x_centered * y_normalized)

x_centrato

Con l'input di [1, 2, 3] la media di x è 2 e la sottraiamo da x per centrare i nostri valori x su 0. Quindi il nostro risultato di [-1.0, 0.0, 1.0] è corretto.

y_normalizzato

Volevamo scalare i nostri valori y tra 0 e 1. Il nostro input era [1, 2, 3] quindi il nostro risultato di [0.0, 0.5, 1.0] è corretto.

s_integrato

Volevamo mappare le nostre stringhe agli indici in un vocabolario e c'erano solo 2 parole nel nostro vocabolario ("ciao" e "mondo"). Quindi con l'input di ["hello", "world", "hello"] il nostro risultato di [0, 1, 0] è corretto. Poiché "ciao" ricorre più frequentemente in questi dati, sarà la prima voce nel vocabolario.

x_centered_times_y_normalized

Volevamo creare una nuova funzionalità incrociando x_centered e y_normalized usando la moltiplicazione. Nota che questo moltiplica i risultati, non i valori originali, e il nostro nuovo risultato di [-0.0, 0.0, 1.0] è corretto.