Únase a TensorFlow en Google I/O, del 11 al 12 de mayo Regístrese ahora

Comience con la validación de datos de Tensorflow

Tensorflow Data Validation (TFDV) puede analizar datos de entrenamiento y servicio para:

La API central admite cada parte de la funcionalidad, con métodos convenientes que se basan en la parte superior y se pueden llamar en el contexto de los cuadernos.

Cálculo de estadísticas de datos descriptivos

TFDV descriptivos puede calcular estadísticas que proporcionan una visión general de los datos en términos de las características que están presentes y las formas de sus distribuciones de valores. Herramientas como Facetas general pueden proporcionar una visualización sucinta de estas estadísticas para una fácil navegación.

Por ejemplo, supongamos que path puntos a un archivo en el TFRecord formato (que contiene los registros de tipo tensorflow.Example ). El siguiente fragmento ilustra el cálculo de estadísticas utilizando TFDV:

    stats = tfdv.generate_statistics_from_tfrecord(data_location=path)

El valor devuelto es un DatasetFeatureStatisticsList búfer de protocolo. El ejemplo cuaderno contiene una visualización de las estadísticas utilizando Facetas general :

    tfdv.visualize_statistics(stats)

Captura de pantalla de visualización de estadísticas

El ejemplo anterior asume que los datos se almacenan en un TFRecord archivo. TFDV también admite el formato de entrada CSV, con extensibilidad para otros formatos comunes. Puede encontrar los decodificadores de datos disponibles aquí . Además, TFDV proporciona la tfdv.generate_statistics_from_dataframe función de utilidad para los usuarios con datos en memoria representa como un pandas trama de datos.

Además de calcular un conjunto predeterminado de estadísticas de datos, TFDV también puede calcular estadísticas para dominios semánticos (p. ej., imágenes, texto). Para habilitar el cálculo de las estadísticas de dominios semánticos, pasar una tfdv.StatsOptions objeto con enable_semantic_domain_stats el valor true para tfdv.generate_statistics_from_tfrecord .

Corriendo en la nube de Google

Internamente, TFDV utiliza Apache Beam marco de procesamiento de datos en paralelo 's para escalar el cálculo de las estadísticas más grandes conjuntos de datos. Para las aplicaciones que desean integrar más profunda con TFDV (por ejemplo, adjuntar la generación de estadísticas al final de una tubería de datos de generación, la generación de estadísticas para los datos en formato personalizado ), la API también expone un PTransform Beam para la generación de estadísticas.

Para ejecutar TFDV en Google Cloud, el archivo de rueda de TFDV debe descargarse y proporcionarse a los trabajadores de Dataflow. Descargue el archivo de la rueda al directorio actual de la siguiente manera:

pip download tensorflow_data_validation \
  --no-deps \
  --platform manylinux2010_x86_64 \
  --only-binary=:all:

El siguiente fragmento muestra un ejemplo de uso de TFDV en Google Cloud:


import tensorflow_data_validation as tfdv
from apache_beam.options.pipeline_options import PipelineOptions, GoogleCloudOptions, StandardOptions, SetupOptions

PROJECT_ID = ''
JOB_NAME = ''
GCS_STAGING_LOCATION = ''
GCS_TMP_LOCATION = ''
GCS_DATA_LOCATION = ''
# GCS_STATS_OUTPUT_PATH is the file path to which to output the data statistics
# result.
GCS_STATS_OUTPUT_PATH = ''

PATH_TO_WHL_FILE = ''


# Create and set your PipelineOptions.
options = PipelineOptions()

# For Cloud execution, set the Cloud Platform project, job_name,
# staging location, temp_location and specify DataflowRunner.
google_cloud_options = options.view_as(GoogleCloudOptions)
google_cloud_options.project = PROJECT_ID
google_cloud_options.job_name = JOB_NAME
google_cloud_options.staging_location = GCS_STAGING_LOCATION
google_cloud_options.temp_location = GCS_TMP_LOCATION
options.view_as(StandardOptions).runner = 'DataflowRunner'

setup_options = options.view_as(SetupOptions)
# PATH_TO_WHL_FILE should point to the downloaded tfdv wheel file.
setup_options.extra_packages = [PATH_TO_WHL_FILE]

tfdv.generate_statistics_from_tfrecord(GCS_DATA_LOCATION,
                                       output_path=GCS_STATS_OUTPUT_PATH,
                                       pipeline_options=options)

En este caso, el proto estadísticas generada se almacena en un archivo TFRecord escrito a GCS_STATS_OUTPUT_PATH .

NOTA Cuando se llama a cualquiera de los tfdv.generate_statistics_... funciones (por ejemplo, tfdv.generate_statistics_from_tfrecord ) en la nube de Google, debe proporcionar un output_path . Especificar Ninguno puede causar un error.

Inferir un esquema sobre los datos

El esquema describe las propiedades esperadas de los datos. Algunas de estas propiedades son:

  • qué características se espera que estén presentes
  • su tipo
  • el número de valores para una característica en cada ejemplo
  • la presencia de cada característica en todos los ejemplos
  • los dominios de características esperados.

En resumen, el esquema describe las expectativas de datos "correctos" y, por lo tanto, puede usarse para detectar errores en los datos (descritos a continuación). Por otra parte, el mismo esquema se puede utilizar para configurar Tensorflow Transform para transformaciones de datos. Tenga en cuenta que se espera que el esquema sea bastante estático, por ejemplo, varios conjuntos de datos pueden ajustarse al mismo esquema, mientras que las estadísticas (descritas anteriormente) pueden variar según el conjunto de datos.

Dado que escribir un esquema puede ser una tarea tediosa, especialmente para conjuntos de datos con muchas funciones, TFDV proporciona un método para generar una versión inicial del esquema basada en las estadísticas descriptivas:

    schema = tfdv.infer_schema(stats)

En general, TFDV utiliza heurísticas conservadoras para inferir propiedades de datos estables a partir de las estadísticas a fin de evitar el sobreajuste del esquema al conjunto de datos específico. Se recomienda encarecidamente que revise el esquema inferido y refinarlo, según sea necesario, para capturar cualquier conocimiento del dominio sobre los datos que la heurística de TFDV podría haber perdido.

Por defecto, tfdv.infer_schema infiere la forma de cada función que se requiera, si value_count.min es igual value_count.max para la función. Ajuste el infer_feature_shape argumento a false para deshabilitar la inferencia forma.

El esquema en sí se almacena como un búfer de protocolo de esquema y de este modo se puede actualizar / editado usando el API-buffer protocolo estándar. TFDV también proporciona un par de métodos de utilidad para hacer más fácil estas actualizaciones. Por ejemplo, supongamos que el esquema contiene la siguiente estrofa para describir una característica cadena requerida payment_type que toma un solo valor:

feature {
  name: "payment_type"
  value_count {
    min: 1
    max: 1
  }
  type: BYTES
  domain: "payment_type"
  presence {
    min_fraction: 1.0
    min_count: 1
  }
}

Para marcar que la función debe completarse en al menos el 50% de los ejemplos:

    tfdv.get_feature(schema, 'payment_type').presence.min_fraction = 0.5

El ejemplo cuaderno contiene una simple visualización del esquema como una tabla, una lista de cada función y sus principales características como codificado en el esquema.

Captura de pantalla de la visualización del esquema

Comprobación de los datos en busca de errores.

Dado un esquema, es posible comprobar si un conjunto de datos se ajusta a las expectativas establecidas en el esquema o si existen anomalías en los datos . Puede verificar sus datos en busca de errores (a) en conjunto en un conjunto de datos completo comparando las estadísticas del conjunto de datos con el esquema, o (b) verificando errores por ejemplo.

Hacer coincidir las estadísticas del conjunto de datos con un esquema

Para verificar errores en el agregado, TFDV compara las estadísticas del conjunto de datos con el esquema y marca cualquier discrepancia. Por ejemplo:

    # Assume that other_path points to another TFRecord file
    other_stats = tfdv.generate_statistics_from_tfrecord(data_location=other_path)
    anomalies = tfdv.validate_statistics(statistics=other_stats, schema=schema)

El resultado es una instancia de la Anomalías búfer de protocolo y describe los errores en las estadísticas no están de acuerdo con el esquema. Por ejemplo, supongamos que los datos en other_path contiene ejemplos con valores para la característica de payment_type fuera del dominio especificado en el esquema.

Esto produce una anomalía.

   payment_type  Unexpected string values  Examples contain values missing from the schema: Prcard (<1%).

lo que indica que se encontró un valor fuera de dominio en las estadísticas en < 1% de los valores de características.

Si se esperaba esto, entonces el esquema se puede actualizar de la siguiente manera:

   tfdv.get_domain(schema, 'payment_type').value.append('Prcard')

Si la anomalía realmente indica un error de datos, los datos subyacentes deben corregirse antes de usarlos para el entrenamiento.

Los diversos tipos de anomalías que pueden ser detectadas por este módulo se enumeran aquí .

El ejemplo cuaderno contiene una simple visualización de las anomalías como una mesa, una lista de las características que se detecten errores y una breve descripción de cada error.

Captura de pantalla de anomalías

Comprobación de errores por ejemplo

TFDV también ofrece la opción de validar los datos por ejemplo, en lugar de comparar las estadísticas de todo el conjunto de datos con el esquema. TFDV proporciona funciones para validar datos por ejemplo y luego generar estadísticas de resumen para los ejemplos anómalos encontrados. Por ejemplo:

   options = tfdv.StatsOptions(schema=schema)
   anomalous_example_stats = tfdv.validate_examples_in_tfrecord(
       data_location=input, stats_options=options)

Los anomalous_example_stats que validate_examples_in_tfrecord retornos es un DatasetFeatureStatisticsList búfer de protocolo en el que cada conjunto de datos consiste en el conjunto de ejemplos que muestran una anomalía en particular. Puede usar esto para determinar la cantidad de ejemplos en su conjunto de datos que exhiben una anomalía dada y las características de esos ejemplos.

Entornos de esquema

De forma predeterminada, las validaciones asumen que todos los conjuntos de datos en una tubería se adhieren a un solo esquema. En algunos casos, es necesario introducir ligeras variaciones en el esquema, por ejemplo, las características utilizadas como etiquetas son necesarias durante el entrenamiento (y deben validarse), pero faltan durante el servicio.

Ambientes se pueden utilizar para expresar tales requisitos. En particular, las características del esquema se pueden asociar con un conjunto de entornos utilizando default_environment, in_environment y not_in_environment.

Por ejemplo, si la función de consejos está siendo utilizado como la etiqueta en el entrenamiento, pero perdidos en los datos que sirven. Sin el entorno especificado, aparecerá como una anomalía.

    serving_stats = tfdv.generate_statistics_from_tfrecord(data_location=serving_data_path)
    serving_anomalies = tfdv.validate_statistics(serving_stats, schema)

Captura de pantalla de anomalías en el servicio

Para solucionar esto, debemos configurar el entorno predeterminado para que todas las funciones sean tanto "ENTRENAMIENTO" como "SERVICIO", y excluir la función "consejos" del entorno de SERVICIO.

    # All features are by default in both TRAINING and SERVING environments.
    schema.default_environment.append('TRAINING')
    schema.default_environment.append('SERVING')

    # Specify that 'tips' feature is not in SERVING environment.
    tfdv.get_feature(schema, 'tips').not_in_environment.append('SERVING')

    serving_anomalies_with_env = tfdv.validate_statistics(
        serving_stats, schema, environment='SERVING')

Comprobación de sesgo y deriva de datos

Además de verificar si un conjunto de datos se ajusta a las expectativas establecidas en el esquema, TFDV también proporciona funcionalidades para detectar:

  • sesgo entre el entrenamiento y el servicio de datos
  • deriva entre diferentes días de datos de entrenamiento

TFDV realiza esta verificación comparando las estadísticas de diferentes conjuntos de datos en función de los comparadores de deriva/sesgo especificados en el esquema. Por ejemplo, para verificar si hay algún sesgo entre la característica 'pago_tipo' dentro del conjunto de datos de entrenamiento y servicio:

    # Assume we have already generated the statistics of training dataset, and
    # inferred a schema from it.
    serving_stats = tfdv.generate_statistics_from_tfrecord(data_location=serving_data_path)
    # Add a skew comparator to schema for 'payment_type' and set the threshold
    # of L-infinity norm for triggering skew anomaly to be 0.01.
    tfdv.get_feature(schema, 'payment_type').skew_comparator.infinity_norm.threshold = 0.01
    skew_anomalies = tfdv.validate_statistics(
        statistics=train_stats, schema=schema, serving_statistics=serving_stats)

NOTA Para detectar sesgo de funciones numéricas, especifique un jensen_shannon_divergence umbral en lugar de un infinity_norm umbral en el skew_comparator .

Lo mismo pasa con la comprobación de si un conjunto de datos se ajustan a las expectativas establecidas en el esquema, el resultado es también una instancia de la Anomalías búfer de protocolo y describe cualquier inclinación entre la formación y conjuntos de datos que sirven. Por ejemplo, supongamos que los datos de porción contiene significativamente más ejemplos con característica payement_type que tienen valor Cash , esto produce una anomalía skew

   payment_type  High L-infinity distance between serving and training  The L-infinity distance between serving and training is 0.0435984 (up to six significant digits), above the threshold 0.01. The feature value with maximum difference is: Cash

Si la anomalía realmente indica un sesgo entre el entrenamiento y el servicio de datos, entonces se necesita más investigación, ya que esto podría tener un impacto directo en el rendimiento del modelo.

El ejemplo cuaderno contiene un simple ejemplo de comprobación de anomalías basados en oblicuos.

La detección de la deriva entre diferentes días de datos de entrenamiento se puede hacer de manera similar

    # Assume we have already generated the statistics of training dataset for
    # day 2, and inferred a schema from it.
    train_day1_stats = tfdv.generate_statistics_from_tfrecord(data_location=train_day1_data_path)
    # Add a drift comparator to schema for 'payment_type' and set the threshold
    # of L-infinity norm for triggering drift anomaly to be 0.01.
    tfdv.get_feature(schema, 'payment_type').drift_comparator.infinity_norm.threshold = 0.01
    drift_anomalies = tfdv.validate_statistics(
        statistics=train_day2_stats, schema=schema, previous_statistics=train_day1_stats)

NOTA Para detectar sesgo de funciones numéricas, especifique un jensen_shannon_divergence umbral en lugar de un infinity_norm umbral en el drift_comparator .

Escribir conector de datos personalizado

Para estadísticas de los datos de cómputo, TFDV proporciona varios métodos convenientes para la manipulación de datos de entrada en varios formatos (por ejemplo TFRecord de tf.train.Example , CSV, etc). Si su formato de datos no está en esta lista, debe escribir un conector de datos personalizado para leer datos de entrada y conectarlo con la API principal de TFDV para calcular estadísticas de datos.

El TFDV API núcleo para el cálculo de estadísticas de los datos es un PTransform Beam que toma un PCollection de lotes de ejemplos de entrada (un lote de ejemplos de entrada se representa como una flecha RecordBatch), y emite una PCollection que contiene un único DatasetFeatureStatisticsList búfer de protocolo.

Una vez que haya implementado el conector de datos a medida que los lotes sus ejemplos de entrada en una flecha RecordBatch, debe conectar con el tfdv.GenerateStatistics API para calcular las estadísticas de los datos. Tome TFRecord de tf.train.Example 's, por ejemplo. tfx_bsl proporciona la TFExampleRecord conector de datos, y a continuación es un ejemplo de cómo conectar con el tfdv.GenerateStatistics API.

import tensorflow_data_validation as tfdv
from tfx_bsl.public import tfxio
import apache_beam as beam
from tensorflow_metadata.proto.v0 import statistics_pb2

DATA_LOCATION = ''
OUTPUT_LOCATION = ''

with beam.Pipeline() as p:
    _ = (
    p
    # 1. Read and decode the data with tfx_bsl.
    | 'TFXIORead' >> (
          tfxio.TFExampleRecord(
              file_pattern=[DATA_LOCATION],
              telemetry_descriptors=['my', 'tfdv']).BeamSource())
    # 2. Invoke TFDV `GenerateStatistics` API to compute the data statistics.
    | 'GenerateStatistics' >> tfdv.GenerateStatistics()
    # 3. Materialize the generated data statistics.
    | 'WriteStatsOutput' >> WriteStatisticsToTFRecord(OUTPUT_LOCATION))

Cálculo de estadísticas sobre segmentos de datos

TFDV se puede configurar para calcular estadísticas sobre segmentos de datos. Rebanar se puede activar proporcionando funciones de rebanado que tienen en una Flecha RecordBatch y la salida una secuencia de tuplas de forma (slice key, record batch) . TFDV proporciona una manera fácil de generar funciones basadas en el valor de rebanado característica que se pueden proporcionar como parte de tfdv.StatsOptions al calcular las estadísticas.

Cuando se habilita el corte en lonchas, la salida DatasetFeatureStatisticsList proto contiene múltiples DatasetFeatureStatistics Protos, uno para cada rebanada. Cada corte se identifica por un nombre único que se establece como el nombre del conjunto de datos en el proto DatasetFeatureStatistics . De forma predeterminada, TFDV calcula estadísticas para el conjunto de datos general además de los sectores configurados.

import tensorflow_data_validation as tfdv
from tensorflow_data_validation.utils import slicing_util

# Slice on country feature (i.e., every unique value of the feature).
slice_fn1 = slicing_util.get_feature_value_slicer(features={'country': None})

# Slice on the cross of country and state feature (i.e., every unique pair of
# values of the cross).
slice_fn2 = slicing_util.get_feature_value_slicer(
    features={'country': None, 'state': None})

# Slice on specific values of a feature.
slice_fn3 = slicing_util.get_feature_value_slicer(
    features={'age': [10, 50, 70]})

stats_options = tfdv.StatsOptions(
    slice_functions=[slice_fn1, slice_fn2, slice_fn3])