Cuando trabajas con modelos de TensorFlow con entrenamiento personalizado, necesitas información específica para guardar el modelo y configurar las explicaciones.
Si quieres usar Vertex Explainable AI con un modelo tabular de AutoML, no tienes que hacer ninguna configuración. Vertex AI configura automáticamente el modelo para Vertex Explainable AI. Salta este documento y consulta Cómo obtener explicaciones.
En esta guía se proporciona la información que necesitas para entrenar un modelo de TensorFlow y asegurarte de que puedes usarlo con Vertex Explainable AI. En concreto, la guía trata los siguientes temas:
Encontrar los nombres de los tensores de entrada y salida durante el entrenamiento que necesitas especificar al configurar un recurso
Model
para Vertex Explainable AI. Esto incluye la creación y la búsqueda de los tensores adecuados para Vertex Explainable AI en casos especiales en los que los típicos no funcionan.Exportar tu modelo de TensorFlow como un SavedModel de TensorFlow compatible con Vertex Explainable AI.
Buscar los nombres de los tensores de entrada y salida de un SavedModel de TensorFlow que ya se ha exportado. Esto puede ser útil si no tienes acceso al código de entrenamiento del modelo.
Buscar nombres de tensores de entrada y salida durante el entrenamiento
Cuando usas un contenedor prediseñado de TensorFlow para ofrecer predicciones, debes conocer los nombres de los tensores de entrada y de salida de tu modelo. Estos nombres se especifican como parte de un mensaje ExplanationMetadata
cuando configuras un Model
para Vertex Explainable AI.
Si tu modelo de TensorFlow cumple los siguientes criterios, puedes usar el "método básico" que se describe en la siguiente sección para determinar estos nombres de tensor durante el entrenamiento:
- Tus entradas no están en formato serializado
- Cada entrada de
SignatureDef
del modelo contiene el valor de la característica directamente (pueden ser valores numéricos o cadenas). - Las salidas son valores numéricos que se tratan como datos numéricos. Esto excluye los IDs de clase, que se consideran datos categóricos.
Si tu modelo no cumple estos criterios, consulta la sección Ajustar el código de entrenamiento y buscar nombres de tensor en casos especiales.
El método básico
Durante el entrenamiento, imprime el atributo name
de los tensores de entrada y de salida de tu modelo. En el ejemplo siguiente, el campo name
de la capa de Keras genera el nombre del tensor subyacente que necesitas para tu 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)
Al ejecutar este código Python, se muestra el siguiente resultado:
input_tensor_name: input_1:0
output_tensor_name: dense_1/Sigmoid:0
Después, puedes usar input_1:0
como nombre del tensor de entrada y dense_1/Sigmod:0
como nombre del tensor de salida al configurar tu Model
para las explicaciones.
Ajustar el código de entrenamiento y buscar nombres de tensores en casos especiales
Hay algunos casos habituales en los que los tensores de entrada y salida de tu ExplanationMetadata
no deben ser los mismos que los de tu SignatureDef
:
- Has serializado las entradas
- Tu gráfico incluye operaciones de preprocesamiento
- Las salidas de servicio no son probabilidades, logits u otros tipos de tensores de coma flotante
En estos casos, debes usar enfoques diferentes para encontrar los tensores de entrada y salida adecuados. El objetivo general es encontrar los tensores correspondientes a los valores de las características que quieres explicar para las entradas y los tensores correspondientes a los logits (preactivación), las probabilidades (postactivación) o cualquier otra representación de las salidas.
Casos especiales de tensores de entrada
Las entradas de los metadatos de la explicación son diferentes de las de la publicación
SignatureDef
si usas una entrada serializada para alimentar el modelo o si tu
gráfico incluye operaciones de preprocesamiento.
Entradas serializadas
Los SavedModels de TensorFlow pueden aceptar una gran variedad de entradas complejas, como las siguientes:
- Mensajes tf.Example serializados
- Cadenas JSON
- Cadenas codificadas en Base64 (para representar datos de imagen)
Si tu modelo acepta entradas serializadas como estas, no podrás usar estos tensores directamente como entrada para tus explicaciones o podrías obtener resultados sin sentido. En su lugar, debe buscar los tensores de entrada posteriores que se introducen en las columnas de características de su modelo.
Cuando exportas tu modelo, puedes añadir una operación de análisis a tu gráfico de TensorFlow llamando a una función de análisis en tu función de entrada de servicio. Puedes encontrar funciones de análisis en el módulo tf.io. Estas funciones de análisis suelen devolver tensores como respuesta, y estos tensores son mejores selecciones para los metadatos de explicación.
Por ejemplo, puedes usar tf.parse_example() al exportar el modelo. Toma un mensaje tf.Example serializado y devuelve un diccionario de tensores que se introducen en las columnas de características. Puedes usar su salida para rellenar los metadatos de explicación. Si algunas de estas salidas son tf.SparseTensor, que es una tupla con nombre que consta de 3 tensores, debes obtener los nombres de los tensores de índices, valores y dense_shape, y rellenar los campos correspondientes en los metadatos.
En el siguiente ejemplo se muestra cómo obtener el nombre del tensor de entrada después de una operación de decodificación:
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)
Entradas de preprocesamiento
Si tu gráfico de modelo contiene algunas operaciones de preprocesamiento, puede que quieras obtener explicaciones sobre los tensores después del paso de preprocesamiento. En este caso, puede obtener los nombres de esos tensores mediante la propiedad name
de tf.Tensor y colocarlos en los metadatos de la explicación:
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)
El nombre del tensor decodificado es input_pixels:0
.
Casos especiales de tensores de salida
En la mayoría de los casos, las salidas de tu SignatureDef
de servicio son probabilidades o logits.
Si tu modelo atribuye probabilidades, pero quieres explicar los valores de logit, debes buscar los nombres de los tensores de salida adecuados que correspondan a los logits.
Si tu SignatureDef
tiene resultados que no son probabilidades ni logits, consulta la operación de probabilidades en el gráfico de entrenamiento.
Es poco probable que se dé en los modelos de Keras. Si esto ocurre, puedes usar TensorBoard (u otras herramientas de visualización de gráficos) para encontrar los nombres de los tensores de salida correctos.
Consideraciones especiales para los degradados integrados
Si quieres usar la atribución de funciones con gradientes integrados de Vertex Explainable AI, debes asegurarte de que las entradas sean diferenciables con respecto a la salida.
Los metadatos de explicación separan lógicamente las características de un modelo de sus entradas. Cuando se usan gradientes integrados con un tensor de entrada que no es diferenciable con respecto al tensor de salida, también debes proporcionar la versión codificada (y diferenciable) de esa característica.
Sigue este procedimiento si tienes tensores de entrada no diferenciables o si tienes operaciones no diferenciables en tu gráfico:
- Codifica las entradas no diferenciables como entradas diferenciables.
- Asigna a
input_tensor_name
el nombre del tensor de entrada original no diferenciable y asigna aencoded_tensor_name
el nombre de su versión codificada y diferenciable.
Archivo de metadatos de explicación con codificación
Por ejemplo, supongamos que tiene un modelo con una característica categórica con un tensor de entrada llamado zip_codes:0
. Como los datos de entrada incluyen códigos postales como cadenas, el tensor de entrada zip_codes:0
no es diferenciable. Si el modelo también preprocesa estos datos para obtener una representación de codificación one-hot de los códigos postales, el tensor de entrada después del preprocesamiento será diferenciable. Para distinguirlo del tensor de entrada original, puedes llamarlo zip_codes_embedding:0
.
Para usar los datos de ambos tensores de entrada en tu solicitud de explicaciones, define ExplanationMetadata
de la siguiente manera al configurar Model
para las explicaciones:
- Asigna a la clave de la función de entrada un nombre significativo, como
zip_codes
. - Asigna a
input_tensor_name
el nombre del tensor original,zip_codes:0
. - Asigna
encoded_tensor_name
al nombre del tensor después de la codificación one-hot,zip_codes_embedding:0
. - Asigna el valor
COMBINED_EMBEDDING
aencoding
.
{
"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"
}
}
}
También puedes asignar a input_tensor_name
el nombre del tensor de entrada codificado y diferenciable, y omitir el tensor original no diferenciable. La ventaja de proporcionar ambos tensores es que las atribuciones se pueden hacer a valores de código postal individuales en lugar de a su representación de codificación one-hot. En este ejemplo, excluirías el tensor original (zip_codes:0
) y asignarías el valor zip_codes_embedding:0
a input_tensor_name
. No se recomienda este enfoque, ya que sería difícil determinar las atribuciones de las funciones resultantes.
Codificación
Para habilitar la codificación de tu Model
, especifica los ajustes de codificación tal y como se muestra en el ejemplo anterior.
La función de codificación ayuda a invertir el proceso de los datos codificados a los datos de entrada para las atribuciones, lo que elimina la necesidad de posprocesar las atribuciones devueltas manualmente. Consulta la lista de codificaciones que admite Vertex Explainable AI.
En la codificación COMBINED_EMBEDDING
, el tensor de entrada se codifica en una matriz 1D.
Por ejemplo:
- Entrada:
["This", "is", "a", "test"]
- Entrada codificada:
[0.1, 0.2, 0.3, 0.4]
Exportar SavedModels de TensorFlow para Vertex Explainable AI
Después de entrenar un modelo de TensorFlow, expórtalo como SavedModel.
El módulo SavedModel de TensorFlow contiene tu modelo de TensorFlow entrenado, junto con firmas, variables y otros recursos serializados necesarios para ejecutar el gráfico. Cada SignatureDef
de SavedModel identifica una función de tu gráfico que acepta entradas de tensor y produce salidas de tensor.
Para asegurarte de que tu SavedModel es compatible con Vertex Explainable AI, sigue las instrucciones de una de las siguientes secciones, en función de si usas TensorFlow 2 o TensorFlow 1.
TensorFlow 2
Si trabajas con TensorFlow 2.x, usa tf.saved_model.save
para guardar tu modelo. Puedes especificar firmas de entrada al guardar tu modelo. Si tienes una firma de entrada, Vertex Explainable AI usa la función de servicio predeterminada para tus solicitudes de explicaciones. Si tienes más de una firma de entrada, debes especificar la firma de tu función predeterminada de servicio al guardar el modelo:
tf.saved_model.save(m, model_dir, signatures={
'serving_default': serving_fn,
'xai_model': model_fn # Required for XAI
})
En este caso, Vertex Explainable AI usa la firma de función del modelo que guardaste con la clave xai_model
para tu solicitud de explicaciones. Usa la cadena exacta xai_model
para la clave.
Si usas una función de preprocesamiento, también debes especificar las firmas de tu función de preprocesamiento y de tu función de modelo. Debes usar las cadenas exactas xai_preprocess
y xai_model
como claves:
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
})
En este caso, Vertex Explainable AI usa tu función de preprocesamiento y tu función de modelo para tus solicitudes de explicación. Asegúrate de que el resultado de tu función de preprocesamiento coincida con la entrada que espera tu función de modelo.
Consulta más información sobre cómo especificar firmas de servicio en TensorFlow.
TensorFlow 1.15
Si trabajas con TensorFlow 1.15, no uses
tf.saved_model.save
.
Vertex Explainable AI no admite modelos de TensorFlow 1 guardados con este método
Si creas y entrenas tu modelo en Keras, debes convertirlo en un Estimador de TensorFlow y, a continuación, exportarlo a un SavedModel. En esta sección se explica cómo guardar un modelo.
Una vez que hayas creado, compilado, entrenado y evaluado tu modelo de Keras, debes hacer lo siguiente:
- Convierte el modelo de Keras en un Estimator de TensorFlow con
tf.keras.estimator.model_to_estimator
- Proporciona una función de entrada de servicio mediante
tf.estimator.export.build_raw_serving_input_receiver_fn
- Exporta el modelo como SavedModel con
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)
Obtener nombres de tensor de SignatureDef
de SavedModel
Puedes usar el SignatureDef
de un SavedModel de TensorFlow para preparar los metadatos de la explicación, siempre que cumpla los criterios del método básico descritos en una sección anterior. Esto puede ser útil si no tienes acceso al código de entrenamiento que ha generado el modelo.
Para inspeccionar el SignatureDef
de tu SavedModel, puedes usar la CLI de SavedModel. Consulta más información sobre cómo usar la CLI de SavedModel.
Veamos el siguiente ejemplo 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
El gráfico tiene un tensor de entrada llamado x:0
y un tensor de salida llamado dense/Softmax:0
. Cuando configures tu Model
para
explicaciones, usa x:0
como nombre del tensor de entrada y dense/Softmax:0
como nombre del tensor de salida en el mensaje ExplanationMetadata
.
Siguientes pasos
- Usa los nombres de los tensores de entrada y salida para configurar un
Model
para Vertex Explainable AI - Prueba un cuaderno de ejemplo que muestre Vertex Explainable AI con datos tabulares o datos de imágenes.