Wstępne przetwarzanie danych za pomocą TensorFlow Transform

Komponent inżynierii funkcji TensorFlow Extended (TFX)

Ten przykładowy notatnik colab stanowi bardzo prosty przykład tego, jak TensorFlow Transform ( tf.Transform ) może być używany do wstępnego przetwarzania danych przy użyciu dokładnie tego samego kodu zarówno do trenowania modelu, jak i obsługi wniosków w środowisku produkcyjnym.

TensorFlow Transform to biblioteka do wstępnego przetwarzania danych wejściowych dla TensorFlow, w tym tworzenia funkcji wymagających pełnego przejścia przez treningowy zestaw danych. Na przykład za pomocą TensorFlow Transform możesz:

  • Normalizuj wartość wejściową, używając średniej i odchylenia standardowego
  • Konwertuj łańcuchy na liczby całkowite, generując słownik dla wszystkich wartości wejściowych
  • Konwertuj liczby zmiennoprzecinkowe na liczby całkowite, przypisując je do segmentów na podstawie obserwowanego rozkładu danych

TensorFlow ma wbudowaną obsługę manipulacji na pojedynczym przykładzie lub partii przykładów. tf.Transform rozszerza te możliwości, aby obsługiwać pełne przebiegi całego zestawu danych treningowych.

Dane wyjściowe tf.Transform są eksportowane jako wykres TensorFlow, którego można używać zarówno do trenowania, jak i obsługi. Używanie tego samego wykresu zarówno do trenowania, jak i obsługi może zapobiec przekrzywieniu, ponieważ te same przekształcenia są stosowane na obu etapach.

Ulepsz Pip

Aby uniknąć aktualizacji Pip w systemie uruchomionym lokalnie, upewnij się, że działamy w Colab. Systemy lokalne można oczywiście aktualizować oddzielnie.

try:
  import colab
  !pip install --upgrade pip
except:
  pass

Zainstaluj TensorFlow Transform

pip install -q -U tensorflow_transform

Czy uruchomiłeś ponownie środowisko wykonawcze?

Jeśli używasz Google Colab, przy pierwszym uruchomieniu powyższej komórki musisz ponownie uruchomić środowisko wykonawcze (Runtime > Restart runtime ...). Wynika to ze sposobu, w jaki Colab ładuje paczki.

Import

import pprint
import tempfile

import tensorflow as tf
import tensorflow_transform as tft

import tensorflow_transform.beam as tft_beam
from tensorflow_transform.tf_metadata import dataset_metadata
from tensorflow_transform.tf_metadata import schema_utils

Dane: Utwórz fałszywe dane

Stworzymy kilka prostych fikcyjnych danych dla naszego prostego przykładu:

  • raw_data to początkowe nieprzetworzone dane, które zamierzamy wstępnie przetworzyć
  • raw_data_metadata zawiera schemat, który informuje nas o typach każdej z kolumn w raw_data . W tym przypadku sprawa jest bardzo prosta.
raw_data = [
      {'x': 1, 'y': 1, 's': 'hello'},
      {'x': 2, 'y': 2, 's': 'world'},
      {'x': 3, 'y': 3, 's': 'hello'}
  ]

raw_data_metadata = dataset_metadata.DatasetMetadata(
    schema_utils.schema_from_feature_spec({
        'y': tf.io.FixedLenFeature([], tf.float32),
        'x': tf.io.FixedLenFeature([], tf.float32),
        's': tf.io.FixedLenFeature([], tf.string),
    }))

Przekształć: Utwórz funkcję przetwarzania wstępnego

Funkcja przetwarzania wstępnego jest najważniejszą koncepcją tf.Transform. Funkcja przetwarzania wstępnego to miejsce, w którym naprawdę zachodzi transformacja zestawu danych. Przyjmuje i zwraca słownik tensorów, gdzie tensor oznacza Tensor lubSparseTensor . Istnieją dwie główne grupy wywołań API, które zazwyczaj tworzą serce funkcji przetwarzania wstępnego:

  1. TensorFlow Ops: Dowolna funkcja, która przyjmuje i zwraca tensory, co zwykle oznacza operacje TensorFlow. Dodają one operacje TensorFlow do wykresu, który przekształca nieprzetworzone dane w dane przekształcone po jednym wektorze cech naraz. Będą one działać na każdym przykładzie, zarówno podczas treningu, jak i podania.
  2. Analizatory/mapery transformacji tensorowej: Dowolne analizatory/mapery udostępniane przez tf.Transform. Akceptują one również i zwracają tensory i zazwyczaj zawierają kombinację operacji Tensorflow i obliczeń Beam, ale w przeciwieństwie do operacji TensorFlow działają one tylko w potoku Beam podczas analizy wymagającej pełnego przejścia przez cały zestaw danych treningowych. Obliczenie wiązki jest wykonywane tylko raz, podczas uczenia i zazwyczaj wykonuje pełny przebieg przez cały uczący zestaw danych. Tworzą one stałe tensorowe, które są dodawane do Twojego wykresu. Na przykład tft.min oblicza minimum tensora w uczącym zestawie danych, podczas gdy tft.scale_by_min_max najpierw oblicza min i maksimum tensora w uczącym zestawie danych, a następnie skaluje tensor tak, aby mieścił się w zakresie określonym przez użytkownika, [output_min, output_max]. tf.Transform zapewnia stały zestaw takich analizatorów/maperów, ale zostanie on rozszerzony w przyszłych wersjach.
def preprocessing_fn(inputs):
    """Preprocess input columns into transformed columns."""
    x = inputs['x']
    y = inputs['y']
    s = inputs['s']
    x_centered = x - tft.mean(x)
    y_normalized = tft.scale_to_0_1(y)
    s_integerized = tft.compute_and_apply_vocabulary(s)
    x_centered_times_y_normalized = (x_centered * y_normalized)
    return {
        'x_centered': x_centered,
        'y_normalized': y_normalized,
        's_integerized': s_integerized,
        'x_centered_times_y_normalized': x_centered_times_y_normalized,
    }

Kładąc wszystko razem

Teraz jesteśmy gotowi do przekształcenia naszych danych. Użyjemy Apache Beam z bezpośrednim runnerem i dostarczymy trzy dane wejściowe:

  1. raw_data - surowe dane wejściowe, które stworzyliśmy powyżej
  2. raw_data_metadata - Schemat surowych danych
  3. preprocessing_fn - Funkcja, którą stworzyliśmy, aby wykonać naszą transformację
def main():
  # Ignore the warnings
  with tft_beam.Context(temp_dir=tempfile.mkdtemp()):
    transformed_dataset, transform_fn = (  # pylint: disable=unused-variable
        (raw_data, raw_data_metadata) | tft_beam.AnalyzeAndTransformDataset(
            preprocessing_fn))

  transformed_data, transformed_metadata = transformed_dataset  # pylint: disable=unused-variable

  print('\nRaw data:\n{}\n'.format(pprint.pformat(raw_data)))
  print('Transformed data:\n{}'.format(pprint.pformat(transformed_data)))

if __name__ == '__main__':
  main()
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:apache_beam.options.pipeline_options:Discarding unparseable args: ['/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py', '-f', '/tmp/tmp8aif_7w8.json', '--HistoryManager.hist_file=:memory:']
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
2022-02-03 10:18:41.378629: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
Raw data:
[{'s': 'hello', 'x': 1, 'y': 1},
 {'s': 'world', 'x': 2, 'y': 2},
 {'s': 'hello', 'x': 3, 'y': 3}]

Transformed data:
[{'s_integerized': 0,
  'x_centered': -1.0,
  'x_centered_times_y_normalized': -0.0,
  'y_normalized': 0.0},
 {'s_integerized': 1,
  'x_centered': 0.0,
  'x_centered_times_y_normalized': 0.0,
  'y_normalized': 0.5},
 {'s_integerized': 0,
  'x_centered': 1.0,
  'x_centered_times_y_normalized': 1.0,
  'y_normalized': 1.0}]

Czy to właściwa odpowiedź?

Wcześniej używaliśmy do tego tf.Transform :

x_centered = x - tft.mean(x)
y_normalized = tft.scale_to_0_1(y)
s_integerized = tft.compute_and_apply_vocabulary(s)
x_centered_times_y_normalized = (x_centered * y_normalized)

x_centered

Z wejściem [1, 2, 3] średnia x wynosi 2 i odejmujemy ją od x, aby wyśrodkować nasze wartości x na 0. Zatem nasz wynik [-1.0, 0.0, 1.0] jest poprawny.

y_znormalizowane

Chcieliśmy przeskalować nasze wartości y między 0 a 1. Nasze dane wejściowe to [1, 2, 3] , więc nasz wynik [0.0, 0.5, 1.0] jest poprawny.

s_zintegrowany

Chcieliśmy odwzorować nasze łańcuchy na indeksy w słowniku, a w naszym słowniku były tylko 2 słowa („hello” i „world”). Tak więc przy wprowadzeniu ["hello", "world", "hello"] nasz wynik [0, 1, 0] jest poprawny. Ponieważ słowo „cześć” występuje w tych danych najczęściej, będzie to pierwszy wpis w słowniku.

x_centered_times_y_normalized

Chcieliśmy stworzyć nową funkcję, krzyżując x_centered i y_normalized za pomocą mnożenia. Zauważ, że to mnoży wyniki, a nie oryginalne wartości, a nasz nowy wynik [-0.0, 0.0, 1.0] jest poprawny.