![]() | ![]() | ![]() |
Suponga un escenario en el que configura una canalización de ML de producción para clasificar pingüinos. La canalización ingiere sus datos de entrenamiento, entrena y evalúa un modelo y lo envía a producción.
Sin embargo, cuando luego intentas usar este modelo con un conjunto de datos más grande que contiene diferentes tipos de pingüinos, observas que tu modelo no se comporta como se esperaba y comienza a clasificar las especies incorrectamente.
En este punto, te interesa conocer:
- ¿Cuál es la forma más eficiente de depurar el modelo cuando el único artefacto disponible es el modelo en producción?
- ¿Qué conjunto de datos de entrenamiento se utilizó para entrenar el modelo?
- ¿Qué entrenamiento llevó a este modelo erróneo?
- ¿Dónde están los resultados de la evaluación del modelo?
- ¿Dónde empezar a depurar?
ML Metadata (MLMD) es una biblioteca que aprovecha los metadatos asociados con los modelos ML para ayudarlo a responder estas preguntas y más. Una analogía útil es pensar en estos metadatos como el equivalente a iniciar sesión en el desarrollo de software. MLMD le permite realizar un seguimiento confiable de los artefactos y el linaje asociados con los diversos componentes de su canal de ML.
En este tutorial, configuraste un canal TFX para crear un modelo que clasifica a los pingüinos en tres especies según la masa corporal y la longitud y profundidad de sus culmens, y la longitud de sus aletas. Luego, usa MLMD para rastrear el linaje de los componentes de la tubería.
Tuberías TFX en Colab
Colab es un entorno de desarrollo ligero que se diferencia significativamente de un entorno de producción. En producción, puede tener varios componentes de canalización como ingesta de datos, transformación, entrenamiento de modelos, historiales de ejecución, etc. en múltiples sistemas distribuidos. Para este tutorial, debe tener en cuenta que existen diferencias significativas en el almacenamiento de orquestación y metadatos; todo se maneja localmente dentro de Colab. Obtenga más información sobre TFX en Colab aquí .
Configuración
Primero, instalamos e importamos los paquetes necesarios, configuramos rutas y descargamos datos.
Actualizar Pip
Para evitar actualizar Pip en un sistema cuando se ejecuta localmente, verifique que estemos ejecutando en Colab. Por supuesto, los sistemas locales se pueden actualizar por separado.
try:
import colab
!pip install --upgrade pip
except:
pass
Instalar e importar TFX
pip install -q -U --use-feature=2020-resolver tfx
Debe reiniciar el tiempo de ejecución de Colab después de instalar TFX. Seleccione Tiempo de ejecución> Reiniciar tiempo de ejecución en el menú Colab. Esto se debe a la forma en que Colab carga los paquetes.
No continúe con el resto de este tutorial sin antes reiniciar el tiempo de ejecución.
Importar otras bibliotecas
import os
import tempfile
import urllib
import pandas as pd
Importe clases de componentes TFX .
from tfx.components.evaluator.component import Evaluator
from tfx.components.example_gen.csv_example_gen.component import CsvExampleGen
from tfx.components.pusher.component import Pusher
from tfx.components.schema_gen.component import SchemaGen
from tfx.components.statistics_gen.component import StatisticsGen
from tfx.components.trainer.component import Trainer
from tfx.components.base import executor_spec
from tfx.components.trainer.executor import GenericExecutor
from tfx.orchestration.experimental.interactive.interactive_context import InteractiveContext
from tfx.proto import evaluator_pb2
from tfx.proto import pusher_pb2
from tfx.proto import trainer_pb2
from tfx.utils.dsl_utils import external_input
from tensorflow_metadata.proto.v0 import anomalies_pb2
from tensorflow_metadata.proto.v0 import schema_pb2
from tensorflow_metadata.proto.v0 import statistics_pb2
import tensorflow_model_analysis as tfma
from tfx.components import ResolverNode
from tfx.dsl.experimental import latest_blessed_model_resolver
from tfx.types import Channel
from tfx.types.standard_artifacts import Model
from tfx.types.standard_artifacts import ModelBlessing
Importe la biblioteca MLMD.
import ml_metadata as mlmd
from ml_metadata.proto import metadata_store_pb2
Descarga el conjunto de datos
En este colab, usamos el conjunto de datos de Palmer Penguins que se puede encontrar en Github . Procesamos el conjunto de datos int32
registros incompletos, descartamos sex
columnas de island
y sex
y convertimos las etiquetas a int32
. El conjunto de datos contiene 334 registros de la masa corporal y la longitud y profundidad de los culmens de los pingüinos, y la longitud de sus aletas. Utiliza estos datos para clasificar a los pingüinos en una de tres especies.
DATA_PATH = 'https://raw.githubusercontent.com/tensorflow/tfx/master/tfx/examples/penguin/data/penguins_processed.csv'
_data_root = tempfile.mkdtemp(prefix='tfx-data')
_data_filepath = os.path.join(_data_root, "penguins_processed.csv")
urllib.request.urlretrieve(DATA_PATH, _data_filepath)
('/tmp/tfx-datap7jk35hz/penguins_processed.csv', <http.client.HTTPMessage at 0x7fe4eef4c160>)
Crear un contexto interactivo
Para ejecutar componentes TFX de forma interactiva en este cuaderno, cree un InteractiveContext
. InteractiveContext
utiliza un directorio temporal con una instancia de base de datos MLMD efímera. Tenga en cuenta que las llamadas a InteractiveContext
no son operaciones fuera del entorno de Colab.
En general, es una buena práctica agrupar ejecuciones de canalizaciones similares en un Context
.
interactive_context = InteractiveContext()
WARNING:absl:InteractiveContext pipeline_root argument not provided: using temporary directory /tmp/tfx-interactive-2021-02-11T13_16_43.521464-6hj93f0i as root for pipeline outputs. WARNING:absl:InteractiveContext metadata_connection_config not provided: using SQLite ML Metadata database at /tmp/tfx-interactive-2021-02-11T13_16_43.521464-6hj93f0i/metadata.sqlite.
Construya el oleoducto TFX
Una canalización TFX consta de varios componentes que realizan diferentes aspectos del flujo de trabajo de AA. En este cuaderno, usted crea y ejecuta los ExampleGen
, StatisticsGen
, SchemaGen
y Trainer
y usa el componente Evaluator
y Pusher
para evaluar e impulsar el modelo entrenado.
Consulte el tutorial de componentes para obtener más información sobre los componentes de la canalización TFX.
Crear una instancia y ejecutar el componente ExampleGen
input_data = external_input(_data_root)
example_gen = CsvExampleGen(input=input_data)
interactive_context.run(example_gen)
WARNING:absl:From <ipython-input-1-e4ef519b0b92>:1: external_input (from tfx.utils.dsl_utils) is deprecated and will be removed in a future version. Instructions for updating: external_input is deprecated, directly pass the uri to ExampleGen. WARNING:absl:The "input" argument to the CsvExampleGen component has been deprecated by "input_base". Please update your usage as support for this argument will be removed soon. WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features. WARNING:apache_beam.io.tfrecordio:Couldn't find python-snappy so the implementation of _TFRecordUtil._masked_crc32c is not as fast as it could be.
Cree una instancia y ejecute el componente StatisticsGen
statistics_gen = StatisticsGen(examples=example_gen.outputs['examples'])
interactive_context.run(statistics_gen)
Crear una instancia y ejecutar el componente SchemaGen
infer_schema = SchemaGen(
statistics=statistics_gen.outputs['statistics'], infer_feature_shape=True)
interactive_context.run(infer_schema)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_data_validation/utils/stats_util.py:247: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version. Instructions for updating: Use eager execution and: `tf.data.TFRecordDataset(path)` WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_data_validation/utils/stats_util.py:247: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version. Instructions for updating: Use eager execution and: `tf.data.TFRecordDataset(path)`
Crear una instancia y ejecutar el componente Entrenador
# Define the module file for the Trainer component
trainer_module_file = 'penguin_trainer.py'
%%writefile {trainer_module_file}
# Define the training algorithm for the Trainer module file
import os
from typing import List, Text
import tensorflow as tf
from tensorflow import keras
from tfx.components.trainer.executor import TrainerFnArgs
from tfx.components.trainer.fn_args_utils import FnArgs
# Features used for classification - culmen length and depth, flipper length,
# body mass, and species.
_FEATURES = {
'culmen_length_mm': tf.io.FixedLenFeature([], dtype=tf.float32),
'culmen_depth_mm': tf.io.FixedLenFeature([], dtype=tf.float32),
'flipper_length_mm': tf.io.FixedLenFeature([], dtype=tf.float32),
'body_mass_g': tf.io.FixedLenFeature([], dtype=tf.float32),
'species': tf.io.FixedLenFeature([], dtype=tf.int64)
}
_LABEL_KEY = 'species'
_FEATURE_KEYS = [
'culmen_length_mm', 'culmen_depth_mm', 'flipper_length_mm', 'body_mass_g'
]
def _gzip_reader_fn(filenames):
return tf.data.TFRecordDataset(filenames, compression_type='GZIP')
def _input_fn(file_pattern: List[Text], batch_size: int = 200):
dataset = tf.data.experimental.make_batched_features_dataset(
file_pattern=file_pattern,
batch_size=batch_size,
features=_FEATURES,
reader=_gzip_reader_fn,
label_key=_LABEL_KEY)
return dataset
def _build_keras_model():
inputs = [keras.layers.Input(shape=(1,), name=f) for f in _FEATURE_KEYS]
d = keras.layers.concatenate(inputs)
d = keras.layers.Dense(8, activation='relu')(d)
d = keras.layers.Dense(8, activation='relu')(d)
outputs = keras.layers.Dense(3, activation='softmax')(d)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=[keras.metrics.SparseCategoricalAccuracy()])
return model
def run_fn(fn_args: TrainerFnArgs):
train_dataset = _input_fn(fn_args.train_files, batch_size=10)
eval_dataset = _input_fn(fn_args.eval_files, batch_size=10)
model = _build_keras_model()
model.fit(
train_dataset,
epochs=int(fn_args.train_steps / 20),
steps_per_epoch=20,
validation_data=eval_dataset,
validation_steps=fn_args.eval_steps)
model.save(fn_args.serving_model_dir, save_format='tf')
Writing penguin_trainer.py
Ejecute el componente Trainer
.
trainer = Trainer(
module_file=os.path.abspath(trainer_module_file),
custom_executor_spec=executor_spec.ExecutorClassSpec(GenericExecutor),
examples=example_gen.outputs['examples'],
schema=infer_schema.outputs['schema'],
train_args=trainer_pb2.TrainArgs(num_steps=100),
eval_args=trainer_pb2.EvalArgs(num_steps=50))
interactive_context.run(trainer)
WARNING:absl:From <ipython-input-1-d2af3312f9a2>:3: The name tfx.components.base.executor_spec.ExecutorClassSpec is deprecated. Please use tfx.dsl.components.base.executor_spec.ExecutorClassSpec instead. Epoch 1/5 20/20 [==============================] - 1s 33ms/step - loss: 1.0484 - sparse_categorical_accuracy: 0.4277 - val_loss: 1.0130 - val_sparse_categorical_accuracy: 0.4700 Epoch 2/5 20/20 [==============================] - 0s 8ms/step - loss: 1.0075 - sparse_categorical_accuracy: 0.4838 - val_loss: 0.9657 - val_sparse_categorical_accuracy: 0.6900 Epoch 3/5 20/20 [==============================] - 0s 8ms/step - loss: 0.9473 - sparse_categorical_accuracy: 0.7441 - val_loss: 0.9347 - val_sparse_categorical_accuracy: 0.7700 Epoch 4/5 20/20 [==============================] - 0s 8ms/step - loss: 0.8869 - sparse_categorical_accuracy: 0.8405 - val_loss: 0.9047 - val_sparse_categorical_accuracy: 0.7700 Epoch 5/5 20/20 [==============================] - 0s 8ms/step - loss: 0.8597 - sparse_categorical_accuracy: 0.8060 - val_loss: 0.8736 - val_sparse_categorical_accuracy: 0.7700 INFO:tensorflow:Assets written to: /tmp/tfx-interactive-2021-02-11T13_16_43.521464-6hj93f0i/Trainer/model/4/serving_model_dir/assets INFO:tensorflow:Assets written to: /tmp/tfx-interactive-2021-02-11T13_16_43.521464-6hj93f0i/Trainer/model/4/serving_model_dir/assets
Evaluar e impulsar el modelo
Utilice el componente Evaluator
para evaluar y "bendecir" el modelo antes de utilizar el componente Pusher
para enviar el modelo a un directorio de publicación.
_serving_model_dir = os.path.join(tempfile.mkdtemp(),
'serving_model/penguins_classification')
eval_config = tfma.EvalConfig(
model_specs=[
tfma.ModelSpec(label_key='species', signature_name='serving_default')
],
metrics_specs=[
tfma.MetricsSpec(metrics=[
tfma.MetricConfig(
class_name='SparseCategoricalAccuracy',
threshold=tfma.MetricThreshold(
value_threshold=tfma.GenericValueThreshold(
lower_bound={'value': 0.6})))
])
],
slicing_specs=[tfma.SlicingSpec()])
evaluator = Evaluator(
examples=example_gen.outputs['examples'],
model=trainer.outputs['model'],
schema=infer_schema.outputs['schema'],
eval_config=eval_config)
interactive_context.run(evaluator)
pusher = Pusher(
model=trainer.outputs['model'],
model_blessing=evaluator.outputs['blessing'],
push_destination=pusher_pb2.PushDestination(
filesystem=pusher_pb2.PushDestination.Filesystem(
base_directory=_serving_model_dir)))
interactive_context.run(pusher)
La ejecución de la canalización TFX llena la base de datos de MLMD. En la siguiente sección, utiliza la API de MLMD para consultar esta base de datos en busca de información de metadatos.
Consultar la base de datos de MLMD
La base de datos MLMD almacena tres tipos de metadatos:
- Metadatos sobre la información de la canalización y el linaje asociada con los componentes de la canalización
- Metadatos sobre artefactos que se generaron durante la ejecución de la canalización
- Metadatos sobre las ejecuciones del pipeline
Una canalización de entorno de producción típica sirve a varios modelos a medida que llegan nuevos datos. Cuando encuentre resultados erróneos en los modelos servidos, puede consultar la base de datos MLMD para aislar los modelos erróneos. Luego puede rastrear el linaje de los componentes de la tubería que corresponden a estos modelos para depurar sus modelos
Configure el almacén de metadatos (MD) con el InteractiveContext
definido previamente para consultar la base de datos MLMD.
connection_config = interactive_context.metadata_connection_config
store = mlmd.MetadataStore(connection_config)
# All TFX artifacts are stored in the base directory
base_dir = connection_config.sqlite.filename_uri.split('metadata.sqlite')[0]
Cree algunas funciones auxiliares para ver los datos de la tienda MD.
def display_types(types):
# Helper function to render dataframes for the artifact and execution types
table = {'id': [], 'name': []}
for a_type in types:
table['id'].append(a_type.id)
table['name'].append(a_type.name)
return pd.DataFrame(data=table)
def display_artifacts(store, artifacts):
# Helper function to render dataframes for the input artifacts
table = {'artifact id': [], 'type': [], 'uri': []}
for a in artifacts:
table['artifact id'].append(a.id)
artifact_type = store.get_artifact_types_by_id([a.type_id])[0]
table['type'].append(artifact_type.name)
table['uri'].append(a.uri.replace(base_dir, './'))
return pd.DataFrame(data=table)
def display_properties(store, node):
# Helper function to render dataframes for artifact and execution properties
table = {'property': [], 'value': []}
for k, v in node.properties.items():
table['property'].append(k)
table['value'].append(
v.string_value if v.HasField('string_value') else v.int_value)
for k, v in node.custom_properties.items():
table['property'].append(k)
table['value'].append(
v.string_value if v.HasField('string_value') else v.int_value)
return pd.DataFrame(data=table)
Primero, consulte la tienda MD para obtener una lista de todos sus ArtifactTypes
almacenados.
display_types(store.get_artifact_types())
A continuación, consulte todos los artefactos PushedModel
.
pushed_models = store.get_artifacts_by_type("PushedModel")
display_artifacts(store, pushed_models)
Consulte en la tienda MD el último modelo enviado. Este tutorial tiene solo un modelo empujado.
pushed_model = pushed_models[-1]
display_properties(store, pushed_model)
Uno de los primeros pasos en la depuración de un modelo empujado es observar qué modelo entrenado se empuja y ver qué datos de entrenamiento se utilizan para entrenar ese modelo.
MLMD proporciona API transversales para recorrer el gráfico de procedencia, que puede utilizar para analizar la procedencia del modelo.
def get_one_hop_parent_artifacts(store, artifacts):
# Get a list of artifacts within a 1-hop of the artifacts of interest
artifact_ids = [artifact.id for artifact in artifacts]
executions_ids = set(
event.execution_id
for event in store.get_events_by_artifact_ids(artifact_ids)
if event.type == metadata_store_pb2.Event.OUTPUT)
artifacts_ids = set(
event.artifact_id
for event in store.get_events_by_execution_ids(executions_ids)
if event.type == metadata_store_pb2.Event.INPUT)
return [artifact for artifact in store.get_artifacts_by_id(artifacts_ids)]
Consulte los artefactos principales para el modelo enviado.
parent_artifacts = get_one_hop_parent_artifacts(store, [pushed_model])
display_artifacts(store, parent_artifacts)
Consulte las propiedades del modelo.
exported_model = parent_artifacts[0]
display_properties(store, exported_model)
Consulte los artefactos ascendentes del modelo.
model_parents = get_one_hop_parent_artifacts(store, [exported_model])
display_artifacts(store, model_parents)
Obtén los datos de entrenamiento con los que se entrenó el modelo.
used_data = model_parents[0]
display_properties(store, used_data)
Ahora que tiene los datos de entrenamiento con los que se entrenó el modelo, vuelva a consultar la base de datos para encontrar el paso de entrenamiento (ejecución). Consulte la tienda MD para obtener una lista de los tipos de ejecución registrados.
display_types(store.get_execution_types())
El paso de entrenamiento es ExecutionType
llamado tfx.components.trainer.component.Trainer
. Atraviesa la tienda MD para que el entrenador funcione que corresponde al modelo empujado.
def find_producer_execution(store, artifact):
executions_ids = set(
event.execution_id
for event in store.get_events_by_artifact_ids([artifact.id])
if event.type == metadata_store_pb2.Event.OUTPUT)
return store.get_executions_by_id(executions_ids)[0]
trainer = find_producer_execution(store, exported_model)
display_properties(store, trainer)
Resumen
En este tutorial, aprendió cómo puede aprovechar MLMD para rastrear el linaje de sus componentes de canalización TFX y resolver problemas.
Para obtener más información sobre cómo usar MLMD, consulte estos recursos adicionales: