Unisciti alla comunità SIG TFX-Addons e contribuisci a rendere TFX ancora migliore!

Preelaborare i dati con TensorFlow Transform

Il componente di ingegneria 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 le 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 puoi:

  • Normalizza 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 il supporto integrato per le manipolazioni su un singolo esempio o un batch di esempi. tf.Transform estende queste funzionalità per supportare i passaggi completi sull'intero set di dati di addestramento.

L'output di tf.Transform viene esportato come grafico TensorFlow che puoi utilizzare sia per l'addestramento che per la pubblicazione. L'uso 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 di aggiornare Pip in un sistema quando è in esecuzione localmente, assicurati di essere 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==0.24.1

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 preelaboreremo
  • 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 pre-elaborazione

La funzione di pre-elaborazione è il concetto più importante di tf.Transform. Una funzione di pre-elaborazione è dove la trasformazione del set di dati avviene realmente. Accetta e restituisce un dizionario di tensori, dove un tensore significa un Tensor o unoSparseTensor . 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 operazioni TensorFlow. Questi aggiungono operazioni TensorFlow al grafico che trasforma i dati grezzi in dati trasformati un vettore di feature alla volta. Questi funzioneranno per ogni esempio, sia durante l'allenamento che durante il servizio.
  2. Tensorflow Transform Analyzers / Mappers: uno qualsiasi degli analizzatori / mappatori forniti 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 di 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 si trovi entro un intervallo specificato dall'utente, [output_min, output_max]. tf.Transform fornisce un set fisso di tali analizzatori / mappatori, ma 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 non raw_data che abbiamo creato sopra
  2. raw_data_metadata - Lo schema per i dati grezzi
  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:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended.
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:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended.
WARNING:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended.
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:218: 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:218: 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/python/saved_model/signature_def_utils_impl.py:201: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:201: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info.
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:No assets to write.
INFO:tensorflow:No assets to write.
WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
INFO:tensorflow:SavedModel written to: /tmp/tmpyjqmd8zx/tftransform_tmp/a0812edd940447aeb9bd8cca86f19136/saved_model.pb
INFO:tensorflow:SavedModel written to: /tmp/tmpyjqmd8zx/tftransform_tmp/a0812edd940447aeb9bd8cca86f19136/saved_model.pb
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:No assets to write.
INFO:tensorflow:No assets to write.
WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'
INFO:tensorflow:SavedModel written to: /tmp/tmpyjqmd8zx/tftransform_tmp/ec933f1f949d40dbb39bfadf8b963b3f/saved_model.pb
INFO:tensorflow:SavedModel written to: /tmp/tmpyjqmd8zx/tftransform_tmp/ec933f1f949d40dbb39bfadf8b963b3f/saved_model.pb
WARNING:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended.
WARNING:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended.
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: ['/home/kbuilder/.local/lib/python3.7/site-packages/ipykernel_launcher.py', '-f', '/tmp/tmpe_bjh6uw.json', '--HistoryManager.hist_file=:memory:']
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:Assets written to: /tmp/tmpyjqmd8zx/tftransform_tmp/2492704f81904b2e9d2b471e8e67103c/assets
INFO:tensorflow:Assets written to: /tmp/tmpyjqmd8zx/tftransform_tmp/2492704f81904b2e9d2b471e8e67103c/assets
INFO:tensorflow:SavedModel written to: /tmp/tmpyjqmd8zx/tftransform_tmp/2492704f81904b2e9d2b471e8e67103c/saved_model.pb
INFO:tensorflow:SavedModel written to: /tmp/tmpyjqmd8zx/tftransform_tmp/2492704f81904b2e9d2b471e8e67103c/saved_model.pb
WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\013\n\tConst_3:0\022-vocab_compute_and_apply_vocabulary_vocabulary"
WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\013\n\tConst_3:0\022-vocab_compute_and_apply_vocabulary_vocabulary"
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\013\n\tConst_3:0\022-vocab_compute_and_apply_vocabulary_vocabulary"
WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\013\n\tConst_3:0\022-vocab_compute_and_apply_vocabulary_vocabulary"
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
INFO:tensorflow:Saver not created because there are no variables in the graph to restore
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, abbiamo utilizzato 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_centered

Con l'input di [1, 2, 3] la media di x è 2 e la sottraiamo da x per centrare i nostri valori x a 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_integerized

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"] nostro risultato di [0, 1, 0] è corretto. Poiché "ciao" compare più frequentemente in questi dati, sarà la prima voce del vocabolario.

x_centered_times_y_normalized

Volevamo creare una nuova funzionalità incrociando x_centered e y_normalized utilizzando 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.