Компонент конвейера Transform TFX

Компонент конвейера Transform TFX выполняет разработку функций для tf.Examples, созданного из компонента SampleGen , с использованием схемы данных, созданной компонентом SchemaGen , и создает как SavedModel, так и статистику как по данным до преобразования, так и после преобразования. При выполнении SavedModel примет tf.Examples, созданный из компонента SampleGen, и выдаст преобразованные данные объекта.

  • Потребляет: tf.Examples из компонента SampleGen и схему данных из компонента SchemaGen.
  • Испускает: SavedModel для компонента Trainer, статистика до и после преобразования.

Настройка компонента преобразования

После того, как ваш preprocessing_fn написан, его необходимо определить в модуле Python, который затем предоставляется компоненту Transform в качестве входных данных. Этот модуль будет загружен преобразованием, а функция с именем preprocessing_fn будет найдена и использована преобразованием для создания конвейера предварительной обработки.

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

Кроме того, вы можете предоставить опции для расчета статистики до или после преобразования на основе TFDV . Для этого определите stats_options_updater_fn в том же модуле.

Преобразование и преобразование TensorFlow

Transform широко использует TensorFlow Transform для проектирования функций вашего набора данных. TensorFlow Transform — отличный инструмент для преобразования данных объектов до того, как они попадут в вашу модель, а также в рамках процесса обучения. Общие преобразования функций включают в себя:

  • Встраивание : преобразование разреженных функций (например, целочисленных идентификаторов, созданных словарем) в плотные функции путем нахождения значимого отображения из многомерного пространства в низкомерное пространство. См. раздел «Внедрения» в ускоренном курсе машинного обучения, чтобы получить представление о встраиваниях.
  • Генерация словаря : преобразование строк или других нечисловых функций в целые числа путем создания словаря, который сопоставляет каждое уникальное значение с идентификационным номером.
  • Нормализация значений : преобразование числовых функций так, чтобы все они находились в одном диапазоне.
  • Бакетизация : преобразование функций с непрерывным значением в категориальные функции путем присвоения значений дискретным сегментам.
  • Расширение текстовых функций : создание функций из необработанных данных, таких как токены, n-граммы, сущности, настроения и т. д., для расширения набора функций.

TensorFlow Transform обеспечивает поддержку этих и многих других видов преобразований:

  • Автоматически создавайте словарь на основе последних данных.

  • Выполняйте произвольные преобразования данных перед отправкой их в модель. TensorFlow Transform встраивает преобразования в график TensorFlow для вашей модели, поэтому одни и те же преобразования выполняются во время обучения и вывода. Вы можете определить преобразования, которые относятся к глобальным свойствам данных, таким как максимальное значение признака во всех экземплярах обучения.

Вы можете преобразовать свои данные по своему усмотрению перед запуском TFX. Но если вы сделаете это в TensorFlow Transform, преобразования станут частью графа TensorFlow. Такой подход помогает избежать перекоса в обучении/обслуживании.

Преобразования внутри вашего кода моделирования используют FeatureColumns. Используя FeatureColumns, вы можете определить сегменты, целочисленные преобразования, использующие предопределенные словари, или любые другие преобразования, которые можно определить, не просматривая данные.

Напротив, TensorFlow Transform предназначен для преобразований, требующих полного прохода данных для вычисления значений, которые заранее не известны. Например, генерация словаря требует полного прохождения данных.

Помимо вычисления значений с помощью Apache Beam, TensorFlow Transform позволяет пользователям встраивать эти значения в график TensorFlow, который затем можно загрузить в обучающий граф. Например, при нормализации функций функция tft.scale_to_z_score вычисляет среднее и стандартное отклонение функции, а также представление на графике TensorFlow функции, которая вычитает среднее значение и делит на стандартное отклонение. Создавая график TensorFlow, а не только статистику, TensorFlow Transform упрощает процесс создания конвейера предварительной обработки.

Поскольку предварительная обработка выражается в виде графика, она может происходить на сервере и гарантированно будет согласованной между обучением и обслуживанием. Такая последовательность устраняет один из источников перекосов в обучении/обслуживании.

TensorFlow Transform позволяет пользователям указывать свой конвейер предварительной обработки с помощью кода TensorFlow. Это означает, что конвейер строится так же, как и граф TensorFlow. Если бы в этом графе использовались только операции TensorFlow, конвейер представлял бы собой чистую карту, которая принимает пакеты входных данных и возвращает пакеты выходных данных. Такой конвейер был бы эквивалентен размещению этого графика внутри вашего input_fn при использовании API tf.Estimator . Чтобы указать полнопроходные операции, такие как вычисление квантилей, TensorFlow Transform предоставляет специальные функции, называемые analyzers , которые выглядят как операции TensorFlow, но на самом деле определяют отложенные вычисления, которые будут выполняться Apache Beam, а выходные данные вставляются в график как постоянный. В то время как обычная операция TensorFlow принимает на вход один пакет, выполняет некоторые вычисления только над этим пакетом и выдает пакет, analyzer выполнит глобальное сокращение (реализованное в Apache Beam) для всех пакетов и вернет результат.

Объединив обычные анализаторы TensorFlow ops и TensorFlow Transform, пользователи могут создавать сложные конвейеры для предварительной обработки своих данных. Например, функция tft.scale_to_z_score принимает входной тензор и возвращает этот тензор, нормализованный так, чтобы он имел среднее значение 0 и дисперсию 1 . Это делается путем вызова анализаторов mean и var , которые эффективно генерируют на графике константы, равные среднему и дисперсии входного тензора. Затем он будет использовать операции TensorFlow, чтобы вычесть среднее значение и разделить его на стандартное отклонение.

Преобразование TensorFlow preprocessing_fn

Компонент TFX Transform упрощает использование Transform, обрабатывая вызовы API, связанные с чтением и записью данных, и записывая выходную SavedModel на диск. Как пользователю TFX, вам нужно определить только одну функцию, называемую preprocessing_fn . В preprocessing_fn вы определяете серию функций, которые манипулируют входным словарем тензоров для создания выходного словаря тензоров. Вы можете найти вспомогательные функции, такие как Scale_to_0_1 и Compute_and_apply_vocabulary API преобразования TensorFlow , или использовать обычные функции TensorFlow, как показано ниже.

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

Понимание входных данных для preprocessing_fn

preprocessing_fn описывает серию операций с тензорами (то есть Tensor , SparseTensor или RaggedTensor ). Чтобы правильно определить preprocessing_fn необходимо понять, как данные представляются в виде тензоров. Входные данные для preprocessing_fn определяются схемой. Прототип Schema в конечном итоге преобразуется в «спецификацию функции» (иногда называемую «спецификация синтаксического анализа»), которая используется для синтаксического анализа данных. Более подробную информацию о логике преобразования см. здесь .

Использование TensorFlow Transform для обработки строковых меток

Обычно нужно использовать TensorFlow Transform как для создания словаря, так и для применения этого словаря для преобразования строк в целые числа. При выполнении этого рабочего процесса input_fn , созданный в модели, будет выводить целочисленную строку. Однако метки являются исключением, поскольку для того, чтобы модель могла сопоставлять выходные (целочисленные) метки обратно со строками, модели требуется input_fn для вывода строковой метки вместе со списком возможных значений метки. Например, если метками являются cat и dog , то выводом input_fn должны быть эти необработанные строки, а ключи ["cat", "dog"] необходимо передать в оценщик в качестве параметра (подробности см. ниже).

Чтобы обрабатывать сопоставление строковых меток с целыми числами, вам следует использовать TensorFlow Transform для создания словаря. Мы продемонстрируем это в фрагменте кода ниже:

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)

  ...

Приведенная выше функция предварительной обработки принимает функцию необработанного ввода (которая также будет возвращена как часть вывода функции предварительной обработки) и вызывает для нее tft.vocabulary . В результате создается словарь для education , к которому можно получить доступ в модели.

В примере также показано, как преобразовать метку, а затем создать словарь для преобразованной метки. В частности, он берет education метки и преобразует все метки, кроме первых 5 (по частоте), в UNKNOWN , не преобразуя метку в целое число.

В коде модели классификатору должен быть передан словарь, сгенерированный tft.vocabulary в качестве аргумента label_vocabulary . Для этого сначала прочитайте этот словарь в виде списка со вспомогательной функцией. Это показано во фрагменте ниже. Обратите внимание, что в примере кода используется преобразованная метка, описанная выше, но здесь мы показываем код для использования необработанной метки.

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

Настройка статистики до и после преобразования

Как упоминалось выше, компонент Transform вызывает TFDV для вычисления статистики как до преобразования, так и после преобразования. TFDV принимает в качестве входных данных необязательный объект StatsOptions . Пользователи могут захотеть настроить этот объект, чтобы включить определенную дополнительную статистику (например, статистику NLP) или установить проверяемые пороговые значения (например, минимальную/максимальную частоту токена). Для этого определите stats_options_updater_fn в файле модуля.

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

Статистика после преобразования часто выигрывает от знания словаря, используемого для предварительной обработки объекта. Сопоставление имени словаря с путем предоставляется StatsOptions (и, следовательно, TFDV) для каждого словаря, созданного TFT. Кроме того, сопоставления для словарей, созданных извне, можно добавить либо (i) напрямую изменив словарь vocab_paths в StatsOptions, либо (ii) используя tft.annotate_asset .