Utilizza TensorFlow con Vertex Explainable AI

Quando lavori con modelli TensorFlow personalizzati, devi disporre di informazioni specifiche necessarie per salvare il modello e configurare le spiegazioni.

Se vuoi utilizzare Vertex Explainable AI con un modello tabulare AutoML, non devi eseguire alcuna configurazione; Vertex AI configura automaticamente il modello per Vertex Explainable AI. Salta questo documento e leggi Recupero delle spiegazioni.

Questa guida fornisce le informazioni necessarie per l'addestramento di un modello TensorFlow per assicurarti di poterlo utilizzare con Vertex Explainable AI. In particolare, la guida tratta i seguenti argomenti:

  • Trova i nomi dei tensori di input e output durante l'addestramento che devi specificare quando configuri una risorsa Model per Vertex Explainable AI. Ciò include la creazione e la ricerca dei tensori appropriati per Vertex Explainable AI in casi speciali quando quelli tipici non funzionano.

  • Esportare il modello TensorFlow come TensorFlow SavedModel compatibile con Vertex Explainable AI.

  • Ricerca dei nomi tensori di input e output da un TensorFlow SavedModel già esportato. Ciò potrebbe essere utile se non hai accesso al codice di addestramento per il modello.

Trovare i nomi dei tensori di input e output durante l'addestramento

Quando utilizzi un container predefinito TensorFlow per fornire le previsioni, devi conoscere i nomi dei tensori di input e del tensore di output del modello. Specifica questi nomi come parte di un messaggio ExplanationMetadata quando configuri Model per Vertex Explainable AI

Se il tuo modello TensorFlow soddisfa i seguenti criteri, puoi utilizzare il metodo di base descritto nella sezione successiva per determinare questi nomi di tensori durante l'addestramento:

  • I dati inseriti non sono serializzati
  • Ogni valore inserito nel parametro SignatureDef del modello contiene direttamente il valore della caratteristica (possono essere valori numerici o stringhe)
  • Gli output sono valori numerici, pertanto vengono trattati come dati numerici. Sono esclusi gli ID classe, che sono considerati dati categorici.

Se il modello non soddisfa questi criteri, leggi la sezione Modificare il codice di addestramento e trovare i nomi di tensoriatori in casi speciali.

Metodo di base

Durante l'addestramento, stampa l'attributo name dei tensori di input dei tuoi modelli. Nell'esempio seguente, il campo name del livello Keras genera il nome del tensore sottostante necessario per il ExplanationMetadata:

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)

L'esecuzione di questo codice Python stampa il seguente output:

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

Puoi quindi utilizzare input_1:0 come nome tensore di input e dense_1/Sigmod:0 come nome tensore di output quando configuri Model per le spiegazioni.

Modificare il codice di addestramento e trovare i nomi dei tensoriatori in casi speciali

Esistono alcuni casi comuni in cui i tensori di input e output per il tuo elemento ExplanationMetadata non devono essere gli stessi del tuo SignatureDef:

  • Sono presenti input serializzati
  • Il grafico include operazioni di pre-elaborazione
  • Gli output di servizio non sono probabilità, logit o altri tipi di tensori in virgola mobile

In questi casi, dovresti utilizzare approcci diversi per trovare i tensori di input e output corretti. L'obiettivo generale è trovare i tensorierenti per i valori delle caratteristiche che vuoi spiegare per gli input e i tensore relativi a logit (pre-attivazione), le probabilità (post-attivazione) o qualsiasi altra rappresentazione per gli output.

Casi speciali di tensore di input

Gli input nei metadati della spiegazione sono diversi da quelli presenti nella pubblicazione SignatureDef se utilizzi un input serializzato per fornire il modello o se il grafico include operazioni di pre-elaborazione.

Ingressi serializzati

TensorFlow SalvaModels può accettare una varietà di input complessi, tra cui:

  • Messaggi di esempio di tf.serializzati
  • Stringhe JSON
  • Stringhe Base64 codificate (per rappresentare i dati delle immagini)

Se il tuo modello accetta input serializzati come questi, l'utilizzo di questi tensori direttamente come input per le tue spiegazioni non funzionerà, o potrebbe produrre risultati insensati. Dovrai invece individuare i tensori di input successivi che vengono inseriti nelle colonne delle funzionalità all'interno del modello.

Quando esporti il modello, puoi aggiungere un'operazione di analisi al grafico di TensorFlow chiamando una funzione di analisi nella funzione di input di pubblicazione. Le funzioni di analisi sono elencate nel modulo tf.io. Queste funzioni di analisi di solito restituiscono tensori come risposta e tendono a essere selezioni migliori per i metadati di spiegazione.

Ad esempio, puoi utilizzare tf.parse_example() per esportare il modello. Prende un messaggio tf.Example serie e restituisce un dizionario di tensori che vengono alimentati nelle colonne delle funzionalità. Puoi utilizzare l'output per compilare i metadati della spiegazione. Se alcuni di questi output sono tf.SparseTensor, che è una tupla denominata di 3 tensori, dovresti recuperare i nomi degli indici, dei valori e dei tensori dense_shape e compilare i campi corrispondenti nei metadati.

L'esempio seguente mostra come ottenere il nome del tensore di input dopo un'operazione di decodifica:

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)
Pre-elaborazione degli input

Se il grafico del modello contiene alcune operazioni di pre-elaborazione, ti consigliamo di ricevere spiegazioni sui tensori dopo il passaggio di pre-elaborazione. In questo caso, puoi ottenere i nomi di questi tensori utilizzando la proprietà name di tf.Tensor e inseriscili nei metadati esplicativi:

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)

Il nome tensore decodificato diventa input_pixels:0.

Casi speciali di tensore di output

Nella maggior parte dei casi, gli output nel SignatureDef di pubblicazione sono probabilità o logit.

Se il modello attribuisce le probabilità ma vuoi spiegare i valori del logit, devi trovare i nomi tensori di output corrispondenti ai logit.

Se l'elemento di pubblicazione SignatureDef presenta output che non sono probabilità o log, devi fare riferimento all'operazione di probabilità nel grafico di addestramento. Questo scenario è improbabile per i modelli Keras. In questo caso, puoi utilizzare TensorBoard (o altri strumenti di visualizzazione dei grafici) per individuare i nomi dei tensori di output corretti.

Considerazioni speciali per i gradienti integrati

Se vuoi utilizzare il metodo di attribuzione dei gradienti integrati di Vertex Explainable AI, devi assicurarti che i tuoi input siano differenziabili rispetto all'output.

I metadati della spiegazione separa logicamente le caratteristiche di un modello dai dati che contiene. Quando utilizzi gradienti integrati con un tensore di input non distinguibile rispetto al tensore di output, devi fornire anche la versione codificata (e differenziabile) della funzionalità.

Utilizza il seguente approccio se hai tensori di input non distinguibili o se sono presenti operazioni non distinguibili nel grafico:

  1. Codifica gli input non distinguibili come input differenziabili.
  2. Imposta input_tensor_name sul nome del tensore di input originale non distinguibile e imposta encoded_tensor_name sul nome della relativa versione codificata, differibile.

File di metadati esplicativi con codifica

Prendiamo ad esempio un modello che ha una funzionalità di categoria con un tensore di input denominato zip_codes:0. Poiché i dati di input includono codici postali come stringhe, il tensore di input zip_codes:0 non è distinguibile. Se il modello pre-elabora anche questi dati per ottenere una rappresentazione one-hot dei codici postali, è possibile differenziare il tensore di input dopo la pre-elaborazione. Per distinguerla dal tensore di input originale, puoi nominarla zip_codes_embedding:0.

Per utilizzare i dati di entrambi i tensori di input nella richiesta di spiegazioni, imposta ExplanationMetadata come segue quando configuri Model per le spiegazioni:

  • Imposta la chiave di input su un nome significativo, ad esempio zip_codes.
  • Imposta input_tensor_name sul nome del tensore originale, zip_codes:0.
  • Imposta encoded_tensor_name sul nome del tensore dopo la codifica one-hot, zip_codes_embedding:0.
  • Imposta encoding su 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"
      }
    }
}

In alternativa, puoi impostare input_tensor_name sul nome del tensore di input differenziato codificato e omettere il tensore originale non distinguibile. Il vantaggio di fornire a entrambi i tensori è che le attribuzioni possono essere effettuate per singoli valori del codice postale anziché per la rappresentazione con codifica a caldo. In questo esempio, escludi il tensore originale (zip_codes:0) e imposti input_tensor_name su zip_codes_embedding:0. Questo approccio non è consigliato, perché sarebbe difficile ragionare le attribuzioni delle funzionalità.

Codifica

Per attivare la codifica per Model, specifica le impostazioni di codifica come mostrato nell'esempio precedente.

La funzionalità di codifica consente di invertire il processo dai dati codificati alle informazioni di input per le attribuzioni, eliminando la necessità di post-elaborare manualmente le attribuzioni restituite. Consulta l'elenco delle codifiche supportate da Vertex Explainable AI.

Per la codifica COMBINED_EMBEDDING, il tensore di input è codificato in un array 1D.

Ad esempio:

  • Ingresso: ["This", "is", "a", "test"]
  • Ingresso codificato: [0.1, 0.2, 0.3, 0.4]

Esporta TensorFlow SavedModels per Vertex Explainable AI

Dopo aver addestrato un modello TensorFlow, esportalo come SavedModel. Il modello TensorFlow salvato contiene il modello TensorFlow addestrato, insieme a firme, variabili e altri asset serializzati per eseguire il grafico. Ogni elemento SignatureDef nel modello Saved identifica una funzione nel grafico che accetta input tensori e produce output tensori.

Per assicurarti che il tuo SavedModel sia compatibile con Vertex Explainable AI, segui le istruzioni in una delle seguenti sezioni, a seconda che utilizzi TensorFlow 2 o TensorFlow 1.

TensorFlow 2

Se utilizzi TensorFlow 2.x, utilizza tf.saved_model.save per salvare il modello. Puoi specificare le firme di input durante il salvataggio del modello. Se hai una firma di input, Vertex Explainable AI utilizza la funzione di pubblicazione predefinita per le richieste di spiegazione. Se disponi di più di una firma di input, devi specificare la firma della funzione predefinita di pubblicazione quando salvi il modello:

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

In questo caso, Vertex Explainable AI utilizza la firma della funzione modello che hai salvato con la chiave xai_model per la tua richiesta di spiegazioni. Utilizza la stringa esatta xai_model per la chiave.

Se utilizzi una funzione di pre-elaborazione, devi specificare anche le firme per la funzione di pre-elaborazione e la funzione del modello. Devi utilizzare le stringhe esatte xai_preprocess e xai_model come chiavi:

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 questo caso, Vertex Explainable AI utilizza la funzione di pre-elaborazione e la funzione del modello per le richieste di spiegazione. Assicurati che l'output della funzione di pre-elaborazione corrisponda all'input previsto dalla funzione del modello.

Ulteriori informazioni su come specificare le firme di pubblicazione in TensorFlow.

TensorFlow 1.15

Se utilizzi TensorFlow 1.15, non utilizzare tf.saved_model.save. Vertex Explainable AI non supporta i modelli TensorFlow 1 salvati con questo metodo

Se crei e addestra il tuo modello in Keras, devi convertirlo in uno Strumento per la stima di TensorFlow ed esportarlo in un SavedModel. Questa sezione si concentra sul salvataggio di un modello.

Dopo aver creato, compilato, addestrato e valutato il tuo modello Keras, devi:

  • Converti il modello Keras in uno strumento di stima TensorFlow utilizzando tf.keras.estimator.model_to_estimator
  • Fornisci una funzione di input di pubblicazione, utilizzando tf.estimator.export.build_raw_serving_input_receiver_fn
  • Esporta il modello come SavedModel, utilizzando tf.estimator.export_saved_model.
# 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)

Ottieni i nomi dei tensori da SignatureDef di SavedModel

Puoi utilizzare il SignatureDef di un modello salvato di TensorFlow per preparare i metadati della spiegazione, a condizione che soddisfi i criteri per il "metodo di base" descritto in una sezione precedente. Ciò potrebbe essere utile se non hai accesso al codice di addestramento che ha prodotto il modello.

Per ispezionare SignatureDef del modello SavedModel, puoi utilizzare l'interfaccia a riga di comando. Scopri di più su come utilizzare l'interfaccia a riga di comando SavedModel.

Considera il seguente esempio: SignatureDef:

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

Il grafico ha un tensore di input denominato x:0 e un tensore di output denominato dense/Softmax:0. Quando configuri Model per le spiegazioni, utilizza x:0 come nome del tensore di input e dense/Softmax:0 come nome del tensore di output nel messaggio ExplanationMetadata.

Passaggi successivi