TensorFlow für Erläuterungen verwenden

Wenn Sie mit benutzerdefiniert trainierten TensorFlow-Modellen arbeiten, benötigen Sie bestimmte Informationen, um das Modell zu speichern und Erläuterungen zu konfigurieren.

Um Vertex Explainable AI mit einem tabellarischen AutoML-Modell zu verwenden, müssen Sie keine Konfiguration vornehmen. Vertex AI konfiguriert das Modell für Vertex Explainable AI automatisch. Überspringen Sie dieses Dokument und lesen Sie Erläuterungen.

Diese Anleitung stellt die Informationen bereit, die Sie für das Training eines TensorFlow-Modells benötigen, um sicherzustellen, dass Sie es mit Vertex Explainable AI verwenden können. Hier werden insbesondere die folgenden Themen behandelt:

  • Suchen der Namen für Eingabe- und Ausgabetensoren während des Trainings, die Sie angeben müssen, wenn Sie eine Model-Ressource für Vertex Explainable AI konfigurieren. Dazu gehört auch das Erstellen und Suchen der entsprechenden Tensoren für Vertex Explainable AI in Sonderfällen, in denen die typischen nicht funktionieren.

  • Exportieren des TensorFlow-Modells als TensorFlow SavedModel, das mit Vertex Explainable AI kompatibel ist

  • Namen für Eingabe- und Ausgabetensoren von einem TensorFlow-SavedModel suchen, das bereits exportiert wurde Dies kann hilfreich sein, wenn Sie keinen Zugriff auf den Trainingscode für das Modell haben.

Namen für Eingabe- und Ausgabetensoren während des Trainings suchen

Wenn Sie einen integrierten TensorFlow-Container für Vorhersagen verwenden, müssen Sie die Namen der Eingabetensoren und des Ausgabetensors Ihres Modells kennen. Sie geben diese Namen als Teil einer ExplanationMetadata-Nachricht an, wenn Sie ein Model für Vertex Explainable AI konfigurieren.

Wenn Ihr TensorFlow-Modell die folgenden Kriterien erfüllt, können Sie mit der im nächsten Abschnitt beschriebenen „grundlegenden Methode” diese Tensornamen für das Training ermitteln:

  • Die Eingaben haben keine serialisierte Form.
  • Jede Eingabe für SignatureDef des Modells enthält den Wert des Features direkt. Dabei kann es sich um numerische Werte oder Strings handeln.
  • Die Ausgaben sind numerische Werte, die als numerische Daten behandelt werden. Dies schließt Klassen-IDs aus, die als kategoriale Daten betrachtet werden.

Wenn Ihr Modell diese Kriterien nicht erfüllt, lesen Sie den Abschnitt Trainingscode anpassen und in Sonderfällen Tensornamen finden.

Die grundlegende Methode

Geben Sie im Training das Attribut name der Eingabetensoren und der Ausgabetensoren Ihres Modells aus. Im folgenden Beispiel erzeugt das Feld name der Keras-Ebene den zugrunde liegenden Tensornamen, den Sie für Ihre ExplanationMetadata benötigen:

bow_inputs = tf.keras.layers.Input(shape=(2000,))
merged_layer = tf.keras.layers.Dense(256, activation="relu")(bow_inputs)
predictions = tf.keras.layers.Dense(10, activation="sigmoid")(merged_layer)
model = tf.keras.Model(inputs=bow_inputs, outputs=predictions)
print('input_tensor_name:', bow_inputs.name)
print('output_tensor_name:', predictions.name)

Die Ausführung dieses Python-Codes gibt die folgende Ausgabe aus:

input_tensor_name: input_1:0
output_tensor_name: dense_1/Sigmoid:0

Sie können dann input_1:0 als Namen für den Eingabetensor und dense_1/Sigmod:0 als Namen für den Ausgabetensor verwenden, wenn Sie Model für Erläuterungen konfigurieren.

Trainingscode anpassen und in Sonderfällen Tensornamen suchen

Es gibt ein paar gängige Fälle, in denen die Eingabe- und Ausgabetensoren für ExplanationMetadata nicht mit denen in Ihrer Bereitstellungs-SignatureDef übereinstimmen sollten:

  • Ihre Eingaben sind serialisiert.
  • Ihr Graph beinhaltet Vorverarbeitungsvorgänge.
  • Ihre Bereitstellungsausgaben sind keine Wahrscheinlichkeiten, Logits oder andere Typen von Gleitkommatensoren.

In diesen Fällen sollten Sie verschiedene Ansätze verwenden, um die richtigen Eingabe- und Ausgabetensoren zu finden. Das übergreifende Ziel besteht darin, die Tensoren für die Featurewerte zu finden, die Sie hinsichtlich der Eingaben erklären möchten, sowie Tensoren für Logits (Vorabaktivierung), Wahrscheinlichkeiten (nach der Aktivierung) oder eine beliebige andere Darstellungsform von Ausgaben.

Sonderfälle für Eingabetensoren

Die Eingaben in den Erklärungsmetadaten unterscheiden sich dann von denen in der Bereitstellungs-SignatureDef, wenn Sie für das Modell eine serialisierte Eingabe verwenden oder wenn Ihr Graph Vorverarbeitungsvorgänge enthält.

Serialisierte Eingaben

TensorFlow SavedModels können eine Vielzahl komplexer Eingaben verarbeiten, darunter:

  • Serialisierte tf.Example-Nachrichten
  • JSON-Strings
  • Codierte Base64-Strings zur Darstellung von Bilddaten

Wenn Ihr Modell serialisierte Eingaben wie diese akzeptiert, funktioniert es nicht, diese Tensoren direkt als Eingabe für Ihre Erklärungen zu verwenden bzw. könnte dies zu unsinnigen Ergebnissen führen. Stattdessen möchten Sie nachfolgende Eingabetensoren finden, die Featurespalten innerhalb des Modells versorgen.

Wenn Sie das Modell exportieren, können Sie dem TensorFlow-Graphen einen Parser-Vorgang hinzufügen, indem Sie in Ihrer Bereitstellungseingabefunktion eine Parser-Funktion aufrufen. Parser-Funktionen finden Sie im tf.io-Modul. Diese Parser-Funktionen geben in der Regel Tensoren als Antwort zurück, die sich besser für die Erklärungsmetadaten eignen.

Sie könnten z. B. tf.parse_example() beim Exportieren des Modells verwenden. Die Funktion verwendet eine serialisierte tf.Example-Nachricht und gibt ein Wörterbuch der Tensoren aus, die Featurespalten versorgen. Sie können deren Ausgabe verwenden, um die Erklärungsmetadaten anzugeben. Wenn manche dieser Ausgaben die Form des benannten Tupels "tf.SparseTensor" haben, das aus drei Tensoren besteht, sollten Sie die Namen der Indexe, Werte und dense_shape-Tensoren notieren und in die entsprechenden Felder in den Metadaten eingeben.

Das folgende Beispiel zeigt, wie nach einem Decodierungsvorgang der Name des Eingabetensors abgerufen wird:

float_pixels = tf.map_fn(
    lambda img_string: tf.io.decode_image(
        img_string,
        channels=color_depth,
        dtype=tf.float32
    ),
    features,
    dtype=tf.float32,
    name='input_convert'
  )

print(float_pixels.name)
Eingaben vorverarbeiten

Wenn Ihr Modellgraph Vorverarbeitungsvorgänge enthält, möchten Sie möglicherweise nach dem Vorverarbeitungsschritt Erklärungen zu den Tensoren abrufen. In diesem Fall können Sie die Namen der Tensoren mithilfe des name-Attributs von tf.Tensor abrufen und diese in die Erklärungsmetadaten einfügen:

item_one_hot = tf.one_hot(item_indices, depth,
    on_value=1.0, off_value=0.0,
    axis=-1, name="one_hot_items:0")
print(item_one_hot.name)

Der decodierte Name des Tensors lautet input_pixels:0.

Sonderfälle für Ausgabetensoren

Die Ausgaben in Ihrer Bereitstellungs-SignatureDef sind in den meisten Fällen entweder Wahrscheinlichkeiten oder Logits.

Wenn Ihr Modell Wahrscheinlichkeiten zuordnet, Sie aber stattdessen die Logit-Werte erklären möchten, müssen Sie die passenden Ausgabetensornamen finden, die den Logits entsprechen.

Wenn die Bereitstellungs-SignatureDef Ausgaben hat, die weder Wahrscheinlichkeiten noch Logits sind, sollten Sie auf den Wahrscheinlichkeitsvorgang im Trainingsgraphen verweisen. Dieses Szenario ist bei Keras-Modellen unwahrscheinlich. In diesem Fall können Sie mit TensorBoard oder einem anderen Graph-Visualisierungstool nach den richtigen Ausgabetensornamen suchen.

Besondere Überlegungen für integrierte Gradienten

Wenn Sie die integrierte Gradienten-Feature-Attributionsmethode von Vertex Explainable AI verwenden möchten, müssen Ihre Eingaben in Bezug auf die Ausgabe differenzierbar sein.

Die Erklärungsmetadaten sorgen für eine logische Trennung der Features eines Modells von seinen Eingaben. Wenn Sie integrierte Gradienten mit einem Eingabetensor verwenden, der in Bezug auf den Ausgabetensor nicht differenzierbar ist, müssen Sie auch die codierte (differenzierbare) Version des jeweiligen Features bereitstellen.

Verwenden Sie den folgenden Ansatz, wenn Sie nicht differenzierbare Eingabetensoren haben oder in Ihrem Graphen nicht differenzierbare Vorgänge haben:

  1. Codieren Sie die nicht differenzierbaren Eingaben als differenzierbare Eingaben.
  2. Legen Sie input_tensor_name auf den Namen des ursprünglichen, nicht differenzierbaren Eingangstensors und encoded_tensor_name auf den Namen seiner codierten, differenzierbaren Version fest.

Erklärungsmetadaten-Datei mit Codierung

Nehmen wir als Beispiel ein Modell an, das ein kategoriales Feature mit einem Eingabetensor namens zip_codes:0 aufweist. Da die Eingabedaten Postleitzahlen als Strings enthalten, ist der Eingabetensor zip_codes:0 nicht differenzierbar. Wenn das Modell diese Daten zusätzlich vorverarbeitet, um eine One-Hot-Codierungsdarstellung der Postleitzahlen zu erhalten, ist der Eingabetensor nach der Vorverarbeitung differenzierbar. Um ihn vom ursprünglichen Eingabetensor zu unterscheiden, können Sie ihn zip_codes_embedding:0 nennen.

Wenn Sie die Daten von beiden Eingabetensoren in Ihrer Erläuterungsanfrage verwenden möchten, legen Sie ExplanationMetadata fest, wenn Sie Model für Erläuterungen konfigurieren:

  • Legen Sie den "input feature key" auf einen aussagekräftigen Namen fest, z. B. zip_codes.
  • Legen Sie input_tensor_name auf den Namen des ursprünglichen Tensors (zip_codes:0) fest.
  • Legen Sie encoded_tensor_name auf den Namen des Tensors nach der One-Hot-Codierung fest (zip_codes_embedding:0).
  • Setzen Sie encoding auf COMBINED_EMBEDDING.
{
    "inputs": {
      "zip_codes": {
        "input_tensor_name": "zip_codes:0",
        "encoded_tensor_name": "zip_codes_embedding:0",
        "encoding": "COMBINED_EMBEDDING"
      }
    },
    "outputs": {
      "probabilities": {
        "output_tensor_name": "dense/Softmax:0"
      }
    }
}

Alternativ können Sie input_tensor_name auf den Namen des codierten, differenzierbaren Eingabetensors setzen und den ursprünglichen, nicht differenzierbaren Tensor weglassen. Der Vorteil der Bereitstellung beider Tensoren besteht darin, dass Attributionen zu einzelnen Postleitzahlwerten statt zu deren One-Hot-Codierungsdarstellung vorgenommen werden können. In diesem Beispiel würden Sie den ursprünglichen Tensor (zip_codes:0) weglassen und input_tensor_name auf zip_codes_embedding:0 festlegen. Dieser Ansatz ist nicht empfehlenswert, da die resultierenden Featureattributionen schwer zu verstehen wären.

Codierung

Geben Sie Codierungseinstellungen wie im vorherigen Beispiel gezeigt an, um die Codierung für Model zu aktivieren.

Mit dem Codierungsfeature können Sie den Prozess der Umwandlung von codierten Daten in Eingabedaten für Attributionen rückgängig machen, sodass die zurückgegebenen Attributionen nicht manuell nachbearbeitet werden müssen. Weitere Informationen finden Sie in der Liste der Codierungen, die Vertex Explanations AI unterstützt.

Für die COMBINED_EMBEDDING-Codierung wird der Eingabetensor in einem 1D-Array codiert.

Beispiel:

  • Eingabe: ["This", "is", "a", "test"]
  • Codierte Eingabe: [0.1, 0.2, 0.3, 0.4]

TensorFlow-SavedModels für Vertex Explainable AI exportieren

Nach dem Training eines TensorFlow-Modells exportieren Sie es als SavedModel. Das TensorFlow-SavedModel enthält das trainierte TensorFlow-Modell sowie serialisierte Signaturen, Variablen und andere Assets, die zum Ausführen des Graphen erforderlich sind. Jede SignatureDef im SavedModel identifiziert eine Funktion im Graphen, die Tensor-Eingaben akzeptiert und Tensor-Ausgaben erzeugt.

Folgen Sie der Anleitung in einem der folgenden Abschnitte, je nachdem, ob Sie TensorFlow 2 oder TensorFlow 1 verwenden, um dafür zu sorgen, dass Ihr SavedModel mit Vertex Explainable AI kompatibel ist.

TensorFlow 2

Wenn Sie mit TensorFlow 2.x arbeiten, verwenden Sie tf.saved_model.save zum Speichern für das Modell. Sie können beim Speichern Ihres Modells Eingabesignaturen angeben. Wenn Sie eine Eingabesignatur haben, verwendet Vertex Explainable AI die Standardbereitstellungsfunktion für Ihre Erläuterungsanfragen. Bei mehreren Eingabesignaturen sollten Sie beim Speichern des Modells die Signatur der Standardbereitstellungsfunktion angeben:

tf.saved_model.save(m, model_dir, signatures={
    'serving_default': serving_fn,
    'xai_model': model_fn # Required for XAI
    })

In diesem Fall verwendet Vertex Explainable AI die Signaturfunktion für die Modellfunktion, die Sie mit dem Schlüssel xai_model für Ihre Erläuterungsanfrage gespeichert haben. Verwenden Sie für den Schlüssel exakt den String xai_model.

Wenn Sie eine Vorverarbeitungsfunktion nutzen, müssen Sie die Signaturen für Ihre Vorverarbeitungsfunktion und für Ihre Modellfunktion angeben. Dabei müssen als Schlüssel exakt die Strings xai_preprocess und xai_model verwendet werden:

tf.saved_model.save(m, model_dir, signatures={
    'serving_default': serving_fn,
    'xai_preprocess': preprocess_fn, # Required for XAI
    'xai_model': model_fn # Required for XAI
    })

In diesem Fall verwendet Vertex Explainable AI die Vorverarbeitungsfunktion und die Modellfunktion für Ihre Erläuterungsanfragen. Die Ausgabe der Vorverarbeitungsfunktion muss der Eingabe entsprechen, die Ihre Modellfunktion erwartet.

Weitere Informationen finden Sie im Abschnitt zum Festlegen von Bereitstellungssignaturen in TensorFlow.

TensorFlow 1.15

Wenn Sie mit TensorFlow 1.15 arbeiten, verwenden Sie nicht tf.saved_model.save. Vertex Explainable AI unterstützt keine mit dieser Methode gespeicherten TensorFlow 1-Modelle

Wenn Sie Ihr Modell in Keras erstellen und trainieren, müssen Sie es in einen TensorFlow Estimator konvertieren und anschließend in ein SavedModel exportieren. In diesem Abschnitt geht es hauptsächlich um das Speichern eines Modells.

Nachdem Sie Ihr Keras-Modell erstellt, kompiliert, trainiert und bewertet haben, müssen Sie:

  • Das Keras-Modell mithilfe von tf.keras.estimator.model_to_estimator in einen TensorFlow Estimator konvertieren
  • Eine Bereitstellungseingabefunktion mithilfe von tf.estimator.export.build_raw_serving_input_receiver_fn bereitstellen
  • Das Modell mithilfe von tf.estimator.export_saved_model als SavedModel exportieren.
# Build, compile, train, and evaluate your Keras model
model = tf.keras.Sequential(...)
model.compile(...)
model.fit(...)
model.predict(...)

## Convert your Keras model to an Estimator
keras_estimator = tf.keras.estimator.model_to_estimator(keras_model=model, model_dir='export')

## Define a serving input function appropriate for your model
def serving_input_receiver_fn():
  ...
  return tf.estimator.export.ServingInputReceiver(...)

## Export the SavedModel to Cloud Storage, using your serving input function
export_path = keras_estimator.export_saved_model(
  'gs://' + 'YOUR_BUCKET_NAME',
  serving_input_receiver_fn
).decode('utf-8')

print("Model exported to: ", export_path)

Tensornamen aus SignatureDef von SavedModel abrufen

Sie können die SignatureDef eines TensorFlow-SavedModel verwenden, um die Erklärungsmetadaten vorzubereiten, sofern es die Kriterien für die in einem vorherigen Abschnitt beschriebene „Basismethode” erfüllt. Dies kann hilfreich sein, wenn Sie keinen Zugriff auf den Trainingscode haben, der das Modell erstellt hat.

Zum Prüfen der SignatureDef Ihres SavedModels können Sie die SavedModel-Befehlszeile verwenden. Weitere Informationen über die Verwendung der SavedModel-Befehlszeile

Sehen Sie sich die folgende Beispiel-SignatureDef an:

The given SavedModel SignatureDef contains the following input(s):
  inputs['my_numpy_input'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1)
      name: x:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['probabilities'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1)
      name: dense/Softmax:0
Method name is: tensorflow/serving/predict

Der Graph hat einen Eingabetensor namens x:0 und einen Ausgabetensor namens dense/Softmax:0. Wenn Sie Model für Erläuterungen konfigurieren, verwenden Sie x:0 als Eingabetensornamen und dense/Softmax:0 als Ausgabetensornamen in der Nachricht ExplanationMetadata.

Nächste Schritte