Se usó la API de Cloud Translation para traducir esta página.
Switch to English

TensorFlow 2.x en TFX

TensorFlow 2.0 se lanzó en 2019 , con una estrecha integración de Keras , una ejecución entusiasta por defecto y la ejecución de la función Pythonic , entre otras nuevas características y mejoras .

Esta guía proporciona una descripción técnica integral de TF 2.x en TFX.

¿Qué versión usar?

TFX es compatible con TensorFlow 2.x, y las API de alto nivel que existían en TensorFlow 1.x (particularmente Estimadores) continúan funcionando.

Iniciar nuevos proyectos en TensorFlow 2.x

Dado que TensorFlow 2.x conserva las capacidades de alto nivel de TensorFlow 1.x, no hay ninguna ventaja en usar la versión anterior en proyectos nuevos, incluso si no planea usar las nuevas funciones.

Por lo tanto, si está comenzando un nuevo proyecto TFX, le recomendamos que utilice TensorFlow 2.x. Es posible que desee actualizar su código más adelante a medida que esté disponible el soporte completo para Keras y otras características nuevas, y el alcance de los cambios será mucho más limitado si comienza con TensorFlow 2.x, en lugar de intentar actualizar desde TensorFlow 1.x en el futuro.

Convertir proyectos existentes a TensorFlow 2.x

El código escrito para TensorFlow 1.x es en gran medida compatible con TensorFlow 2.xy continuará funcionando en TFX.

Sin embargo, si desea aprovechar las mejoras y las nuevas funciones a medida que estén disponibles en TF 2.x, puede seguir las instrucciones para migrar a TF 2.x.

Estimador

La API de Estimator se ha mantenido en TensorFlow 2.x, pero no es el foco de nuevas características y desarrollo. El código escrito en TensorFlow 1.xo 2.x usando Estimadores continuará funcionando como se espera en TFX.

Aquí hay un ejemplo de TFX de extremo a extremo usando el Estimador puro: Ejemplo de taxi (Estimador)

Keras con model_to_estimator

Los modelos Keras se pueden envolver con la función tf.keras.estimator.model_to_estimator , que les permite trabajar como si fueran Estimadores. Para usar esto:

  1. Construye un modelo de Keras.
  2. Pase el modelo compilado a model_to_estimator .
  3. Use el resultado de model_to_estimator en Trainer, de la forma en que normalmente usaría un Estimador.
 # 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,
      ...
  }
 

Aparte del archivo del módulo de usuario de Entrenador, el resto de la tubería permanece sin cambios. Aquí hay un ejemplo de TFX de extremo a extremo utilizando Keras con model_to_estimator: ejemplo de Iris (model_to_estimator)

Keras nativas (es decir, Keras sin model_to_estimator )

Ejemplos y Colab

Aquí hay varios ejemplos con Keras nativos:

También tenemos un Keras Colab por componente.

Componentes TFX

Las siguientes secciones explican cómo los componentes TFX relacionados admiten Keras nativos.

Transformar

Transform actualmente tiene soporte experimental para los modelos Keras.

El componente Transform en sí mismo se puede usar para Keras nativas sin cambios. La definición preprocessing_fn sigue siendo la misma, utilizando TensorFlow y tf.Transform ops.

La función de servicio y la función de evaluación se cambian para Keras nativas. Los detalles se discutirán en las siguientes secciones de Entrenador y Evaluador.

Entrenador

Para configurar Keras nativas, el GenericExecutor debe configurarse para que el componente Entrenador reemplace al ejecutor predeterminado basado en el Estimador. Para más detalles, consulte aquí .

Archivo del Módulo Keras con Transformar

El archivo del módulo de entrenamiento debe contener un run_fn que será llamado por el GenericExecutor , un Keras run_fn típico se vería así:

 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 feature_spec from tft.
  train_dataset = _input_fn(fn_args.train_files, tf_transform_output, 40)
  eval_dataset = _input_fn(fn_args.eval_files, tf_transform_output, 40)

  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)
 

En el run_fn anterior, se necesita una firma de publicación al exportar el modelo entrenado para que ese modelo pueda tomar ejemplos sin procesar para la predicción. Una función de servicio típica se vería así:

 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
 

En la función de servicio anterior, las transformaciones tf.Transform deben aplicarse a los datos sin procesar para inferencia, utilizando la capa tft.TransformFeaturesLayer . El _serving_input_receiver_fn anterior que se requería para los Estimadores ya no será necesario con Keras.

Archivo de módulo de Keras sin transformación

Esto es similar al archivo de módulo que se muestra arriba, pero sin las transformaciones:

 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 feature_spec from schema.
  train_dataset = _input_fn(fn_args.train_files, schema, 40)
  eval_dataset = _input_fn(fn_args.eval_files, schema, 40)

  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

En este momento, TFX solo admite estrategias de un solo trabajador (por ejemplo, MirroredStrategy , OneDeviceStrategy ).

Para usar una estrategia de distribución, cree una estrategia tf.distribute.Strategy adecuada y mueva la creación y compilación del modelo Keras dentro del alcance de una estrategia.

Por ejemplo, reemplace el model = _build_keras_model() anterior 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(...)
 

Para verificar el dispositivo (CPU / GPU) utilizado por MirroredStrategy , habilite el registro de flujo de tensor de nivel de información:

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

y debería poder ver Using MirroredStrategy with devices (...) en el registro.

Evaluador

En TFMA v0.2x, ModelValidator y Evaluator se han combinado en un solo componente nuevo de Evaluator . El nuevo componente Evaluador puede realizar evaluaciones de un solo modelo y también validar el modelo actual en comparación con los modelos anteriores. Con este cambio, el componente Pusher ahora consume un resultado de bendición del Evaluador en lugar de ModelValidator.

El nuevo Evaluador admite los modelos Keras y los modelos Estimator. Los _eval_input_receiver_fn guardados _eval_input_receiver_fn y eval que se requerían anteriormente ya no serán necesarios con Keras, ya que Evaluator ahora se basa en el mismo SavedModel que se utiliza para servir.

Ver Evaluador para más información .