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

El componente Transform TFX Pipeline

El componente de canalización Transform TFX realiza ingeniería de características en tf.Examples emitidos desde un componente ExampleGen , utilizando un esquema de datos creado por un componente SchemaGen , y emite un modelo guardado. Cuando se ejecuta, SavedModel aceptará tf.Examples emitidos desde un componente ExampleGen y emitirá los datos de características transformados.

  • Consume: tf. Ejemplos de un componente ExampleGen y un esquema de datos de un componente SchemaGen.
  • Emite: un modelo guardado a un componente de entrenador

Configurar un componente de transformación

Una vez que se escribe su preprocessing_fn , debe definirse en un módulo de Python que luego se proporciona al componente Transform como entrada. Este módulo se cargará mediante transform y la función denominada preprocessing_fn será encontrada y utilizada por Transform para construir la canalización de preprocesamiento.

transform_training = components.Transform(
    examples=examples_gen.outputs['training_examples'],
    schema=infer_schema.outputs['schema'],
    module_file=taxi_pipeline_utils,
    name='transform-training')

transform_eval = components.Transform(
    examples=examples_gen.outputs['eval_examples'],
    schema=infer_schema.outputs['schema'],
    transform_dir=transform_training.outputs['output'],
    name='transform-eval')

Transform y TensorFlow Transform

Transform hace un uso extensivo de TensorFlow Transform para realizar ingeniería de funciones en su conjunto de datos. TensorFlow Transform es una gran herramienta para transformar datos de características antes de que vayan a su modelo y como parte del proceso de entrenamiento. Las transformaciones de características comunes incluyen:

  • Incrustación : conversión de características dispersas (como los ID enteros producidos por un vocabulario) en características densas al encontrar un mapeo significativo desde el espacio de alta dimensión al espacio de baja dimensión. Consulte la unidad Embeddings en el curso intensivo de aprendizaje automático para obtener una introducción a los embeddings.
  • Generación de vocabulario : conversión de cadenas u otras características no numéricas en números enteros mediante la creación de un vocabulario que asigna cada valor único a un número de identificación.
  • Normalizar valores : transformar características numéricas para que todas caigan dentro de un rango similar.
  • Bucketización : conversión de características de valor continuo en características categóricas mediante la asignación de valores a cubos discretos.
  • Enriquecimiento de características de texto : producción de características a partir de datos sin procesar como tokens, n-gramas, entidades, sentimiento, etc., para enriquecer el conjunto de características.

TensorFlow Transform proporciona compatibilidad con estos y muchos otros tipos de transformaciones:

  • Genere automáticamente un vocabulario a partir de sus datos más recientes.

  • Realice transformaciones arbitrarias en sus datos antes de enviarlos a su modelo. TensorFlow Transform crea transformaciones en el gráfico de TensorFlow para tu modelo, por lo que se realizan las mismas transformaciones en el momento de la inferencia y el entrenamiento. Puede definir transformaciones que hagan referencia a propiedades globales de los datos, como el valor máximo de una característica en todas las instancias de entrenamiento.

Puede transformar sus datos como desee antes de ejecutar TFX. Pero si lo haces dentro de TensorFlow Transform, las transformaciones pasan a formar parte del gráfico de TensorFlow. Este enfoque ayuda a evitar el sesgo de entrenamiento / servicio.

Las transformaciones dentro de su código de modelado utilizan FeatureColumns. Con FeatureColumns, puede definir agrupaciones, integerizaciones que usan vocabularios predefinidos o cualquier otra transformación que se pueda definir sin mirar los datos.

Por el contrario, TensorFlow Transform está diseñado para transformaciones que requieren un pase completo sobre los datos para calcular valores que no se conocen de antemano. Por ejemplo, la generación de vocabulario requiere un pase completo sobre los datos.

Además de calcular valores con Apache Beam, TensorFlow Transform permite a los usuarios insertar estos valores en un gráfico de TensorFlow, que luego se puede cargar en el gráfico de entrenamiento. Por ejemplo, al normalizar características, la función tft.scale_to_z_score calculará la media y la desviación estándar de una característica, y también una representación, en un gráfico de TensorFlow, de la función que resta la media y divide por la desviación estándar. Al emitir un gráfico de TensorFlow, no solo estadísticas, TensorFlow Transform simplifica el proceso de creación de su canalización de preprocesamiento.

Dado que el preprocesamiento se expresa como un gráfico, puede ocurrir en el servidor y se garantiza que será coherente entre el entrenamiento y el servicio. Esta consistencia elimina una fuente de sesgo de entrenamiento / servicio.

TensorFlow Transform permite a los usuarios especificar su canalización de preprocesamiento mediante el código de TensorFlow. Esto significa que una canalización se construye de la misma manera que un gráfico de TensorFlow. Si solo se usaran operaciones de TensorFlow en este gráfico, la canalización sería un mapa puro que acepta lotes de entrada y devuelve lotes de salida. Tal canalización sería equivalente a colocar este gráfico dentro de su input_fn cuando usa la API tf.Estimator . Para especificar operaciones de paso completo, como calcular cuantiles, TensorFlow Transform proporciona funciones especiales llamadas analyzers que aparecen como operaciones de TensorFlow, pero de hecho especifican un cálculo diferido que realizará Apache Beam y la salida se insertará en el gráfico como un constante. Mientras que una operación de TensorFlow ordinaria tomará un solo lote como entrada, realizará algunos cálculos solo en ese lote y emitirá un lote, un analyzer realizará una reducción global (implementada en Apache Beam) en todos los lotes y devolverá el resultado.

Al combinar las operaciones ordinarias de TensorFlow y los analizadores de transformación de TensorFlow, los usuarios pueden crear canalizaciones complejas para preprocesar sus datos. Por ejemplo, la función tft.scale_to_z_score toma un tensor de entrada y devuelve ese tensor normalizado para tener media 0 y varianza 1 . Lo hace llamando a los analizadores de mean y var bajo el capó, que generarán efectivamente constantes en el gráfico iguales a la media y la varianza del tensor de entrada. Luego utilizará las operaciones de TensorFlow para restar la media y dividir por la desviación estándar.

La transformación de TensorFlow preprocessing_fn

El componente TFX Transform simplifica el uso de Transform al manejar las llamadas a la API relacionadas con la lectura y escritura de datos y al escribir la salida SavedModel en el disco. Como usuario de TFX, solo tiene que definir una única función llamada preprocessing_fn . En preprocessing_fn se define una serie de funciones que manipulan el dictado de entrada de tensores para producir el dictado de salida de tensores. Puede encontrar funciones auxiliares como scale_to_0_1 y compute_and_apply_vocabulary en la API de transformación de TensorFlow o usar funciones regulares de TensorFlow como se muestra a continuación.

def preprocessing_fn(inputs):
  """tf.transform's callback function for preprocessing inputs.

  Args:
    inputs: map from feature keys to raw not-yet-transformed features.

  Returns:
    Map from string feature key to transformed feature operations.
  """
  outputs = {}
  for key in _DENSE_FLOAT_FEATURE_KEYS:
    # Preserve this feature as a dense float, setting nan's to the mean.
    outputs[_transformed_name(key)] = transform.scale_to_z_score(
        _fill_in_missing(inputs[key]))

  for key in _VOCAB_FEATURE_KEYS:
    # Build a vocabulary for this feature.
    outputs[_transformed_name(
        key)] = transform.compute_and_apply_vocabulary(
            _fill_in_missing(inputs[key]),
            top_k=_VOCAB_SIZE,
            num_oov_buckets=_OOV_SIZE)

  for key in _BUCKET_FEATURE_KEYS:
    outputs[_transformed_name(key)] = transform.bucketize(
        _fill_in_missing(inputs[key]), _FEATURE_BUCKET_COUNT)

  for key in _CATEGORICAL_FEATURE_KEYS:
    outputs[_transformed_name(key)] = _fill_in_missing(inputs[key])

  # Was this passenger a big tipper?
  taxi_fare = _fill_in_missing(inputs[_FARE_KEY])
  tips = _fill_in_missing(inputs[_LABEL_KEY])
  outputs[_transformed_name(_LABEL_KEY)] = tf.where(
      tf.is_nan(taxi_fare),
      tf.cast(tf.zeros_like(taxi_fare), tf.int64),
      # Test if the tip was > 20% of the fare.
      tf.cast(
          tf.greater(tips, tf.multiply(taxi_fare, tf.constant(0.2))), tf.int64))

  return outputs

Comprender las entradas de preprocessing_fn

preprocessing_fn describe una serie de operaciones en tensores (es decir, Tensor s o SparseTensor s) y, por lo tanto, para escribir preprocessing_fn correctamente es necesario comprender cómo se representan sus datos como tensores. La entrada a preprocessing_fn está determinada por el esquema. Un Schema contiene una lista de Feature , y Transform las convierte en una "especificación de característica" (a veces llamada "especificación de análisis") que es un dictado cuyas claves son nombres de características y cuyos valores son uno de FixedLenFeature o VarLenFeature (u otro opciones no utilizadas por TensorFlow Transform).

Las reglas para inferir una especificación de característica del Schema son

  • Cada feature con un conjunto de shape dará como resultado un tf.FixedLenFeature con forma y default_value=None . presence.min_fraction debe ser 1 contrario y se producirá un error, ya que cuando no hay un valor predeterminado, un tf.FixedLenFeature requiere que la característica esté siempre presente.
  • Cada feature con shape no establecida dará como resultado una VarLenFeature .
  • Cada sparse_feature dará lugar a un tf.SparseFeature cuyo size y is_sorted son determinados por el fixed_shape y is_sorted campos de la SparseFeature mensaje.
  • Las características utilizadas como index_feature o value_feature de sparse_feature no tendrán su propia entrada generada en la especificación de la característica.
  • La correspondencia entre el campo de type de la feature (o los valores de característica de un proto sparse_feature ) y el dtype de la especificación de característica viene dada por la siguiente tabla:
type dtype
schema_pb2.INT tf.int64
schema_pb2.FLOAT tf.float32
schema_pb2.BYTES tf.string

Usar TensorFlow Transform para manejar etiquetas de cadenas

Por lo general, uno quiere usar TensorFlow Transform para generar un vocabulario y aplicar ese vocabulario para convertir cadenas en números enteros. Al seguir este flujo de trabajo, input_fn construido en el modelo generará la cadena entera. Sin embargo, las etiquetas son una excepción, porque para que el modelo pueda mapear las etiquetas de salida (enteros) a las cadenas, el modelo necesita input_fn para generar una etiqueta de cadena, junto con una lista de posibles valores de la etiqueta. Por ejemplo, si las etiquetas son cat y dog , la salida de input_fn debe ser estas cadenas sin procesar, y las claves ["cat", "dog"] deben pasarse al estimador como parámetro (ver detalles a continuación).

Para manejar la asignación de etiquetas de cadenas a números enteros, debes usar TensorFlow Transform para generar un vocabulario. Demostramos esto en el siguiente fragmento de código:

def _preprocessing_fn(inputs):
  """Preprocess input features into transformed features."""

  ...


  education = inputs[features.RAW_LABEL_KEY]
  _ = tft.uniques(education, vocab_filename=features.RAW_LABEL_KEY)

  ...

La función de preprocesamiento anterior toma la característica de entrada sin procesar (que también se devolverá como parte de la salida de la función de preprocesamiento) y llama a tft.uniques en ella. Esto da como resultado un vocabulario que se genera para la education que se puede acceder en el modelo.

El ejemplo también muestra cómo transformar una etiqueta y luego generar un vocabulario para la etiqueta transformada. En particular, toma la education etiqueta sin procesar y convierte todas las etiquetas excepto las 5 principales (por frecuencia) a UNKNOWN , sin convertir la etiqueta en un número entero.

En el código del modelo, el clasificador debe recibir el vocabulario generado por tft.uniques como argumento label_vocabulary . Esto se hace leyendo primero este vocabulario como una lista con una función auxiliar. Esto se muestra en el fragmento a continuación. Tenga en cuenta que el código de ejemplo usa la etiqueta transformada discutida anteriormente, pero aquí mostramos el código para usar la etiqueta sin formato.

def create_estimator(pipeline_inputs, hparams):

  ...

  tf_transform_output = trainer_util.TFTransformOutput(
      pipeline_inputs.transform_dir)

  # vocabulary_by_name() returns a Python list.
  label_vocabulary = tf_transform_output.vocabulary_by_name(
      features.RAW_LABEL_KEY)

  return tf.contrib.learn.DNNLinearCombinedClassifier(
      ...
      n_classes=len(label_vocab),
      label_vocabulary=label_vocab,
      ...)