Treten Sie der SIG TFX-Addons-Community bei und helfen Sie mit, TFX noch besser zu machen! SIG TFX-Addons beitreten

Die Transform TFX-Pipeline-Komponente

Die Transform TFX-Pipelinekomponente führt Feature-Engineering für tf.Examples durch, die von einer ExampleGen- Komponente unter Verwendung eines von einer SchemaGen- Komponente erstellten Datenschemas ausgegeben werden, und gibt sowohl ein SavedModel als auch Statistiken zu Daten vor und nach der Transformation aus. Bei der Ausführung akzeptiert das SavedModel tf.Examples, die von einer ExampleGen-Komponente ausgegeben wurden, und gibt die transformierten Feature-Daten aus.

  • Verwendet: tf.Beispiele aus einer ExampleGen-Komponente und ein Datenschema aus einer SchemaGen-Komponente.
  • Emits: Ein SavedModel an eine Trainerkomponente, Statistiken vor und nach der Transformation.

Konfigurieren einer Transformationskomponente

Sobald Ihr preprocessing_fn geschrieben ist, muss es in einem Python-Modul definiert werden, das dann der Transform-Komponente als Eingabe bereitgestellt wird. Dieses Modul wird von transform geladen und die Funktion preprocessing_fn wird gefunden und von Transform zum Erstellen der Vorverarbeitungspipeline verwendet.

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

Darüber hinaus möchten Sie möglicherweise Optionen für die TFDV- basierte Statistikberechnung vor oder nach der Transformation bereitstellen. Definieren stats_options_updater_fn im selben Modul einen stats_options_updater_fn .

Transform und TensorFlow-Transformation

Transform verwendet TensorFlow Transform in großem Umfang, um das Feature-Engineering für Ihr Dataset durchzuführen. TensorFlow Transform ist ein großartiges Tool zum Transformieren von Feature-Daten, bevor sie in Ihr Modell gelangen und Teil des Trainingsprozesses sind. Zu den allgemeinen Feature-Transformationen gehören:

  • Einbetten : Konvertieren von spärlichen Merkmalen (wie den von einem Vokabular erzeugten ganzzahligen IDs) in dichte Merkmale, indem eine aussagekräftige Zuordnung vom hochdimensionalen Raum zum niedrigdimensionalen Raum gefunden wird. Eine Einführung in Einbettungen finden Sie in der Einbettungseinheit im Crashkurs für maschinelles Lernen .
  • Wortschatzgenerierung : Konvertieren von Zeichenfolgen oder anderen nicht numerischen Merkmalen in Ganzzahlen durch Erstellen eines Wortschatzes, der jeden eindeutigen Wert einer ID-Nummer zuordnet.
  • Normalisieren von Werten : Transformieren von numerischen Merkmalen, sodass sie alle in einen ähnlichen Bereich fallen.
  • Bucketization : Konvertieren von Features mit kontinuierlichem Wert in kategoriale Features durch Zuweisen von Werten zu diskreten Buckets.
  • Anreichern von Textfeatures : Erstellen von Features aus Rohdaten wie Token, n-Gramm, Entitäten, Sentiment usw., um den Feature-Set zu bereichern.

TensorFlow Transform bietet Unterstützung für diese und viele andere Arten von Transformationen:

  • Generieren Sie automatisch ein Vokabular aus Ihren neuesten Daten.

  • Führen Sie beliebige Transformationen für Ihre Daten durch, bevor Sie sie an Ihr Modell senden. TensorFlow Transform erstellt Transformationen in das TensorFlow-Diagramm für Ihr Modell, sodass dieselben Transformationen zum Trainings- und Inferenzzeitpunkt ausgeführt werden. Sie können Transformationen definieren, die sich auf globale Eigenschaften der Daten beziehen, z. B. den Maximalwert eines Features für alle Trainingsinstanzen.

Sie können Ihre Daten beliebig transformieren, bevor Sie TFX ausführen. Wenn Sie dies jedoch in TensorFlow Transform tun, werden Transformationen Teil des TensorFlow-Diagramms. Dieser Ansatz hilft, Trainings- / Servierversatz zu vermeiden.

Transformationen in Ihrem Modellierungscode verwenden FeatureColumns. Mit FeatureColumns können Sie Bucketizations, Integerizations, die vordefinierte Vokabulare verwenden, oder andere Transformationen definieren, die definiert werden können, ohne die Daten zu betrachten.

Im Gegensatz dazu wurde TensorFlow Transform für Transformationen entwickelt, bei denen ein vollständiger Durchlauf der Daten erforderlich ist, um Werte zu berechnen, die im Voraus nicht bekannt sind. Beispielsweise erfordert die Erzeugung von Vokabeln einen vollständigen Durchlauf der Daten.

Neben der Berechnung von Werten mit Apache Beam können Benutzer mit TensorFlow Transform diese Werte in ein TensorFlow-Diagramm einbetten, das dann in das Trainingsdiagramm geladen werden kann. Wenn Sie beispielsweise Features normalisieren, berechnet die Funktion tft.scale_to_z_score den Mittelwert und die Standardabweichung eines Features sowie eine Darstellung der Funktion, die den Mittelwert subtrahiert und durch die Standardabweichung dividiert, in einem TensorFlow-Diagramm. Durch die Ausgabe eines TensorFlow-Diagramms und nicht nur von Statistiken vereinfacht TensorFlow Transform den Prozess der Erstellung Ihrer Vorverarbeitungspipeline.

Da die Vorverarbeitung als Grafik ausgedrückt wird, kann sie auf dem Server stattfinden und es wird garantiert, dass sie zwischen Training und Serving konsistent ist. Diese Konsistenz eliminiert eine Quelle für Trainings- / Servierversatz.

Mit TensorFlow Transform können Benutzer ihre Vorverarbeitungspipeline mithilfe von TensorFlow-Code angeben. Dies bedeutet, dass eine Pipeline auf die gleiche Weise wie ein TensorFlow-Diagramm erstellt wird. Wenn in diesem Diagramm nur TensorFlow-Operationen verwendet würden, wäre die Pipeline eine reine Karte, die Eingabestapel akzeptiert und Ausgabestapel zurückgibt. Eine solche Pipeline entspricht der Platzierung dieses Diagramms in Ihrem input_fn wenn Sie die tf.Estimator API verwenden. Um Full-Pass-Operationen wie das Berechnen von Quantilen anzugeben, bietet TensorFlow Transform spezielle Funktionen, sogenannte analyzers , die wie TensorFlow-Operationen aussehen. Geben Sie jedoch eine verzögerte Berechnung an, die von Apache Beam ausgeführt wird, und geben Sie die Ausgabe als a in das Diagramm ein Konstante. Während ein gewöhnlicher TensorFlow-Betrieb einen einzelnen Stapel als Eingabe verwendet, einige Berechnungen nur für diesen Stapel durchführt und einen Stapel ausgibt, führt ein analyzer eine globale Reduzierung (in Apache Beam implementiert) für alle Stapel durch und gibt das Ergebnis zurück.

Durch die Kombination gewöhnlicher TensorFlow-Operationen und TensorFlow-Transformationsanalysatoren können Benutzer komplexe Pipelines erstellen, um ihre Daten vorzuverarbeiten. Zum Beispiel nimmt die Funktion tft.scale_to_z_score einen Eingangstensor und gibt diesen Tensor zurück, der auf Mittelwert 0 und Varianz 1 normalisiert ist. Dazu werden die mean und var Analysatoren unter der Haube aufgerufen, wodurch im Diagramm effektiv Konstanten erzeugt werden, die dem Mittelwert und der Varianz des Eingangstensors entsprechen. Anschließend werden TensorFlow-Operationen verwendet, um den Mittelwert zu subtrahieren und durch die Standardabweichung zu dividieren.

Die TensorFlow-Transformation preprocessing_fn

Die TFX-Transformationskomponente vereinfacht die Verwendung von Transform, indem sie die API-Aufrufe zum Lesen und Schreiben von Daten verarbeitet und das ausgegebene SavedModel auf die Festplatte schreibt. Als TFX-Benutzer müssen Sie nur eine einzige Funktion definieren, die als preprocessing_fn . In preprocessing_fn definieren Sie eine Reihe von Funktionen, die das Eingangsdiktat von Tensoren manipulieren, um das Ausgangsdiktat von Tensoren zu erzeugen. Sie können Hilfsfunktionen wie scale_to_0_1 und compute_and_apply_vocabulary in der TensorFlow Transform-API finden oder reguläre TensorFlow-Funktionen verwenden, wie unten gezeigt.

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

Grundlegendes zu den Eingaben für die Vorverarbeitung_fn

Die preprocessing_fn beschreibt eine Reihe von Operationen auf Tensoren (das heißt, Tensor s oder SparseTensor s) und so die schreiben preprocessing_fn richtig ist es notwendig zu verstehen , wie Sie Ihre Daten als Tensoren vertreten. Die Eingabe in die preprocessing_fn wird durch das Schema bestimmt. Ein Schema Proto enthält eine Liste von Feature , und Transform konvertiert diese in eine "Feature-Spezifikation" (manchmal als "Parsing-Spezifikation" bezeichnet), ein Diktat, dessen Schlüssel Feature-Namen sind und dessen Werte FixedLenFeature oder VarLenFeature (oder eine andere) sind Optionen, die von TensorFlow Transform nicht verwendet werden).

Die Regeln zum Ableiten einer Feature-Spezifikation aus dem Schema lauten wie Schema

  • Jede feature mit shape - Set führt zu einem tf.FixedLenFeature mit Form und default_value=None . presence.min_fraction muss andernfalls 1 und es tritt ein Fehler auf, da für ein tf.FixedLenFeature die Funktion immer vorhanden sein muss, wenn kein Standardwert vorhanden ist.
  • Jedes feature mit nicht festgelegter shape führt zu einem VarLenFeature .
  • Jede sparse_feature führt zu einer tf.SparseFeature deren size und is_sorted durch die Felder fixed_shape und is_sorted der SparseFeature Nachricht bestimmt werden.
  • Für Features, die als index_feature oder value_feature eines sparse_feature werden, wird in der Feature-Spezifikation kein eigener Eintrag generiert.
  • Die Übereinstimmung zwischen type - Feld der feature (oder die Werte Merkmal eines sparse_feature proto) und der dtype des Merkmals spec wird durch die folgende Tabelle gegeben:
type dtype
schema_pb2.INT tf.int64
schema_pb2.FLOAT tf.float32
schema_pb2.BYTES tf.string

Verwenden von TensorFlow Transform zum Behandeln von Zeichenfolgenbeschriftungen

Normalerweise möchte man TensorFlow Transform verwenden, um sowohl ein Vokabular zu generieren als auch dieses Vokabular anzuwenden, um Zeichenfolgen in Ganzzahlen umzuwandeln. Wenn Sie diesem Workflow input_fn , gibt die im Modell erstellte input_fn die input_fn Zeichenfolge aus. Beschriftungen sind jedoch eine Ausnahme, da das Modell, damit das Modell die Ausgabe- (Ganzzahl-) Beschriftungen wieder Zeichenfolgen input_fn , die input_fn um eine Zeichenfolgenbeschriftung zusammen mit einer Liste möglicher Werte der Beschriftung auszugeben. Wenn die Bezeichnungen beispielsweise cat und dog die Ausgabe von input_fn diese rohen Zeichenfolgen sein, und die Schlüssel ["cat", "dog"] müssen als Parameter an den Schätzer übergeben werden (siehe Details unten).

Um die Zuordnung von Zeichenfolgenbezeichnungen zu Ganzzahlen zu handhaben, sollten Sie TensorFlow Transform verwenden, um ein Vokabular zu generieren. Wir demonstrieren dies im folgenden Code-Snippet:

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)

  ...

Die obige Vorverarbeitungsfunktion verwendet die tft.vocabulary (die auch als Teil der Ausgabe der Vorverarbeitungsfunktion zurückgegeben wird) und ruft darauf tft.vocabulary auf. Dies führt dazu, dass ein Vokabular für die education generiert wird, auf das im Modell zugegriffen werden kann.

Das Beispiel zeigt auch, wie ein Label transformiert und anschließend ein Vokabular für das transformierte Label generiert wird. Insbesondere nimmt es die Raw-Label- education und konvertiert alle bis auf die Top-5-Labels (nach Häufigkeit) in UNKNOWN , ohne das Label in eine Ganzzahl zu konvertieren.

Im Modellcode muss dem Klassifizierer das von tft.vocabulary generierte tft.vocabulary als Argument tft.vocabulary label_vocabulary . Dies geschieht, indem dieses Vokabular zuerst als Liste mit einer Hilfsfunktion gelesen wird. Dies wird im folgenden Snippet gezeigt. Beachten Sie, dass der Beispielcode das oben beschriebene transformierte Label verwendet. Hier wird jedoch Code für die Verwendung des Raw-Labels angezeigt.

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

Konfigurieren von Statistiken vor und nach der Transformation

Wie oben erwähnt, ruft die Transform-Komponente TFDV auf, um sowohl Statistiken vor als auch nach der Transformation zu berechnen. TFDV verwendet als Eingabe ein optionales StatsOptions- Objekt. Benutzer möchten dieses Objekt möglicherweise so konfigurieren, dass bestimmte zusätzliche Statistiken (z. B. NLP-Statistiken) aktiviert werden oder validierte Schwellenwerte festgelegt werden (z. B. minimale / maximale Token-Häufigkeit). Definieren stats_options_updater_fn in der Moduldatei einen 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

Statistiken nach der Transformation profitieren häufig von der Kenntnis des Vokabulars, das für die Vorverarbeitung eines Features verwendet wird. Die Zuordnung von Vokabelname zu Pfad wird StatsOptions (und damit TFDV) für jedes von TFT generierte Vokabular bereitgestellt. Darüber hinaus können Zuordnungen für extern erstellte Vokabulare hinzugefügt werden, indem entweder (i) das vocab_paths Wörterbuch in StatsOptions direkt geändert wird oder (ii) tft.annotate_asset .