Kỹ thuật ML tốt hơn với Siêu dữ liệu ML

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Giả sử một tình huống trong đó bạn thiết lập một đường ống ML sản xuất để phân loại chim cánh cụt. Hệ thống này nhập dữ liệu đào tạo của bạn, đào tạo và đánh giá một mô hình và đưa nó vào sản xuất.

Tuy nhiên, sau đó, khi bạn thử sử dụng mô hình này với tập dữ liệu lớn hơn chứa các loại chim cánh cụt khác nhau, bạn nhận thấy rằng mô hình của mình không hoạt động như mong đợi và bắt đầu phân loại loài không chính xác.

Tại thời điểm này, bạn muốn biết:

  • Cách hiệu quả nhất để gỡ lỗi mô hình khi hiện vật duy nhất có sẵn là mô hình đang được sản xuất?
  • Tập dữ liệu đào tạo nào đã được sử dụng để đào tạo mô hình?
  • Quá trình đào tạo nào đã dẫn đến mô hình sai lầm này?
  • Kết quả đánh giá mô hình ở đâu?
  • Bắt đầu gỡ lỗi ở đâu?

ML Metadata (MLMD) là một thư viện đó thúc đẩy các siêu dữ liệu liên quan đến mô hình ML để giúp bạn trả lời những câu hỏi này và nhiều hơn nữa. Một phép tương tự hữu ích là coi siêu dữ liệu này tương đương với việc đăng nhập phát triển phần mềm. MLMD cho phép bạn theo dõi một cách đáng tin cậy các hiện vật và dòng dõi liên quan đến các thành phần khác nhau của đường ống ML của bạn.

Trong hướng dẫn này, bạn thiết lập Đường ống TFX để tạo một mô hình phân loại chim cánh cụt thành ba loài dựa trên khối lượng cơ thể, chiều dài và độ sâu của thân cũng như chiều dài chân chèo của chúng. Sau đó, bạn sử dụng MLMD để theo dõi nguồn gốc của các thành phần đường ống.

Đường ống TFX trong Colab

Colab là một môi trường phát triển nhẹ khác biệt đáng kể với môi trường sản xuất. Trong sản xuất, bạn có thể có các thành phần đường ống khác nhau như nhập dữ liệu, chuyển đổi, đào tạo mô hình, lịch sử chạy, v.v. trên nhiều hệ thống phân tán. Đối với hướng dẫn này, bạn nên biết rằng tồn tại những khác biệt đáng kể trong bộ điều phối và lưu trữ siêu dữ liệu - tất cả đều được xử lý cục bộ trong Colab. Tìm hiểu thêm về TFX trong Colab đây .

Thành lập

Đầu tiên, chúng tôi cài đặt và nhập các gói cần thiết, thiết lập đường dẫn và tải xuống dữ liệu.

Nâng cấp Pip

Để tránh nâng cấp Pip trong hệ thống khi chạy cục bộ, hãy kiểm tra để đảm bảo rằng chúng tôi đang chạy trong Colab. Hệ thống cục bộ tất nhiên có thể được nâng cấp riêng.

try:
  import colab
  !pip install --upgrade pip
except:
  pass

Cài đặt và nhập TFX

pip install -q -U tfx

Nhập gói

Bạn có khởi động lại thời gian chạy không?

Nếu bạn đang sử dụng Google Colab, lần đầu tiên bạn chạy ô ở trên, bạn phải khởi động lại thời gian chạy bằng cách nhấp vào phía trên nút "RESTART RUNTIME" hoặc sử dụng menu "Runtime> Restart runtime ...". Điều này là do cách Colab tải các gói.

import os
import tempfile
import urllib
import pandas as pd

import tensorflow_model_analysis as tfma
from tfx.orchestration.experimental.interactive.interactive_context import InteractiveContext

Kiểm tra các phiên bản TFX và MLMD.

from tfx import v1 as tfx
print('TFX version: {}'.format(tfx.__version__))
import ml_metadata as mlmd
print('MLMD version: {}'.format(mlmd.__version__))
TFX version: 1.4.0
MLMD version: 1.4.0

Tải xuống tập dữ liệu

Trong colab này, chúng tôi sử dụng các dữ liệu Palmer Penguins có thể được tìm thấy trên Github . Chúng tôi xử lý số liệu bằng cách bỏ đi bất cứ hồ sơ chưa đầy đủ, và giọt islandsex cột, và chuyển đổi nhãn để int32 . Bộ dữ liệu bao gồm 334 bản ghi về khối lượng cơ thể, chiều dài và độ sâu của thân chim cánh cụt, và chiều dài chân chèo của chúng. Bạn sử dụng dữ liệu này để phân loại chim cánh cụt thành một trong ba loài.

DATA_PATH = 'https://raw.githubusercontent.com/tensorflow/tfx/master/tfx/examples/penguin/data/labelled/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-datal9104odr/penguins_processed.csv',
 <http.client.HTTPMessage at 0x7f9c6d8d2290>)

Tạo một InteractiveContext

Để chạy các thành phần tương tác TFX trong sổ tay này, tạo ra một InteractiveContext . Các InteractiveContext sử dụng thư mục tạm thời với một thể hiện cơ sở dữ liệu MLMD phù du. Lưu ý rằng các cuộc gọi đến InteractiveContext không-ops bên ngoài môi trường Colab.

Nói chung, đó là một thực hành tốt để nhóm đường ống chạy tương tự theo một Context .

interactive_context = InteractiveContext()
WARNING:absl:InteractiveContext pipeline_root argument not provided: using temporary directory /tmp/tfx-interactive-2021-12-05T11_15_56.285625-5hcexlo8 as root for pipeline outputs.
WARNING:absl:InteractiveContext metadata_connection_config not provided: using SQLite ML Metadata database at /tmp/tfx-interactive-2021-12-05T11_15_56.285625-5hcexlo8/metadata.sqlite.

Xây dựng đường ống TFX

Một đường ống TFX bao gồm một số thành phần thực hiện các khía cạnh khác nhau của quy trình ML. Trong máy tính xách tay này, bạn tạo và chạy ExampleGen , StatisticsGen , SchemaGen , và Trainer các thành phần và sử dụng EvaluatorPusher thành phần để đánh giá và thúc đẩy mô hình đào tạo.

Hãy tham khảo các thành phần hướng dẫn để biết thêm thông tin về các thành phần đường ống TFX.

Khởi tạo và chạy Thành phần exampleGen

example_gen = tfx.components.CsvExampleGen(input_base=_data_root)
interactive_context.run(example_gen)
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:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
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.

Khởi tạo và chạy Thành phần StatisticsGen

statistics_gen = tfx.components.StatisticsGen(
    examples=example_gen.outputs['examples'])
interactive_context.run(statistics_gen)
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.

Khởi tạo và chạy Thành phần SchemaGen

infer_schema = tfx.components.SchemaGen(
    statistics=statistics_gen.outputs['statistics'], infer_feature_shape=True)
interactive_context.run(infer_schema)
WARNING: Logging before InitGoogleLogging() is written to STDERR
I1205 11:16:00.941947  6108 rdbms_metadata_access_object.cc:686] No property is defined for the Type

Khởi tạo và chạy Thành phần Trainer

# 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 import v1 as tfx
from tfx_bsl.public import tfxio

from tensorflow_metadata.proto.v0 import schema_pb2

# Features used for classification - culmen length and depth, flipper length,
# body mass, and species.

_LABEL_KEY = 'species'

_FEATURE_KEYS = [
    'culmen_length_mm', 'culmen_depth_mm', 'flipper_length_mm', 'body_mass_g'
]


def _input_fn(file_pattern: List[Text],
              data_accessor: tfx.components.DataAccessor,
              schema: schema_pb2.Schema, batch_size: int) -> tf.data.Dataset:
  return data_accessor.tf_dataset_factory(
      file_pattern,
      tfxio.TensorFlowDatasetOptions(
          batch_size=batch_size, label_key=_LABEL_KEY), schema).repeat()


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)(d)
  model = keras.Model(inputs=inputs, outputs=outputs)
  model.compile(
      optimizer=keras.optimizers.Adam(1e-2),
      loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
      metrics=[keras.metrics.SparseCategoricalAccuracy()])
  return model


def run_fn(fn_args: tfx.components.FnArgs):
  schema = schema_pb2.Schema()
  tfx.utils.parse_pbtxt_file(fn_args.schema_path, schema)
  train_dataset = _input_fn(
      fn_args.train_files, fn_args.data_accessor, schema, batch_size=10)
  eval_dataset = _input_fn(
      fn_args.eval_files, fn_args.data_accessor, schema, 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

Chạy Trainer thành phần.

trainer = tfx.components.Trainer(
    module_file=os.path.abspath(trainer_module_file),
    examples=example_gen.outputs['examples'],
    schema=infer_schema.outputs['schema'],
    train_args=tfx.proto.TrainArgs(num_steps=100),
    eval_args=tfx.proto.EvalArgs(num_steps=50))
interactive_context.run(trainer)
running bdist_wheel
running build
running build_py
creating build
creating build/lib
copying penguin_trainer.py -> build/lib
installing to /tmp/tmpum1crtxy
running install
running install_lib
copying build/lib/penguin_trainer.py -> /tmp/tmpum1crtxy
running install_egg_info
running egg_info
creating tfx_user_code_Trainer.egg-info
writing tfx_user_code_Trainer.egg-info/PKG-INFO
writing dependency_links to tfx_user_code_Trainer.egg-info/dependency_links.txt
writing top-level names to tfx_user_code_Trainer.egg-info/top_level.txt
writing manifest file 'tfx_user_code_Trainer.egg-info/SOURCES.txt'
reading manifest file 'tfx_user_code_Trainer.egg-info/SOURCES.txt'
writing manifest file 'tfx_user_code_Trainer.egg-info/SOURCES.txt'
Copying tfx_user_code_Trainer.egg-info to /tmp/tmpum1crtxy/tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4-py3.7.egg-info
running install_scripts
creating /tmp/tmpum1crtxy/tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4.dist-info/WHEEL
creating '/tmp/tmpo87nn6ey/tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4-py3-none-any.whl' and adding '/tmp/tmpum1crtxy' to it
adding 'penguin_trainer.py'
adding 'tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4.dist-info/METADATA'
adding 'tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4.dist-info/WHEEL'
adding 'tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4.dist-info/top_level.txt'
adding 'tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4.dist-info/RECORD'
removing /tmp/tmpum1crtxy
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
  setuptools.SetuptoolsDeprecationWarning,
listing git files failed - pretending there aren't any
I1205 11:16:01.389324  6108 rdbms_metadata_access_object.cc:686] No property is defined for the Type
I1205 11:16:01.392832  6108 rdbms_metadata_access_object.cc:686] No property is defined for the Type
Processing /tmp/tfx-interactive-2021-12-05T11_15_56.285625-5hcexlo8/_wheels/tfx_user_code_Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4-py3-none-any.whl
Installing collected packages: tfx-user-code-Trainer
Successfully installed tfx-user-code-Trainer-0.0+fef7c4ed90dc336ca26daee59d65660cf8da5fa988b2ca0c89df2f558fda10f4
Epoch 1/5
20/20 [==============================] - 1s 11ms/step - loss: 0.9891 - sparse_categorical_accuracy: 0.4300 - val_loss: 0.9594 - val_sparse_categorical_accuracy: 0.4800
Epoch 2/5
20/20 [==============================] - 0s 6ms/step - loss: 0.8369 - sparse_categorical_accuracy: 0.6350 - val_loss: 0.7484 - val_sparse_categorical_accuracy: 0.8200
Epoch 3/5
20/20 [==============================] - 0s 6ms/step - loss: 0.5289 - sparse_categorical_accuracy: 0.8350 - val_loss: 0.5068 - val_sparse_categorical_accuracy: 0.7800
Epoch 4/5
20/20 [==============================] - 0s 6ms/step - loss: 0.4481 - sparse_categorical_accuracy: 0.7800 - val_loss: 0.4125 - val_sparse_categorical_accuracy: 0.8600
Epoch 5/5
20/20 [==============================] - 0s 6ms/step - loss: 0.3068 - sparse_categorical_accuracy: 0.8650 - val_loss: 0.3279 - val_sparse_categorical_accuracy: 0.8300
2021-12-05 11:16:06.493168: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tfx-interactive-2021-12-05T11_15_56.285625-5hcexlo8/Trainer/model/4/Format-Serving/assets
INFO:tensorflow:Assets written to: /tmp/tfx-interactive-2021-12-05T11_15_56.285625-5hcexlo8/Trainer/model/4/Format-Serving/assets

Đánh giá và thúc đẩy mô hình

Sử dụng các Evaluator thành phần để đánh giá và 'chúc phúc' mô hình trước khi sử dụng Pusher thành phần để thúc đẩy mô hình vào một thư mục phục vụ.

_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 = tfx.components.Evaluator(
    examples=example_gen.outputs['examples'],
    model=trainer.outputs['model'],
    schema=infer_schema.outputs['schema'],
    eval_config=eval_config)
interactive_context.run(evaluator)
I1205 11:16:07.075275  6108 rdbms_metadata_access_object.cc:686] No property is defined for the Type
I1205 11:16:07.078761  6108 rdbms_metadata_access_object.cc:686] No property is defined for the Type
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:114: 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.7/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:114: 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)`
pusher = tfx.components.Pusher(
    model=trainer.outputs['model'],
    model_blessing=evaluator.outputs['blessing'],
    push_destination=tfx.proto.PushDestination(
        filesystem=tfx.proto.PushDestination.Filesystem(
            base_directory=_serving_model_dir)))
interactive_context.run(pusher)
I1205 11:16:11.935312  6108 rdbms_metadata_access_object.cc:686] No property is defined for the Type

Chạy đường ống TFX điền Cơ sở dữ liệu MLMD. Trong phần tiếp theo, bạn sử dụng API MLMD để truy vấn cơ sở dữ liệu này về thông tin siêu dữ liệu.

Truy vấn Cơ sở dữ liệu MLMD

Cơ sở dữ liệu MLMD lưu trữ ba loại siêu dữ liệu:

  • Siêu dữ liệu về đường ống và thông tin dòng dõi được liên kết với các thành phần đường ống
  • Siêu dữ liệu về các phần mềm tạo tác được tạo trong quá trình chạy đường ống
  • Siêu dữ liệu về quá trình thực thi của đường ống

Một đường ống dẫn môi trường sản xuất điển hình phục vụ nhiều mô hình khi dữ liệu mới đến. Khi bạn gặp phải kết quả sai trong các mô hình được cung cấp, bạn có thể truy vấn cơ sở dữ liệu MLMD để cô lập các mô hình có sai sót. Sau đó, bạn có thể theo dõi nguồn gốc của các thành phần đường ống tương ứng với các mô hình này để gỡ lỗi các mô hình của bạn

Thiết lập các cửa hàng siêu dữ liệu (MD) với InteractiveContext định nghĩa trước để truy vấn cơ sở dữ liệu 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]

Tạo một số chức năng trợ giúp để xem dữ liệu từ MD store.

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)

Đầu tiên, truy vấn các cửa hàng MD cho một danh sách của tất cả các lưu trữ của nó ArtifactTypes .

display_types(store.get_artifact_types())

Tiếp theo, truy vấn tất cả PushedModel hiện vật.

pushed_models = store.get_artifacts_by_type("PushedModel")
display_artifacts(store, pushed_models)

Truy vấn cửa hàng MD cho mô hình được đẩy mới nhất. Hướng dẫn này chỉ có một mô hình được đẩy.

pushed_model = pushed_models[-1]
display_properties(store, pushed_model)

Một trong những bước đầu tiên để gỡ lỗi một mô hình được đẩy là xem mô hình được đào tạo nào được đẩy và xem dữ liệu đào tạo nào được sử dụng để đào tạo mô hình đó.

MLMD cung cấp các API truyền tải để xem qua biểu đồ xuất xứ, bạn có thể sử dụng biểu đồ này để phân tích xuất xứ của mô hình.

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 == mlmd.proto.Event.OUTPUT)
  artifacts_ids = set(
      event.artifact_id
      for event in store.get_events_by_execution_ids(executions_ids)
      if event.type == mlmd.proto.Event.INPUT)
  return [artifact for artifact in store.get_artifacts_by_id(artifacts_ids)]

Truy vấn các cấu phần gốc cho mô hình được đẩy.

parent_artifacts = get_one_hop_parent_artifacts(store, [pushed_model])
display_artifacts(store, parent_artifacts)

Truy vấn các thuộc tính cho mô hình.

exported_model = parent_artifacts[0]
display_properties(store, exported_model)

Truy vấn các tạo tác ngược dòng cho mô hình.

model_parents = get_one_hop_parent_artifacts(store, [exported_model])
display_artifacts(store, model_parents)

Nhận dữ liệu đào tạo mà mô hình được đào tạo.

used_data = model_parents[0]
display_properties(store, used_data)

Bây giờ bạn đã có dữ liệu huấn luyện mà mô hình được huấn luyện, hãy truy vấn lại cơ sở dữ liệu để tìm bước huấn luyện (thực thi). Truy vấn cửa hàng MD để biết danh sách các kiểu thực thi đã đăng ký.

display_types(store.get_execution_types())

Bước đào tạo là ExecutionType tên tfx.components.trainer.component.Trainer . Di chuyển qua cửa hàng MD để nhận được lần chạy của huấn luyện viên tương ứng với mô hình được đẩy.

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 == mlmd.proto.Event.OUTPUT)
  return store.get_executions_by_id(executions_ids)[0]

trainer = find_producer_execution(store, exported_model)
display_properties(store, trainer)

Bản tóm tắt

Trong hướng dẫn này, bạn đã tìm hiểu về cách bạn có thể tận dụng MLMD để theo dõi nguồn gốc của các thành phần đường ống TFX của bạn và giải quyết các vấn đề.

Để tìm hiểu thêm về cách sử dụng MLMD, hãy xem các tài nguyên bổ sung sau: