Присоединяйтесь к сообществу SIG TFX-Addons и помогите сделать TFX еще лучше!

Компонент конвейера преобразования TFX

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

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

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

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

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 - отличный инструмент для преобразования данных функций до того, как они попадут в вашу модель, и как часть процесса обучения. Преобразования общих функций включают в себя:

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

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 при использовании tf.Estimator API. Чтобы указать операции полного прохода, такие как вычисление квантилей, TensorFlow Transform предоставляет специальные функции, называемые analyzers которые выглядят как операции TensorFlow, но на самом деле определяют отложенное вычисление, которое будет выполняться Apache Beam, и вывод, вставленный в график как постоянный. В то время как обычная операция TensorFlow принимает в качестве входных данных один пакет, выполняет некоторые вычисления только для этого пакета и генерирует пакет, analyzer выполнит глобальное сокращение (реализованное в Apache Beam) по всем пакетам и вернет результат.

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

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

Компонент TFX Transform упрощает использование Transform, обрабатывая вызовы API, связанные с чтением и записью данных, и записывая выходные данные SavedModel на диск. Как пользователь TFX, вам нужно определить только одну функцию, называемую preprocessing_fn . В preprocessing_fn вы определяете серию функций, которые манипулируют входным dict тензоров для создания выходного dict тензоров. Вы можете найти вспомогательные функции, такие как 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:
    # 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

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

preprocessing_fn описывает серию операций с тензорами (то есть Tensor s или SparseTensor s), поэтому для правильной записи preprocessing_fn необходимо понимать, как ваши данные представлены в виде тензоров. Вход в preprocessing_fn определяется схемой. Schema содержит список Feature s, и Transform преобразует их в «спецификацию функции» (иногда называемую «спецификацией синтаксического анализа»), которая представляет собой dict, ключи которого являются именами функций, а значения - одним из FixedLenFeature или VarLenFeature (или другим параметры, не используемые TensorFlow Transform).

Правила для вывода спецификации функции из Schema :

  • Каждая feature с набором shape приведет к tf.FixedLenFeature с shape и default_value=None . presence.min_fraction противном случае presence.min_fraction должно быть равно 1 приведет к ошибке, поскольку, когда нет значения по умолчанию, tf.FixedLenFeature требует, чтобы функция всегда присутствовала.
  • Каждый feature с VarLenFeature shape приведет к VarLenFeature .
  • Каждый sparse_feature приведет к tf.SparseFeature , чей size и is_sorted определяются fixed_shape и is_sorted полей SparseFeature сообщения.
  • Для функций, используемых в качестве index_feature или value_feature для sparse_feature , не будет собственной записи, созданной в спецификации функции.
  • Соответствие между type поля feature (или функции значений а sparse_feature прото) и dtype бонусной спецификации задается следующей таблицей:
type dtype
schema_pb2.INT tf.int64
schema_pb2.FLOAT tf.float32
schema_pb2.BYTES tf.string

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

Обычно нужно использовать TensorFlow Transform как для создания словаря, так и для применения этого словаря для преобразования строк в целые числа. Следуя этому input_fn процессу, input_fn , 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. Кроме того, для отображения внешне созданных словарей может быть добавлен либо (я) непосредственно модификации vocab_paths словаря в пределах StatsOptions , или (II) с использованием tft.annotate_asset .