Ayuda a proteger la Gran Barrera de Coral con TensorFlow en Kaggle Únete Challenge

El componente Transform TFX Pipeline

Los realice el componente de transformación de tuberías TFX cuentan ingeniería en tf.Examples emitidos desde una ExampleGen componente, utilizando un esquema de datos creada por un SchemaGen componente, y emite un tanto SavedModel así como estadísticas en ambos pre y post-transformar-transformar los datos. Cuando se ejecuta, SavedModel aceptará tf.Examples emitidos desde un componente ExampleGen y emitirá los datos de la característica transformada.

  • 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, estadísticas previas y posteriores a la transformación.

Configurar un componente de transformación

Una vez que su preprocessing_fn está escrito, tiene que ser definido en un módulo de Python que a continuación se proporciona al componente de transformación como una entrada. Este módulo se cargará por transformar y la función llamada preprocessing_fn será encontrado y utilizado por Transformada de construir la tubería pre-procesamiento.

transform = Transform(
    examples=example_gen.outputs['examples'],
    schema=schema_gen.outputs['schema'],
    module_file=os.path.abspath(_taxi_transform_module_file))

Además, es posible que desee proporcionar opciones al TFDV basadas en pre-transformar o después de transformar las estadísticas de cálculo. Para ello, defina una stats_options_updater_fn dentro del mismo módulo.

Transform y TensorFlow Transform

Transformar hace un amplio uso de TensorFlow Transformar para realizar la ingeniería característica 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: convertir características dispersas (como el ID de enteros producidos por un vocabulario) en características densos de encontrar un mapeo significativa desde el espacio de alta dimensional a baja espacio tridimensional. Ver la unidad de Inclusiones en el curso acelerado de aprendizaje automático para una introducción a las incrustaciones.
  • Generación de vocabulario: la conversión de cadenas u otros elementos no numéricos en enteros mediante la creación de un vocabulario que mapea cada valor único a un número de identificación.
  • La normalización de los valores: la transformación de funciones numéricas de modo que todos ellos caen dentro de un rango similar.
  • Bucketization: la conversión de funciones continuas valioso en las características categóricas mediante la asignación de valores a los cubos discretos.
  • Enriquecimiento de las características del texto: Características de los productores de datos en bruto como fichas, 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 del entrenamiento y la inferencia. 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 una pasada completa de 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 cuando las características de la normalización, la tft.scale_to_z_score función calculará la media y la desviación estándar de una función, y también una representación, en un gráfico TensorFlow, de la función que resta la media y la 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 suceder 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. Una tubería sería equivalente a colocar este gráfico dentro de su input_fn cuando se utiliza el tf.Estimator API. Con el fin de especificar las operaciones de paso completo, tales como el cálculo de cuantiles, TensorFlow Transform proporciona funciones especiales llamados analyzers que aparecen como ops TensorFlow, pero de hecho especificar un cálculo diferido que se hará por Apache Beam, y la salida insertado en el gráfico como una constante. Mientras que un TensorFlow op ordinaria tendrá un único lote como su entrada, realizar algún cálculo en un solo lote y que emiten un lote, un analyzer llevará a cabo una reducción global (implementado en Apache Beam) sobre 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 tft.scale_to_z_score función toma un tensor de entrada y retornos que tensor normalizado para tener media 0 y varianza 1 . Esto se hace llamando a los mean y var analizadores bajo el capó, que generarán efectivamente constantes en la gráfica igual a la media y la varianza del tensor de entrada. Luego usará las operaciones de TensorFlow para restar la media y dividir por la desviación estándar.

El TensorFlow Transform 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 TFX, es suficiente para definir una única función llamada la preprocessing_fn . En preprocessing_fn se define una serie de funciones que manipulan el dict de entrada de los tensores para producir el dict de salida de los tensores. Puede encontrar helper funciones como scale_to_0_1 y compute_and_apply_vocabulary la TensorFlow Transform API o usar las funciones regulares 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:
    # If sparse make it dense, setting nan's to 0 or '', and apply zscore.
    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

El preprocessing_fn describe una serie de operaciones en los tensores (es decir, Tensor s o SparseTensor s) y así para escribir el preprocessing_fn correctamente, es necesario entender cómo sus datos se representa como tensores. La entrada a la preprocessing_fn está determinada por el esquema. Un Schema proto contiene una lista de Feature s, y transformar los convierte a una "característica especificaciones" (a veces llamado un "especificación de análisis"), que es un diccionario cuyas claves son los nombres de característica 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 función desde el Schema son

  • Cada feature con shape conjunto resultará en una tf.FixedLenFeature con forma y default_value=None . presence.min_fraction debe ser 1 de otra forma y dará lugar a error, ya que cuando no hay ningún valor predeterminado, un tf.FixedLenFeature requiere la característica de estar siempre presente.
  • Cada feature con shape no establecida dará lugar a un 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.
  • Características utilizadas como index_feature o value_feature de un sparse_feature no tendrán su propia entrada generada en la especificación de características.
  • La correspondencia entre type de campo de la feature (o la función de los valores de un sparse_feature proto) y la dtype de la especificación 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. Cuando se sigue este flujo de trabajo, la input_fn construido en la salida del modelo voluntad la cadena de números enteros. Sin embargo etiquetas son una excepción, ya que para que el modelo sea capaz de asignar la salida (número entero) contraetiquetas en cadenas, el modelo necesita la input_fn a la salida de una etiqueta de secuencia, junto con una lista de valores posibles de la etiqueta. Por ejemplo, si las etiquetas son cat y dog , la salida de la input_fn debe ser estas cadenas primas, y las teclas ["cat", "dog"] que se deben transmitir en el estimador como parámetro (ver detalles más abajo).

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.vocabulary(education, vocab_filename=features.RAW_LABEL_KEY)

  ...

La función de preprocesamiento anteriormente tiene la función de entrada en bruto (que también se devuelven como parte de la salida de la función de procesamiento previo) y las llamadas tft.vocabulary en él. Esto resulta en un vocabulario que se generan para 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, se toma el crudo etiqueta education y convierte todos pero la parte superior 5 etiquetas (por frecuencia) para UNKNOWN , sin necesidad de convertir la etiqueta a un entero.

En el código del modelo, el clasificador debe dar el vocabulario generada por tft.vocabulary como el label_vocabulary argumento. 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 procesar.

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,
      ...)

Configuración de estadísticas previas y posteriores a la transformación

Como se mencionó anteriormente, el componente Transform invoca TFDV para calcular las estadísticas de pretransformación y postransformación. TFDV toma como entrada una opcionales StatsOptions objeto. Los usuarios pueden desear configurar este objeto para habilitar ciertas estadísticas adicionales (por ejemplo, estadísticas de PNL) o para establecer umbrales que están validados (por ejemplo, frecuencia de token mínima / máxima). Para ello, defina una stats_options_updater_fn en el archivo de módulo.

def stats_options_updater_fn(stats_type, stats_options):
  ...
  if stats_type == stats_options_util.StatsType.PRE_TRANSFORM:
    # Update stats_options to modify pre-transform statistics computation.
    # Most constraints are specified in the schema which can be accessed
    # via stats_options.schema.
  if stats_type == stats_options_util.StatsType.POST_TRANSFORM
    # Update stats_options to modify post-transform statistics computation.
    # Most constraints are specified in the schema which can be accessed
    # via stats_options.schema.
  return stats_options

Las estadísticas posteriores a la transformación a menudo se benefician del conocimiento del vocabulario que se utiliza para preprocesar una característica. El nombre del vocabulario al mapeo de rutas se proporciona a StatsOptions (y por lo tanto TFDV) para cada vocabulario generado por TFT. Además, las asignaciones de vocabularios creados externamente se pueden añadir ya sea por (i) modificar directamente los vocab_paths diccionario dentro StatsOptions o por (ii) utilizando tft.annotate_asset .