Komponent potoku Transform TFX

Komponent potokowy Transform TFX wykonuje inżynierię funkcji na tf.Examples emitowanym ze składnika PrzykładGen , korzystając ze schematu danych utworzonego przez składnik SchemaGen i emituje zarówno SavedModel, jak i statystyki dotyczące danych przed i po transformacji. Po wykonaniu SavedModel zaakceptuje tf.Examples wyemitowane ze składnika PrzykładGen i wyemituje przekształcone dane funkcji.

  • Zużywa: tf.Examples ze składnika PrzykładGen i schemat danych ze składnika SchemaGen.
  • Emituje: zapisany model do komponentu Trainer, statystyki przed i po transformacji.

Konfigurowanie komponentu transformacji

Po zapisaniu pliku preprocessing_fn należy go zdefiniować w module Pythona, który następnie zostanie dostarczony do komponentu Transform jako dane wejściowe. Moduł ten zostanie załadowany przez transformację, a funkcja o nazwie preprocessing_fn zostanie znaleziona i użyta przez Transform do skonstruowania potoku przetwarzania wstępnego.

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

Dodatkowo możesz chcieć zapewnić opcje obliczeń statystycznych przed transformacją lub po transformacji w oparciu o TFDV . Aby to zrobić, zdefiniuj stats_options_updater_fn w tym samym module.

Transformacja i transformacja TensorFlow

Transform w szerokim zakresie wykorzystuje TensorFlow Transform do wykonywania inżynierii funkcji na zestawie danych. TensorFlow Transform to doskonałe narzędzie do przekształcania danych cech przed przesłaniem ich do modelu oraz w ramach procesu uczenia. Typowe transformacje cech obejmują:

  • Osadzanie : przekształcanie rzadkich cech (takich jak identyfikatory całkowite generowane przez słownictwo) w gęste cechy poprzez znalezienie sensownego mapowania z przestrzeni wielowymiarowej do przestrzeni niskowymiarowej. Zapoznaj się z sekcją Osadzanie w kursie przyspieszonym uczenia maszynowego, aby zapoznać się z wprowadzeniem do osadzania.
  • Generowanie słownictwa : konwertowanie ciągów znaków lub innych cech nienumerycznych na liczby całkowite poprzez utworzenie słownictwa, które odwzorowuje każdą unikalną wartość na numer identyfikacyjny.
  • Normalizowanie wartości : przekształcanie cech numerycznych tak, aby wszystkie mieściły się w podobnym zakresie.
  • Bucketyzacja : przekształcanie cech o wartościach ciągłych w cechy jakościowe poprzez przypisanie wartości do dyskretnych segmentów.
  • Wzbogacanie funkcji tekstowych : tworzenie funkcji na podstawie surowych danych, takich jak tokeny, n-gramy, encje, opinie itp. w celu wzbogacenia zestawu funkcji.

TensorFlow Transform zapewnia obsługę tych i wielu innych rodzajów transformacji:

  • Automatycznie generuj słownictwo na podstawie najnowszych danych.

  • Wykonaj dowolne przekształcenia danych przed wysłaniem ich do modelu. TensorFlow Transform buduje transformacje na wykresie TensorFlow dla Twojego modelu, dzięki czemu te same transformacje są wykonywane w czasie uczenia i wnioskowania. Można zdefiniować przekształcenia, które odwołują się do globalnych właściwości danych, takich jak maksymalna wartość cechy we wszystkich instancjach szkoleniowych.

Możesz przekształcić swoje dane w dowolny sposób przed uruchomieniem TFX. Ale jeśli zrobisz to w ramach TensorFlow Transform, transformacje staną się częścią wykresu TensorFlow. Takie podejście pomaga uniknąć odchyleń w zakresie treningu/porcji.

Transformacje w kodzie modelowania korzystają z kolumn FeatureColumns. Za pomocą FeatureColumns można definiować segmentacje, liczby całkowite korzystające z predefiniowanych słowników lub dowolne inne transformacje, które można zdefiniować bez sprawdzania danych.

Natomiast TensorFlow Transform jest przeznaczony do transformacji, które wymagają pełnego przejścia danych w celu obliczenia wartości, które nie są znane z góry. Na przykład generowanie słownictwa wymaga pełnego przekazania danych.

Oprócz obliczania wartości przy użyciu Apache Beam, TensorFlow Transform umożliwia użytkownikom osadzanie tych wartości w wykresie TensorFlow, który można następnie załadować do wykresu szkoleniowego. Na przykład podczas normalizowania cech funkcja tft.scale_to_z_score obliczy średnią i odchylenie standardowe cechy, a także reprezentację na wykresie TensorFlow funkcji, która odejmuje średnią i dzieli przez odchylenie standardowe. Emitując wykres TensorFlow, a nie tylko statystyki, TensorFlow Transform upraszcza proces tworzenia potoku przetwarzania wstępnego.

Ponieważ przetwarzanie wstępne jest wyrażone w postaci wykresu, może mieć miejsce na serwerze i gwarantuje spójność między szkoleniem a udostępnianiem. Ta spójność eliminuje jedno źródło odchyleń w treningu/serwowaniu.

TensorFlow Transform umożliwia użytkownikom określenie potoku przetwarzania wstępnego przy użyciu kodu TensorFlow. Oznacza to, że potok jest konstruowany w taki sam sposób jak wykres TensorFlow. Jeśli na tym wykresie użyto tylko operacji TensorFlow, potok byłby czystą mapą, która akceptuje partie danych wejściowych i zwraca partie danych wyjściowych. Taki potok byłby równoznaczny z umieszczeniem tego wykresu w input_fn podczas korzystania z interfejsu API tf.Estimator . Aby określić operacje pełnoprzepustowe, takie jak obliczanie kwantyli, TensorFlow Transform udostępnia specjalne funkcje zwane analyzers , które wyglądają jak operacje TensorFlow, ale w rzeczywistości określają odroczone obliczenia, które zostaną wykonane przez Apache Beam, a dane wyjściowe zostaną wstawione do wykresu jako stały. Podczas gdy zwykła operacja TensorFlow pobierze jako dane wejściowe pojedynczą partię, wykona pewne obliczenia tylko na tej partii i wyemituje partię, analyzer wykona globalną redukcję (zaimplementowaną w Apache Beam) we wszystkich partiach i zwróci wynik.

Łącząc zwykłe operacje TensorFlow i analizatory TensorFlow Transform, użytkownicy mogą tworzyć złożone potoki w celu wstępnego przetwarzania danych. Na przykład funkcja tft.scale_to_z_score pobiera tensor wejściowy i zwraca tensor znormalizowany tak, aby miał średnią 0 i wariancję 1 . Robi to, wywołując pod maską analizatory mean i var , które skutecznie generują stałe na wykresie równe średniej i wariancji tensora wejściowego. Następnie użyje operacji TensorFlow, aby odjąć średnią i podzielić przez odchylenie standardowe.

preprocessing_fn transformacji TensorFlow

Komponent TFX Transform upraszcza korzystanie z Transform, obsługując wywołania API związane z odczytywaniem i zapisywaniem danych oraz zapisywaniem danych wyjściowych SavedModel na dysku. Jako użytkownik TFX musisz zdefiniować tylko jedną funkcję zwaną preprocessing_fn . W preprocessing_fn definiujesz serię funkcji, które manipulują wejściowym dyktatem tensorów, aby wygenerować wyjściowy dykt tensorów. Funkcje pomocnicze, takie jak Scale_to_0_1 i compute_and_apply_vocabulary, można znaleźć w interfejsie API TensorFlow Transform lub użyć zwykłych funkcji TensorFlow, jak pokazano poniżej.

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

Zrozumienie danych wejściowych do pliku preprocessing_fn

preprocessing_fn opisuje serię operacji na tensorach (to znaczy Tensor s, SparseTensor s lub RaggedTensor s). Aby poprawnie zdefiniować preprocessing_fn konieczne jest zrozumienie, w jaki sposób dane są reprezentowane jako tensory. Dane wejściowe do preprocessing_fn są określane przez schemat. Proto Schema jest ostatecznie konwertowane na „specyfikację funkcji” (czasami nazywaną „specyfikacją analizowania”), która jest używana do analizowania danych. Więcej szczegółów na temat logiki konwersji znajdziesz tutaj .

Używanie TensorFlow Transform do obsługi etykiet ciągów

Zwykle chce się użyć TensorFlow Transform zarówno do wygenerowania słownictwa, jak i zastosowania tego słownictwa do konwersji ciągów na liczby całkowite. Wykonując tę ​​procedurę, input_fn skonstruowany w modelu wyświetli ciąg znaków w postaci całkowitej. Jednak etykiety stanowią wyjątek, ponieważ aby model mógł odwzorować etykiety wyjściowe (całkowite) z powrotem na ciągi znaków, model potrzebuje input_fn do wygenerowania etykiety ciągu wraz z listą możliwych wartości etykiety. Np. jeśli etykiety to cat i dog , wówczas wyjściem input_fn powinny być surowe ciągi znaków, a klucze ["cat", "dog"] należy przekazać do estymatora jako parametr (szczegóły poniżej).

Aby obsłużyć mapowanie etykiet łańcuchowych na liczby całkowite, należy użyć TensorFlow Transform do wygenerowania słownictwa. Pokazujemy to we fragmencie kodu poniżej:

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)

  ...

Powyższa funkcja przetwarzania wstępnego pobiera surową funkcję wejściową (która zostanie również zwrócona jako część wyniku funkcji przetwarzania wstępnego) i wywołuje na niej tft.vocabulary . Powoduje to wygenerowanie słownictwa na potrzeby education , do którego można uzyskać dostęp w modelu.

Przykład pokazuje również, jak przekształcić etykietę, a następnie wygenerować słownik dla przekształconej etykiety. W szczególności pobiera surową education i konwertuje wszystkie etykiety oprócz 5 pierwszych (według częstotliwości) na UNKNOWN , bez konwertowania etykiety na liczbę całkowitą.

W kodzie modelu klasyfikator musi otrzymać słownictwo wygenerowane przez tft.vocabulary jako argument label_vocabulary . Odbywa się to poprzez pierwsze przeczytanie tego słownictwa w postaci listy z funkcją pomocniczą. Pokazano to na fragmencie poniżej. Zwróć uwagę, że przykładowy kod wykorzystuje przekształconą etykietę omówioną powyżej, ale tutaj pokazujemy kod umożliwiający użycie nieprzetworzonej etykiety.

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

Konfigurowanie statystyk przed i po transformacji

Jak wspomniano powyżej, komponent Transform wywołuje TFDV w celu obliczenia statystyk przed i po transformacji. TFDV przyjmuje jako dane wejściowe opcjonalny obiekt StatsOptions . Użytkownicy mogą chcieć skonfigurować ten obiekt, aby włączyć pewne dodatkowe statystyki (np. statystyki NLP) lub ustawić sprawdzane progi (np. minimalna/maksymalna częstotliwość tokenów). Aby to zrobić, zdefiniuj stats_options_updater_fn w pliku modułu.

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

Statystyki po transformacji często korzystają ze znajomości słownictwa używanego do wstępnego przetwarzania funkcji. Nazwa słownika do mapowania ścieżki jest dostarczana do StatsOptions (a tym samym do TFDV) dla każdego słownictwa wygenerowanego przez TFT. Ponadto mapowania słowników tworzonych zewnętrznie można dodać poprzez (i) bezpośrednią modyfikację słownika vocab_paths w StatsOptions lub (ii) użycie tft.annotate_asset .