Avant de demander des explications, vous devez envoyer un fichier de métadonnées d'explication pour configurer votre requête d'explications. Ce fichier de métadonnées doit inclure les entrées et les sorties de votre modèle. Il comprend également des paramètres facultatifs, tels que les références en entrée et les paramètres de visualisation des données d'image.
La spécification des entrées et des sorties de votre modèle vous permet de sélectionner des caractéristiques particulières pour votre requête d'explications, sans avoir à modifier votre modèle. Vous pouvez utiliser le SDK Explainable AI pour effectuer cette opération automatiquement lorsque vous créez un modèle. Si vous n'utilisez pas le SDK Explainable AI, vous devez identifier manuellement vos entrées et sorties.
Ce guide explique comment identifier manuellement les Tensors d'entrée et de sortie afin de vous aider à préparer votre fichier de métadonnées d'explication.
Entrées et sorties dans les métadonnées d'explications
Pour préparer vos métadonnées d'explications, vous devez spécifier les entrées et les sorties de votre modèle dans un fichier nommé explanation_metadata.json
:
{
"inputs": {
string <input feature key>: {
"input_tensor_name": string,
},
"outputs": {
string <output value key>: {
"output_tensor_name": string
},
},
"framework": "tensorflow"
}
Dans les objets inputs
et outputs
du fichier, vous devez spécifier les noms des Tensors d'entrée et de sortie pour votre requête d'explications.
- Les clés de chaque entrée et sortie ("input feature key" et "output value key" dans l'exemple précédent) vous permettent d'attribuer des noms explicites à chaque Tensor.
Dans l'exemple ci-dessous, la clé de caractéristique d'entrée est
degrees_celsius
et la clé de valeur de sortie estprobabilities
. - Pour les valeurs de chaque métadonnée
input
etoutput
, vous devez spécifier le nom réel du Tensor en tant queinput_tensor_name
ououtput_tensor_name
. Dans l'exemple ci-dessous, la valeur deinput_tensor_name
estx:0
et celle deoutput_tensor_name
estdense/Softmax:0
.
{
"inputs": {
"degrees_celsius": {
"input_tensor_name": "x:0",
}
},
"outputs": {
"probabilities": {
"output_tensor_name": "dense/Softmax:0"
}
},
"framework": "tensorflow"
}
Les noms réels des Tensors sont au format name:index
.
Rechercher des Tensors d'entrée et de sortie
Après avoir entraîné un modèle TensorFlow, exportez-le en tant que modèle SavedModel. Le modèle TensorFlow SavedModel contient votre modèle TensorFlow entraîné, ainsi que des signatures sérialisées, des variables et d'autres éléments nécessaires à l'exécution du graphe. Chaque valeur SignatureDef
identifie une fonction dans votre graphe qui accepte les entrées de Tensor et produit des sorties de Tensor. De la même manière, votre fichier de métadonnées d'explications définit les entrées et les sorties du graphe pour votre requête d'attribution de caractéristiques envoyée à AI Explanations.
Il arrive souvent que les Tensors d'entrée et de sortie que vous spécifiez dans votre fichier de métadonnées d'explications correspondent exactement aux signatures que vous définissez lorsque vous enregistrez votre modèle. Si c'est le cas, la recherche des noms de vos Tensors d'entrée et de sortie est assez simple. Cependant, dans certains cas, les entrées ou les sorties que vous souhaitez expliquer peuvent être différentes de celles que vous définissez lorsque vous enregistrez le modèle.
Vos entrées et vos sorties d'explications sont identiques à celles que vous avez définies dans votre inférence SignatureDef
si :
- vos entrées ne sont pas sérialisées ;
- chaque entrée de
SignatureDef
contient directement la valeur de la caractéristique. Il peut s'agir de valeurs numériques ou de chaînes ; - les sorties sont des valeurs numériques, traitées comme des données numériques. Cela exclut les identifiants de classe, qui sont considérés comme des données catégorielles.
Dans ce cas, vous pouvez obtenir les noms des Tensors d'entrée et de sortie au moment de la création du modèle. Vous pouvez également les obtenir en inspectant le paramètre SignatureDef
de votre modèle SavedModel à l'aide de la CLI SavedModel.
Dans les cas qui ne correspondent pas aux critères précédents, il existe d'autres approches pour trouver les Tensors d'entrée et de sortie corrects.
Obtenir les noms de Tensor pendant l'entraînement
Il est plus facile d'accéder aux noms de Tensor d'entrée et de sortie lors de l'entraînement. Vous pouvez enregistrer ces valeurs dans votre fichier de métadonnées d'explications pendant que votre programme ou votre environnement a encore accès aux variables que vous avez définies lors de la création du modèle. Dans cet exemple, le champ name
de la couche Keras produit le nom du Tensor sous-jacent dont vous avez besoin pour vos métadonnées d'explications :
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
Pour accéder à un exemple fonctionnel complet, reportez-vous aux exemples de notebooks.
Obtenir les noms de Tensor à partir des définitions de signature
Comme les valeurs SignatureDef
et les métadonnées d'explications identifient les entrées et les sorties de Tensor, vous pouvez utiliser le paramètre SignatureDef
pour préparer votre fichier de métadonnées d'explications, à condition de respecter les critères mentionnés précédemment.
Prenons l'exemple SignatureDef
suivant :
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
Le graphe présente un Tensor d'entrée nommé x:0
et un Tensor de sortie nommé dense/Softmax:0
. Les deux Tensors possèdent également un nom explicite, respectivement my_numpy_input
et probabilities
. Pour demander des explications sur les probabilities
par rapport à my_numpy_input
, vous pouvez créer un fichier de métadonnées d'explications comme suit :
{
"inputs": {
"my_numpy_input": {
"input_tensor_name": "x:0",
}
},
"outputs": {
"probabilities": {
"output_tensor_name": "dense/Softmax:0"
}
},
"framework": "tensorflow"
}
Pour inspecter le paramètre SignatureDef
de votre modèle SavedModel, vous pouvez utiliser la CLI SavedModel. Découvrez en détail comment utiliser la CLI SavedModel.
Gérer les écarts d'entrée et de sortie
Il existe des cas où les Tensors d'entrée et de sortie de vos métadonnées d'explications ne doivent pas être identiques à ceux de votre inférence SignatureDef
:
- vous avez des entrées sérialisées ;
- votre graphe inclut des opérations de prétraitement ;
- vos résultats d'inférence ne sont pas des probabilités, des fonctions logit ou d'autres types de Tensors à virgule flottante.
Dans ces cas, vous devez utiliser différentes approches pour trouver les Tensors d'entrée et de sortie corrects. L'objectif général est de trouver les Tensors correspondant aux valeurs de caractéristique que vous souhaitez expliquer pour les entrées, ainsi que les Tensors correspondant aux fonctions logit (préactivation), aux probabilités (postactivation) ou à toute autre représentation des résultats.
Écarts d'entrée
Les entrées de vos métadonnées d'explications diffèrent de celles de votre inférence SignatureDef
si vous utilisez une entrée sérialisée pour alimenter le modèle, ou si votre graphe inclut des opérations de prétraitement.
Entrées sérialisées
Les modèles TensorFlow SavedModel acceptent diverses entrées complexes, y compris les suivantes :
- Messages tf.Example sérialisés
- Chaînes JSON
- Chaînes encodées en base64 (pour représenter les données d'image)
Si votre modèle accepte des entrées sérialisées comme celles-ci, l'utilisation directe de ces Tensors pour vos explications ne fonctionnera pas ou produira des résultats absurdes. Vous devez plutôt rechercher les Tensors d'entrée suivants qui alimentent les colonnes de caractéristiques de votre modèle.
Lorsque vous exportez votre modèle, vous pouvez ajouter une opération d'analyse à votre graphe TensorFlow en appelant une fonction d'analyse dans la fonction d'entrée d'inférence. Les fonctions d'analyse sont répertoriées dans le module tf.io. Ces fonctions d'analyse renvoient généralement des Tensors en tant que réponse. Ces Tensors constituent les meilleurs choix pour vos métadonnées d'explications.
Par exemple, vous pouvez utiliser la fonction tf.parse_example() lors de l'exportation de votre modèle. La fonction utilise un message tf.Example sérialisé et génère un dictionnaire de Tensors qui alimentent les colonnes de caractéristiques. Vous pouvez utiliser la sortie pour renseigner vos métadonnées d'explications. Si certaines de ces sorties sont tf.SparseTensor, qui est un tuple nommé composé de trois Tensors, vous devez obtenir les noms des indices, des valeurs et des Tensors dense_shape, ainsi que renseigner les champs correspondants dans les métadonnées.
L'exemple suivant montre comment obtenir le nom du Tensor d'entrée après une opération de décodage :
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)
Prétraiter les entrées
Si le graphe de votre modèle contient des opérations de prétraitement, vous pouvez obtenir des explications sur les Tensors après l'étape de prétraitement. Dans ce cas, les noms de ces Tensors sont obtenus en utilisant la propriété name
de tf.Tensor et en les insérant dans les métadonnées d'explications :
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)
Le nom du Tensor décodé devient input_pixels:0
.
Écarts de sortie
Dans la plupart des cas, les sorties de votre inférence SignatureDef
sont des probabilités ou des fonctions logit.
Si votre modèle attribue des probabilités, mais que vous souhaitez plutôt expliquer les valeurs logit, vous devez trouver les noms de Tensor de sortie appropriés qui correspondent aux valeurs logit.
Si votre inférence SignatureDef
comporte des résultats qui ne sont pas des probabilités ni des valeurs logit, vous devez vous référer à l'opération de probabilités dans le graphe d'entraînement.
Ce scénario est peu probable pour les modèles Keras. Si tel est le cas, vous pouvez utiliser TensorBoard (ou d'autres outils de visualisation graphique) pour localiser les noms de Tensor de sortie corrects.
Autres considérations sur les gradients intégrés
AI Explanations propose deux méthodes d'attribution de caractéristiques : l'échantillonnage des valeurs de Shapley et les gradients intégrés. Avec la méthode des gradients intégrés, vous devez vous assurer que vos entrées peuvent être différenciées par rapport à la sortie. Vous devez donc garder ceci à l'esprit lorsque vous préparez vos métadonnées d'explications. La vérification de la différenciabilité des entrées n'est pas nécessaire si vous utilisez la méthode d'attribution des caractéristiques par échantillonnage des valeurs de Shapley. Documentez-vous sur les méthodes d'attribution de caractéristiques compatibles avec AI Explanations.
Les métadonnées d'explications séparent logiquement les caractéristiques d'un modèle de ses entrées. Lorsque vous utilisez des gradients intégrés avec un Tensor d'entrée non différenciable par rapport au Tensor de sortie, vous devez également fournir la version encodée (et différenciable) de la caractéristique concernée.
Utilisez l'approche suivante si vous avez des Tensors d'entrée non différenciables, ou si des opérations non différenciables sont présentes dans votre graphe :
- Encodez les entrées non différenciables comme entrées différenciables.
- Définissez la valeur
input_tensor_name
sur le nom du Tensor non différenciable d'origine, et définissez la valeurencoded_tensor_name
sur le nom de sa version encodable et différenciable.
Fichier de métadonnées d'explications avec encodage
Prenons l'exemple d'un modèle qui possède une caractéristique de catégorie avec un Tensor d'entrée nommé zip_codes:0
. Comme les données d'entrée incluent des codes postaux en tant que chaînes, le Tensor d'entrée zip_codes:0
n'est pas différenciable. Si le modèle prétraite également ces données pour obtenir une représentation des codes postaux par encodage one-hot, le Tensor d'entrée après les opérations de prétraitement est différenciable. Pour le distinguer du Tensor d'entrée d'origine, vous pouvez le nommer zip_codes_embedding:0
.
Pour utiliser les données des deux Tensors d'entrée dans votre requête d'explications, définissez les métadonnées inputs
comme suit :
- Attribuez un nom explicite à la clé de la caractéristique d'entrée, par exemple
zip_codes
. - Définissez
input_tensor_name
sur le nom du Tensor d'origine,zip_codes:0
. - Définissez
encoded_tensor_name
sur le nom du Tensor après encodage one-hot,zip_codes_embedding:0
. - Définissez
encoding
surcombined_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"
}
Vous pouvez également définir input_tensor_name
sur le nom du Tensor d'entrée encodé et différenciable, et omettre le Tensor non différenciable d'origine. Spécifier deux Tensors permet d'effectuer les attributions sur chaque valeur de code postal plutôt que sur leur représentation après encodage one-hot. Dans cet exemple, vous devez exclure le Tensor d'origine (zip_codes:0
) et définir input_tensor_name
sur zip_codes_embedding:0
. Cette approche n'est pas recommandée, car les attributions de caractéristiques qui en résultent sont difficiles à interpréter.
Encodage
Pour activer l'encodage dans votre requête d'explications, spécifiez les paramètres d'encodage comme indiqué dans l'exemple précédent.
La fonctionnalité d'encodage permet d'inverser le processus des données encodées vers les données d'entrée pour les attributions, ce qui évite les opérations manuelles de post-traitement des attributions renvoyées. Actuellement, AI Explanations accepte les opérations combined_embedding
, où une caractéristique de longueur variable est combinée dans un élément intégré. L'opération tf.nn.embedding_lookup_sparse
est un exemple d'opération combined_embedding
.
Dans le cas d'une opération combined_embedding
:
Le Tensor d'entrée est encodé dans un tableau 1D. Exemple :
- Entrée :
["This", "is", "a", "test"]
- Encodé :
[0.1, 0.2, 0.3, 0.4]
Étape suivante
- Testez les exemples de notebooks.
- Découvrez comment déployer un modèle avec des explications.