TensorFlow 2.x in TFX

TensorFlow 2.0 è stato rilasciato nel 2019 , con una stretta integrazione di Keras , esecuzione entusiasta per impostazione predefinita ed esecuzione di funzioni Python , oltre ad altre nuove funzionalità e miglioramenti .

Questa guida fornisce una panoramica tecnica completa di TF 2.x in TFX.

Quale versione utilizzare?

TFX è compatibile con TensorFlow 2.x e le API di alto livello esistenti in TensorFlow 1.x (in particolare gli Estimatori) continuano a funzionare.

Avvia nuovi progetti in TensorFlow 2.x

Poiché TensorFlow 2.x conserva le funzionalità di alto livello di TensorFlow 1.x, non vi è alcun vantaggio nell'utilizzare la versione precedente su nuovi progetti, anche se non si prevede di utilizzare le nuove funzionalità.

Pertanto, se stai avviando un nuovo progetto TFX, ti consigliamo di utilizzare TensorFlow 2.x. Potresti voler aggiornare il tuo codice in un secondo momento non appena sarà disponibile il supporto completo per Keras e altre nuove funzionalità e l'ambito delle modifiche sarà molto più limitato se inizi con TensorFlow 2.x, anziché tentare di eseguire l'aggiornamento da TensorFlow 1.x in il futuro.

Conversione di progetti esistenti in TensorFlow 2.x

Il codice scritto per TensorFlow 1.x è ampiamente compatibile con TensorFlow 2.x e continuerà a funzionare in TFX.

Tuttavia, se desideri sfruttare i miglioramenti e le nuove funzionalità non appena diventano disponibili in TF 2.x, puoi seguire le istruzioni per la migrazione a TF 2.x.

Estimatore

L'API Estimator è stata mantenuta in TensorFlow 2.x, ma non è al centro di nuove funzionalità e sviluppi. Il codice scritto in TensorFlow 1.x o 2.x utilizzando gli Estimator continuerà a funzionare come previsto in TFX.

Ecco un esempio TFX end-to-end che utilizza lo stimatore puro: Esempio di taxi (stimatore)

Keras con model_to_estimator

I modelli Keras possono essere inseriti nella funzione tf.keras.estimator.model_to_estimator , che consente loro di funzionare come se fossero Estimatori. Per utilizzare questo:

  1. Costruisci un modello Keras.
  2. Passa il modello compilato in model_to_estimator .
  3. Utilizza il risultato di model_to_estimator in Trainer, nel modo in cui utilizzeresti normalmente uno Estimator.
# Build a Keras model.
def _keras_model_builder():
  """Creates a Keras model."""
  ...

  model = tf.keras.Model(inputs=inputs, outputs=output)
  model.compile()

  return model


# Write a typical trainer function
def trainer_fn(trainer_fn_args, schema):
  """Build the estimator, using model_to_estimator."""
  ...

  # Model to estimator
  estimator = tf.keras.estimator.model_to_estimator(
      keras_model=_keras_model_builder(), config=run_config)

  return {
      'estimator': estimator,
      ...
  }

A parte il file del modulo utente di Trainer, il resto della pipeline rimane invariato.

Keras nativo (ovvero Keras senza model_to_estimator )

Esempi e Colab

Ecco alcuni esempi con Keras nativo:

Abbiamo anche un Keras Colab per componente.

Componenti TFX

Le sezioni seguenti spiegano come i componenti TFX correlati supportano Keras nativo.

Trasformare

Transform attualmente dispone del supporto sperimentale per i modelli Keras.

Il componente Trasforma stesso può essere utilizzato per Keras nativo senza modifiche. La definizione preprocessing_fn rimane la stessa, utilizzando le operazioni TensorFlow e tf.Transform .

La funzione di servizio e la funzione di valutazione vengono modificate per Keras nativo. I dettagli saranno discussi nelle seguenti sezioni Formatore e Valutatore.

Allenatore

Per configurare Keras nativo, è necessario impostare GenericExecutor per il componente Trainer per sostituire l'esecutore predefinito basato su Estimator. Per i dettagli, consultare qui .

File del modulo Keras con Trasformazione

Il file del modulo di formazione deve contenere un run_fn che verrà chiamato dal GenericExecutor , un tipico run_fn di Keras sarebbe simile a questo:

def run_fn(fn_args: TrainerFnArgs):
  """Train the model based on given args.

  Args:
    fn_args: Holds args used to train the model as name/value pairs.
  """
  tf_transform_output = tft.TFTransformOutput(fn_args.transform_output)

  # Train and eval files contains transformed examples.
  # _input_fn read dataset based on transformed schema from tft.
  train_dataset = _input_fn(fn_args.train_files, fn_args.data_accessor,
                            tf_transform_output.transformed_metadata.schema)
  eval_dataset = _input_fn(fn_args.eval_files, fn_args.data_accessor,
                           tf_transform_output.transformed_metadata.schema)

  model = _build_keras_model()

  model.fit(
      train_dataset,
      steps_per_epoch=fn_args.train_steps,
      validation_data=eval_dataset,
      validation_steps=fn_args.eval_steps)

  signatures = {
      'serving_default':
          _get_serve_tf_examples_fn(model,
                                    tf_transform_output).get_concrete_function(
                                        tf.TensorSpec(
                                            shape=[None],
                                            dtype=tf.string,
                                            name='examples')),
  }
  model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)

Nel run_fn riportato sopra, è necessaria una firma di servizio quando si esporta il modello addestrato in modo che il modello possa prendere esempi grezzi per la previsione. Una tipica funzione di servizio sarebbe simile a questa:

def _get_serve_tf_examples_fn(model, tf_transform_output):
  """Returns a function that parses a serialized tf.Example."""

  # the layer is added as an attribute to the model in order to make sure that
  # the model assets are handled correctly when exporting.
  model.tft_layer = tf_transform_output.transform_features_layer()

  @tf.function
  def serve_tf_examples_fn(serialized_tf_examples):
    """Returns the output to be used in the serving signature."""
    feature_spec = tf_transform_output.raw_feature_spec()
    feature_spec.pop(_LABEL_KEY)
    parsed_features = tf.io.parse_example(serialized_tf_examples, feature_spec)

    transformed_features = model.tft_layer(parsed_features)

    return model(transformed_features)

  return serve_tf_examples_fn

Nella funzione di servizio precedente, le trasformazioni tf.Transform devono essere applicate ai dati grezzi per l'inferenza, utilizzando il livello tft.TransformFeaturesLayer . Il precedente _serving_input_receiver_fn richiesto per gli Estimatori non sarà più necessario con Keras.

File del modulo Keras senza trasformazione

Questo è simile al file del modulo mostrato sopra, ma senza le trasformazioni:

def _get_serve_tf_examples_fn(model, schema):

  @tf.function
  def serve_tf_examples_fn(serialized_tf_examples):
    feature_spec = _get_raw_feature_spec(schema)
    feature_spec.pop(_LABEL_KEY)
    parsed_features = tf.io.parse_example(serialized_tf_examples, feature_spec)
    return model(parsed_features)

  return serve_tf_examples_fn


def run_fn(fn_args: TrainerFnArgs):
  schema = io_utils.parse_pbtxt_file(fn_args.schema_file, schema_pb2.Schema())

  # Train and eval files contains raw examples.
  # _input_fn reads the dataset based on raw data schema.
  train_dataset = _input_fn(fn_args.train_files, fn_args.data_accessor, schema)
  eval_dataset = _input_fn(fn_args.eval_files, fn_args.data_accessor, schema)

  model = _build_keras_model()

  model.fit(
      train_dataset,
      steps_per_epoch=fn_args.train_steps,
      validation_data=eval_dataset,
      validation_steps=fn_args.eval_steps)

  signatures = {
      'serving_default':
          _get_serve_tf_examples_fn(model, schema).get_concrete_function(
              tf.TensorSpec(shape=[None], dtype=tf.string, name='examples')),
  }
  model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)
tf.distribute.Strategy

Al momento TFX supporta solo strategie per singolo lavoratore (ad esempio, MirroredStrategy , OneDeviceStrategy ).

Per utilizzare una strategia di distribuzione, creare un tf.distribute.Strategy appropriato e spostare la creazione e la compilazione del modello Keras all'interno di un ambito strategico.

Ad esempio, sostituisci sopra model = _build_keras_model() con:

  mirrored_strategy = tf.distribute.MirroredStrategy()
  with mirrored_strategy.scope():
    model = _build_keras_model()

  # Rest of the code can be unchanged.
  model.fit(...)

Per verificare il dispositivo (CPU/GPU) utilizzato da MirroredStrategy , abilitare la registrazione tensorflow del livello informazioni:

import logging
logging.getLogger("tensorflow").setLevel(logging.INFO)

e dovresti essere in grado di vedere Using MirroredStrategy with devices (...) nel registro.

Valutatore

In TFMA v0.2x, ModelValidator e Evaluator sono stati combinati in un unico nuovo componente Evaluator . Il nuovo componente Evaluator può eseguire sia la valutazione del singolo modello sia anche convalidare il modello corrente rispetto ai modelli precedenti. Con questa modifica, il componente Pusher ora consuma un risultato di benedizione da Evaluator invece che da ModelValidator.

Il nuovo Valutatore supporta i modelli Keras così come i modelli Estimatore. Il modello _eval_input_receiver_fn e eval salvato richiesti in precedenza non saranno più necessari con Keras, poiché Evaluator è ora basato sullo stesso SavedModel utilizzato per la pubblicazione.

Vedi Valutatore per ulteriori informazioni .