Informazioni su input e output per le spiegazioni

Prima di richiedere spiegazioni, devi inviare un file di metadati della spiegazione per configurare la richiesta. Questo file di metadati deve includere gli input e gli output del modello. Inoltre, include impostazioni facoltative, come le basi degli input e le impostazioni di visualizzazione per i dati delle immagini.

Se specifichi gli input e gli output del modello, puoi selezionare caratteristiche particolari per la richiesta di spiegazioni, senza che tu debba modificare il modello. Puoi utilizzare l'SDK Explainable AI per eseguire questa operazione in modo automatico durante la creazione di un nuovo modello. Se non utilizzi l'SDK Explainable AI, devi identificare manualmente gli input e gli output.

Questa guida è incentrata su come identificare manualmente i tensori di input e di output per aiutarti a preparare il file di metadati della spiegazione.

Input e output nei metadati della spiegazione

Per preparare i metadati della spiegazione, devi specificare gli input e gli output per il modello in un file denominato explanation_metadata.json:

{
  "inputs": {
    string <input feature key>: {
      "input_tensor_name": string,
  },
  "outputs": {
    string <output value key>:  {
      "output_tensor_name": string
    },
  },
  "framework": "tensorflow"
}

All'interno degli oggetti inputs e outputs del file, devi fornire i nomi dei tensori di input e di output per la richiesta di spiegazioni.

  • Le chiavi per ciascun input e output ("chiave caratteristica di input" e "chiave del valore di output" nell'esempio precedente) ti consentono di assegnare nomi significativi a ciascun tensore. Nell'esempio riportato di seguito, la chiave funzionalità di input è degrees_celsius, mentre la chiave del valore di output è probabilities.
  • Per i valori in ogni metadati input e output, devi fornire il nome effettivo del tensore come input_tensor_name o output_tensor_name. Nell'esempio riportato di seguito, input_tensor_name è x:0 e output_tensor_name è dense/Softmax:0.
{
    "inputs": {
      "degrees_celsius": {
        "input_tensor_name": "x:0",
      }
    },
    "outputs": {
      "probabilities": {
        "output_tensor_name": "dense/Softmax:0"
      }
    },
  "framework": "tensorflow"
}

I nomi effettivi dei tensori sono nel formato name:index.

Trovare i tensori di input e output

Dopo aver addestrato un modello TensorFlow, esportalo come savedModel. Il modello TensorFlow saveModel contiene il modello TensorFlow addestrato, insieme alle firme in serie, alle variabili e agli altri asset necessari per eseguire il grafico. Ogni SignatureDef identifica una funzione nel grafico che accetta input tensori e produce output tensore. Allo stesso modo, il file di metadati di spiegazione definisce gli input e gli output del grafico per la richiesta di attribuzione delle caratteristiche ad AI Explanations.

Spesso, i tensori di input e di output specificati nel file di metadati della spiegazione vengono mappati esattamente alle firme definite al momento del salvataggio del modello. In tal caso, trovare i nomi dei tensori di input e di output è relativamente semplice. Tuttavia, in alcuni casi, gli input o gli output che vuoi spiegare potrebbero essere diversi da quelli che definisci quando salvi il modello.

Gli input e gli output per le spiegazioni sono gli stessi che hai impostato in SignatureDef di pubblicazione se:

  • I valori inseriti non sono in formato seriale
  • Ogni input in SignatureDef contiene direttamente il valore della caratteristica (può essere costituito da valori numerici o stringhe)
  • Gli output sono valori numerici, trattati come dati numerici. Sono esclusi gli ID classe, che sono considerati dati categorici.

In questi casi, puoi ottenere i nomi dei tensori di input e di output durante la creazione del modello. In alternativa, puoi ispezionare l'SignatureDef di SaveModel con l'interfaccia a riga di comando SaveModel per trovare i nomi dei tensori di input e output.

Per tutti i casi che non soddisfano i criteri precedenti, esistono altri approcci che puoi adottare per trovare i giusti tensori di input e output.

Ottenere i nomi dei tensori durante l'addestramento

È più facile accedere ai nomi dei tensori di input e di output durante l'addestramento. Puoi salvare questi valori nel file di metadati della spiegazione mentre il tuo programma o ambiente ha ancora accesso alle variabili che hai impostato durante la creazione del modello. In questo esempio, il campo name del livello Keras produce il nome del tensore sottostante necessario per i metadati della spiegazione:

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 = keras.Model(inputs=bow_inputs, outputs=predictions)
print('input_tensor_name:', bow_inputs.name)
print('output_tensor_name:', predictions.name)
input_tensor_name: input_1:0
output_tensor_name: dense_1/Sigmoid:0

Per un esempio funzionante completo, consulta i blocchi note di esempio.

Recupero dei nomi dei tensori dalle definizioni delle firme

Dato che i valori SignatureDef e i metadati delle spiegazioni identificano sia input e output del tensore, puoi utilizzare SignatureDef per preparare il file di metadati della spiegazione, a condizione che soddisfi i criteri menzionati in precedenza.

Considera l'esempio SignatureDef seguente:

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. Entrambi i tensori hanno anche nomi significativi: my_numpy_input e probabilities rispettivamente. Per richiedere spiegazioni per probabilities in relazione a my_numpy_input, puoi creare un file di metadati spiegazione come segue:

{
    "inputs": {
      "my_numpy_input": {
        "input_tensor_name": "x:0",
      }
    },
    "outputs": {
      "probabilities": {
        "output_tensor_name": "dense/Softmax:0"
      }
    },
  "framework": "tensorflow"
}

Per ispezionare SignatureDef di SaveModel, puoi utilizzare l'interfaccia a riga di comando SalvatiModel. Scopri di più su come utilizzare l'interfaccia a riga di comando SavingModel.

Gestione delle discrepanze di input e output

In alcuni casi comuni i tensori di input e di output nei metadati della spiegazione non devono essere gli stessi della pubblicazioneSignatureDef:

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

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

Discrepanze di input

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

Input serializzati

I SaveModel di TensorFlow possono accettare una varietà di input complessi, tra cui:

  • Messaggi tf.Example in serie
  • Stringhe JSON
  • Stringhe Base64 codificate (per rappresentare i dati immagine)

Se il tuo modello accetta input seriali come questi, l'utilizzo diretto di questi tensori come input per le spiegazioni non funzionerà o potrebbe produrre risultati incomprensibili. Dovrai invece individuare i tensori di input successivi che si inseriscono nelle colonne delle caratteristiche all'interno del modello.

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

Ad esempio, potresti utilizzare tf.parse_example() durante l'esportazione del modello. Recupera un messaggio tf.Example serializzato e restituisce un dizionario dei tensori che si alimentano alle colonne delle caratteristiche. Puoi utilizzarlo per compilare i metadati della spiegazione. Se alcuni di questi output sono tf.SparseTensor, ovvero una tupla denominata costituita da 3 tensori, dovresti ottenere 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, è possibile che tu voglia ottenere spiegazioni sui tensori dopo la fase di pre-elaborazione. In questo caso, puoi ottenere i nomi di questi tensori utilizzando la proprietà name di tf.Tensor e inserirli nei metadati della spiegazione:

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 del tensore decodificato diventa input_pixels:0.

Discrepanze di output

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

Se il modello attribuisce le probabilità, ma vuoi spiegare i valori dei logit, devi trovare i nomi dei tensori di output appropriati che corrispondano ai logit.

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

Considerazioni aggiuntive sui gradienti integrati

AI Explanations fornisce due metodi di attribuzione delle caratteristiche: Shapley campionato e gradienti integrati. L'utilizzo del metodo dei gradienti integrati richiede di assicurarti che gli input siano differenziabili rispetto all'output, quindi devi tienilo presente quando prepari i metadati della spiegazione. Se utilizzi il metodo di attribuzione delle caratteristiche di Shapley campionato, non devi assicurarti che gli input siano differenziabili. Scopri di più sui metodi di attribuzione delle caratteristiche supportati in AI Explanations.

I metadati di spiegazione separano logicamente le caratteristiche di un modello dai relativi input. Quando utilizzi gradienti integrati con un tensore di input non differenziabile rispetto al tensore di output, devi fornire anche la versione codificata (e differenziabile) di questa funzionalità.

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

  • Codifica gli input non differenziabili come input differenziabili.
  • Imposta input_tensor_name sul nome del tensore di input originale non differenziabile e imposta encoded_tensor_name sul nome della versione codificata e differenziabile.

File di metadati spiegazione con codifica

Ad esempio, considera un modello che ha una caratteristica categorica con un tensore di input denominato zip_codes:0. Poiché i dati di input includono codici postali sotto forma di stringhe, il tensore di input zip_codes:0 non è differenziabile. Se anche il modello pre-elabora questi dati per ottenere una rappresentazione di codifica one-hot dei codici postali, il tensore di input dopo la pre-elaborazione diventa differenziabile. Per distinguerlo dal tensore di input originale, puoi assegnargli il nome zip_codes_embedding:0.

Per utilizzare i dati di entrambi i tensori di input nella richiesta di spiegazioni, imposta i metadati inputs come segue:

  • Imposta il tasto funzionalità 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"
      }
    },
  "framework": "tensorflow"
}

In alternativa, puoi impostare input_tensor_name sul nome del tensore di input codificato e differenziabile e omettere il tensore originale non differenziabile. Il vantaggio di fornire entrambi i tensori è che le attribuzioni possono essere effettuate a singoli valori di codice postale anziché sulla sua rappresentazione di codifica one-hot. 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 sulle attribuzioni delle funzionalità risultanti.

Codifica

Per attivare la codifica nella richiesta di spiegazioni, specifica le impostazioni di codifica come mostrato nell'esempio precedente.

La funzionalità di codifica consente di invertire il processo dai dati codificati ai dati di input per le attribuzioni, eliminando la necessità di post-elaborare manualmente le attribuzioni restituite. Attualmente AI Explanations supporta combined_embedding, in cui una funzionalità di lunghezza variabile viene combinata in un incorporamento. Un'operazione di esempio che corrisponde a questo combined_embedding è tf.nn.embedding_lookup_sparse.

Per combined_embedding:

Il tensore di input è codificato in un array 1D. Ad esempio:

  • Input: ["This", "is", "a", "test"]
  • Codificato: [0.1, 0.2, 0.3, 0.4]

Passaggi successivi