Xem trên TensorFlow.org | Chạy trong Google Colab | Xem trên GitHub | Tải xuống sổ ghi chép |
Lý lịch
Sổ tay này trình bày cách tạo thẻ mô hình bằng Bộ công cụ thẻ mô hình với đường ống MLMD và TFX trong môi trường Jupyter / Colab. Bạn có thể tìm hiểu thêm về thẻ mô hình tại https://modelcards.withgoogle.com/about
Thành lập
Trước tiên, chúng ta cần a) cài đặt và nhập các gói cần thiết, và b) tải xuống dữ liệu.
Nâng cấp lên Pip 20.2 và cài đặt TFX
pip install -q --upgrade pip==20.2
pip install -q "tfx==0.26.0"
pip install -q model-card-toolkit
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 (Runtime> Restart runtime ...). Điều này là do cách Colab tải các gói.
Nhập gói
Chúng tôi nhập các gói cần thiết, bao gồm các lớp thành phần TFX tiêu chuẩn và kiểm tra các phiên bản thư viện.
import os
import pprint
import tempfile
import urllib
import absl
import tensorflow as tf
import tensorflow_model_analysis as tfma
tf.get_logger().propagate = False
pp = pprint.PrettyPrinter()
import tfx
from tfx.components import CsvExampleGen
from tfx.components import Evaluator
from tfx.components import Pusher
from tfx.components import ResolverNode
from tfx.components import SchemaGen
from tfx.components import StatisticsGen
from tfx.components import Trainer
from tfx.components import Transform
from tfx.components.base import executor_spec
from tfx.components.trainer.executor import GenericExecutor
from tfx.dsl.experimental import latest_blessed_model_resolver
from tfx.orchestration import metadata
from tfx.orchestration import pipeline
from tfx.orchestration.experimental.interactive.interactive_context import InteractiveContext
from tfx.proto import pusher_pb2
from tfx.proto import trainer_pb2
from tfx.types import Channel
from tfx.types.standard_artifacts import Model
from tfx.types.standard_artifacts import ModelBlessing
from tfx.utils.dsl_utils import external_input
import ml_metadata as mlmd
WARNING:absl:RuntimeParameter is only supported on Cloud-based DAG runner currently.
print('TensorFlow version: {}'.format(tf.__version__))
print('TFX version: {}'.format(tfx.version.__version__))
print('MLMD version: {}'.format(mlmd.__version__))
TensorFlow version: 2.3.2 TFX version: 0.26.0 MLMD version: 0.26.0
Thiết lập đường dẫn đường ống
# This is the root directory for your TFX pip package installation.
_tfx_root = tfx.__path__
# Set up logging.
absl.logging.set_verbosity(absl.logging.INFO)
Tải xuống dữ liệu mẫu
Chúng tôi tải xuống tập dữ liệu mẫu để sử dụng trong đường dẫn TFX của chúng tôi.
DATA_PATH = 'https://archive.ics.uci.edu/ml/machine-learning-databases/adult/' \
'adult.data'
_data_root = tempfile.mkdtemp(prefix='tfx-data')
_data_filepath = os.path.join(_data_root, "data.csv")
urllib.request.urlretrieve(DATA_PATH, _data_filepath)
columns = [
"Age", "Workclass", "fnlwgt", "Education", "Education-Num", "Marital-Status",
"Occupation", "Relationship", "Race", "Sex", "Capital-Gain", "Capital-Loss",
"Hours-per-week", "Country", "Over-50K"]
with open(_data_filepath, 'r') as f:
content = f.read()
content = content.replace(", <=50K", ', 0').replace(", >50K", ', 1')
with open(_data_filepath, 'w') as f:
f.write(','.join(columns) + '\n' + content)
Hãy xem nhanh tệp CSV.
head {_data_filepath}
Age,Workclass,fnlwgt,Education,Education-Num,Marital-Status,Occupation,Relationship,Race,Sex,Capital-Gain,Capital-Loss,Hours-per-week,Country,Over-50K 39, State-gov, 77516, Bachelors, 13, Never-married, Adm-clerical, Not-in-family, White, Male, 2174, 0, 40, United-States, 0 50, Self-emp-not-inc, 83311, Bachelors, 13, Married-civ-spouse, Exec-managerial, Husband, White, Male, 0, 0, 13, United-States, 0 38, Private, 215646, HS-grad, 9, Divorced, Handlers-cleaners, Not-in-family, White, Male, 0, 0, 40, United-States, 0 53, Private, 234721, 11th, 7, Married-civ-spouse, Handlers-cleaners, Husband, Black, Male, 0, 0, 40, United-States, 0 28, Private, 338409, Bachelors, 13, Married-civ-spouse, Prof-specialty, Wife, Black, Female, 0, 0, 40, Cuba, 0 37, Private, 284582, Masters, 14, Married-civ-spouse, Exec-managerial, Wife, White, Female, 0, 0, 40, United-States, 0 49, Private, 160187, 9th, 5, Married-spouse-absent, Other-service, Not-in-family, Black, Female, 0, 0, 16, Jamaica, 0 52, Self-emp-not-inc, 209642, HS-grad, 9, Married-civ-spouse, Exec-managerial, Husband, White, Male, 0, 0, 45, United-States, 1 31, Private, 45781, Masters, 14, Never-married, Prof-specialty, Not-in-family, White, Female, 14084, 0, 50, United-States, 1
Tạo InteractiveContext
Cuối cùng, chúng tôi tạo một InteractiveContext, cho phép chúng tôi chạy các thành phần TFX một cách tương tác trong sổ ghi chép này.
# Here, we create an InteractiveContext using default parameters. This will
# use a temporary directory with an ephemeral ML Metadata database instance.
# To use your own pipeline root or database, the optional properties
# `pipeline_root` and `metadata_connection_config` may be passed to
# InteractiveContext. Calls to InteractiveContext are no-ops outside of the
# notebook.
context = InteractiveContext()
WARNING:absl:InteractiveContext pipeline_root argument not provided: using temporary directory /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1 as root for pipeline outputs. WARNING:absl:InteractiveContext metadata_connection_config not provided: using SQLite ML Metadata database at /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/metadata.sqlite.
Chạy các thành phần TFX một cách tương tác
Trong các ô tiếp theo, chúng tôi tạo từng thành phần TFX, chạy từng ô trong số chúng và trực quan hóa các tạo tác đầu ra của chúng. Trong máy tính xách tay này, chúng tôi sẽ không cung cấp giải thích chi tiết của mỗi thành phần TFX, nhưng bạn có thể xem những gì từng làm ở xưởng TFX Colab .
ExampleGen
Tạo ExampleGen
thành phần để phân chia dữ liệu vào đào tạo và đánh giá bộ, chuyển đổi dữ liệu vào tf.Example
định dạng, và sao chép dữ liệu vào _tfx_root
thư mục cho các thành phần khác để truy cập.
example_gen = CsvExampleGen(input=external_input(_data_root))
context.run(example_gen)
WARNING:absl:From <ipython-input-1-2e0190c2dd16>: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. INFO:absl:Running driver for CsvExampleGen INFO:absl:MetadataStore with DB connection initialized INFO:absl:select span and version = (0, None) INFO:absl:latest span and version = (0, None) INFO:absl:Running executor for CsvExampleGen INFO:absl:Generating examples. 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. INFO:absl:Processing input csv data /tmp/tfx-datajjx_v0dr/* to TFExample. 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. INFO:absl:Examples generated. INFO:absl:Running publisher for CsvExampleGen INFO:absl:MetadataStore with DB connection initialized
artifact = example_gen.outputs['examples'].get()[0]
print(artifact.split_names, artifact.uri)
["train", "eval"] /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/CsvExampleGen/examples/1
Hãy xem ba ví dụ đào tạo đầu tiên:
# Get the URI of the output artifact representing the training examples, which is a directory
train_uri = os.path.join(example_gen.outputs['examples'].get()[0].uri, 'train')
# Get the list of files in this directory (all compressed TFRecord files)
tfrecord_filenames = [os.path.join(train_uri, name)
for name in os.listdir(train_uri)]
# Create a `TFRecordDataset` to read these files
dataset = tf.data.TFRecordDataset(tfrecord_filenames, compression_type="GZIP")
# Iterate over the first 3 records and decode them.
for tfrecord in dataset.take(3):
serialized_example = tfrecord.numpy()
example = tf.train.Example()
example.ParseFromString(serialized_example)
pp.pprint(example)
features { feature { key: "Age" value { int64_list { value: 39 } } } feature { key: "Capital-Gain" value { int64_list { value: 2174 } } } feature { key: "Capital-Loss" value { int64_list { value: 0 } } } feature { key: "Country" value { bytes_list { value: " United-States" } } } feature { key: "Education" value { bytes_list { value: " Bachelors" } } } feature { key: "Education-Num" value { int64_list { value: 13 } } } feature { key: "Hours-per-week" value { int64_list { value: 40 } } } feature { key: "Marital-Status" value { bytes_list { value: " Never-married" } } } feature { key: "Occupation" value { bytes_list { value: " Adm-clerical" } } } feature { key: "Over-50K" value { int64_list { value: 0 } } } feature { key: "Race" value { bytes_list { value: " White" } } } feature { key: "Relationship" value { bytes_list { value: " Not-in-family" } } } feature { key: "Sex" value { bytes_list { value: " Male" } } } feature { key: "Workclass" value { bytes_list { value: " State-gov" } } } feature { key: "fnlwgt" value { int64_list { value: 77516 } } } } features { feature { key: "Age" value { int64_list { value: 50 } } } feature { key: "Capital-Gain" value { int64_list { value: 0 } } } feature { key: "Capital-Loss" value { int64_list { value: 0 } } } feature { key: "Country" value { bytes_list { value: " United-States" } } } feature { key: "Education" value { bytes_list { value: " Bachelors" } } } feature { key: "Education-Num" value { int64_list { value: 13 } } } feature { key: "Hours-per-week" value { int64_list { value: 13 } } } feature { key: "Marital-Status" value { bytes_list { value: " Married-civ-spouse" } } } feature { key: "Occupation" value { bytes_list { value: " Exec-managerial" } } } feature { key: "Over-50K" value { int64_list { value: 0 } } } feature { key: "Race" value { bytes_list { value: " White" } } } feature { key: "Relationship" value { bytes_list { value: " Husband" } } } feature { key: "Sex" value { bytes_list { value: " Male" } } } feature { key: "Workclass" value { bytes_list { value: " Self-emp-not-inc" } } } feature { key: "fnlwgt" value { int64_list { value: 83311 } } } } features { feature { key: "Age" value { int64_list { value: 38 } } } feature { key: "Capital-Gain" value { int64_list { value: 0 } } } feature { key: "Capital-Loss" value { int64_list { value: 0 } } } feature { key: "Country" value { bytes_list { value: " United-States" } } } feature { key: "Education" value { bytes_list { value: " HS-grad" } } } feature { key: "Education-Num" value { int64_list { value: 9 } } } feature { key: "Hours-per-week" value { int64_list { value: 40 } } } feature { key: "Marital-Status" value { bytes_list { value: " Divorced" } } } feature { key: "Occupation" value { bytes_list { value: " Handlers-cleaners" } } } feature { key: "Over-50K" value { int64_list { value: 0 } } } feature { key: "Race" value { bytes_list { value: " White" } } } feature { key: "Relationship" value { bytes_list { value: " Not-in-family" } } } feature { key: "Sex" value { bytes_list { value: " Male" } } } feature { key: "Workclass" value { bytes_list { value: " Private" } } } feature { key: "fnlwgt" value { int64_list { value: 215646 } } } }
StatisticsGen
StatisticsGen
mất như nhập dữ liệu chúng tôi chỉ ăn sử dụng ExampleGen
và cho phép bạn thực hiện một số phân tích các dữ liệu của bạn sử dụng TensorFlow Data Validation (TFDV).
statistics_gen = StatisticsGen(
examples=example_gen.outputs['examples'])
context.run(statistics_gen)
INFO:absl:Excluding no splits because exclude_splits is not set. INFO:absl:Running driver for StatisticsGen INFO:absl:MetadataStore with DB connection initialized INFO:absl:Running executor for StatisticsGen INFO:absl:Generating statistics for split train. INFO:absl:Statistics for split train written to /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/StatisticsGen/statistics/2/train. INFO:absl:Generating statistics for split eval. INFO:absl:Statistics for split eval written to /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/StatisticsGen/statistics/2/eval. INFO:absl:Running publisher for StatisticsGen INFO:absl:MetadataStore with DB connection initialized
Sau StatisticsGen
ngừng chạy, chúng ta có thể hình dung thống kê outputted. Hãy thử chơi với các âm mưu khác nhau!
context.show(statistics_gen.outputs['statistics'])
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)`
SchemaGen
SchemaGen
sẽ mất đầu vào số liệu thống kê mà chúng ta tạo ra với StatisticsGen
, nhìn vào sự chia rẽ đào tạo theo mặc định.
schema_gen = SchemaGen(
statistics=statistics_gen.outputs['statistics'],
infer_feature_shape=False)
context.run(schema_gen)
INFO:absl:Excluding no splits because exclude_splits is not set. INFO:absl:Running driver for SchemaGen INFO:absl:MetadataStore with DB connection initialized INFO:absl:Running executor for SchemaGen INFO:absl:Processing schema from statistics for split train. INFO:absl:Processing schema from statistics for split eval. INFO:absl:Schema written to /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/SchemaGen/schema/3/schema.pbtxt. INFO:absl:Running publisher for SchemaGen INFO:absl:MetadataStore with DB connection initialized
context.show(schema_gen.outputs['schema'])
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_data_validation/utils/display_util.py:151: FutureWarning: Passing a negative integer is deprecated in version 1.0 and will not be supported in future version. Instead, use None to not limit the column width. pd.set_option('max_colwidth', -1)
Để tìm hiểu thêm về schemas, xem tài liệu SchemaGen .
Biến đổi
Transform
sẽ mất như nhập dữ liệu từ ExampleGen
, lược đồ từ SchemaGen
, cũng như một module có chứa người dùng xác định chuyển đổi mã.
Chúng ta hãy xem một ví dụ về người dùng định nghĩa Chuyển đổi mã dưới đây (đối với một giới thiệu về các TensorFlow Biến đổi API, xem hướng dẫn ).
_census_income_constants_module_file = 'census_income_constants.py'
%%writefile {_census_income_constants_module_file}
# Categorical features are assumed to each have a maximum value in the dataset.
MAX_CATEGORICAL_FEATURE_VALUES = [20]
CATEGORICAL_FEATURE_KEYS = ["Education-Num"]
DENSE_FLOAT_FEATURE_KEYS = ["Capital-Gain", "Hours-per-week", "Capital-Loss"]
# Number of buckets used by tf.transform for encoding each feature.
FEATURE_BUCKET_COUNT = 10
BUCKET_FEATURE_KEYS = ["Age"]
# Number of vocabulary terms used for encoding VOCAB_FEATURES by tf.transform
VOCAB_SIZE = 200
# Count of out-of-vocab buckets in which unrecognized VOCAB_FEATURES are hashed.
OOV_SIZE = 10
VOCAB_FEATURE_KEYS = ["Workclass", "Education", "Marital-Status", "Occupation",
"Relationship", "Race", "Sex", "Country"]
# Keys
LABEL_KEY = "Over-50K"
def transformed_name(key):
return key + '_xf'
Writing census_income_constants.py
_census_income_transform_module_file = 'census_income_transform.py'
%%writefile {_census_income_transform_module_file}
import tensorflow as tf
import tensorflow_transform as tft
import census_income_constants
_DENSE_FLOAT_FEATURE_KEYS = census_income_constants.DENSE_FLOAT_FEATURE_KEYS
_VOCAB_FEATURE_KEYS = census_income_constants.VOCAB_FEATURE_KEYS
_VOCAB_SIZE = census_income_constants.VOCAB_SIZE
_OOV_SIZE = census_income_constants.OOV_SIZE
_FEATURE_BUCKET_COUNT = census_income_constants.FEATURE_BUCKET_COUNT
_BUCKET_FEATURE_KEYS = census_income_constants.BUCKET_FEATURE_KEYS
_CATEGORICAL_FEATURE_KEYS = census_income_constants.CATEGORICAL_FEATURE_KEYS
_LABEL_KEY = census_income_constants.LABEL_KEY
_transformed_name = census_income_constants.transformed_name
def preprocessing_fn(inputs):
"""tf.transform's callback function for preprocessing inputs.
Args:
inputs: map from feature keys to raw not-yet-transformed features.
Returns:
Map from string feature key to transformed feature operations.
"""
outputs = {}
for key in _DENSE_FLOAT_FEATURE_KEYS:
# Preserve this feature as a dense float, setting nan's to the mean.
outputs[_transformed_name(key)] = tft.scale_to_z_score(
_fill_in_missing(inputs[key]))
for key in _VOCAB_FEATURE_KEYS:
# Build a vocabulary for this feature.
outputs[_transformed_name(key)] = tft.compute_and_apply_vocabulary(
_fill_in_missing(inputs[key]),
top_k=_VOCAB_SIZE,
num_oov_buckets=_OOV_SIZE)
for key in _BUCKET_FEATURE_KEYS:
outputs[_transformed_name(key)] = tft.bucketize(
_fill_in_missing(inputs[key]), _FEATURE_BUCKET_COUNT)
for key in _CATEGORICAL_FEATURE_KEYS:
outputs[_transformed_name(key)] = _fill_in_missing(inputs[key])
label = _fill_in_missing(inputs[_LABEL_KEY])
outputs[_transformed_name(_LABEL_KEY)] = label
return outputs
def _fill_in_missing(x):
"""Replace missing values in a SparseTensor.
Fills in missing values of `x` with '' or 0, and converts to a dense tensor.
Args:
x: A `SparseTensor` of rank 2. Its dense shape should have size at most 1
in the second dimension.
Returns:
A rank 1 tensor where missing values of `x` have been filled in.
"""
default_value = '' if x.dtype == tf.string else 0
return tf.squeeze(
tf.sparse.to_dense(
tf.SparseTensor(x.indices, x.values, [x.dense_shape[0], 1]),
default_value),
axis=1)
Writing census_income_transform.py
transform = Transform(
examples=example_gen.outputs['examples'],
schema=schema_gen.outputs['schema'],
module_file=os.path.abspath(_census_income_transform_module_file))
context.run(transform)
INFO:absl:Running driver for Transform INFO:absl:MetadataStore with DB connection initialized INFO:absl:Running executor for Transform INFO:absl:Analyze the 'train' split and transform all splits when splits_config is not set. WARNING:absl:The default value of `force_tf_compat_v1` will change in a future release from `True` to `False`. Since this pipeline has TF 2 behaviors enabled, Transform will use native TF 2 at that point. You can test this behavior now by passing `force_tf_compat_v1=False` or disable it by explicitly setting `force_tf_compat_v1=True` in the Transform component. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tfx/components/transform/executor.py:541: Schema (from tensorflow_transform.tf_metadata.dataset_schema) is deprecated and will be removed in a future version. Instructions for updating: Schema is a deprecated, use schema_utils.schema_from_feature_spec to create a `Schema` INFO:absl:Loading /tmpfs/src/temp/model_card_toolkit/documentation/examples/census_income_transform.py because it has not been loaded before. INFO:absl:/tmpfs/src/temp/model_card_toolkit/documentation/examples/census_income_transform.py is already loaded. INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_transform/tf_utils.py:261: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version. Instructions for updating: Use ref() instead. INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. WARNING:tensorflow:TFT beam APIs accept both the TFXIO format and the instance dict format now. There is no need to set use_tfxio any more and it will be removed soon. WARNING:root:This output type hint will be ignored and not used for type-checking purposes. Typically, output type hints for a PTransform are single (or nested) types wrapped by a PCollection, PDone, or None. Got: Tuple[Dict[str, Union[NoneType, _Dataset]], Union[Dict[str, Dict[str, PCollection]], NoneType]] instead. WARNING:root:This output type hint will be ignored and not used for type-checking purposes. Typically, output type hints for a PTransform are single (or nested) types wrapped by a PCollection, PDone, or None. Got: Tuple[Dict[str, Union[NoneType, _Dataset]], Union[Dict[str, Dict[str, PCollection]], NoneType]] instead. WARNING:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:201: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version. Instructions for updating: This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info. INFO:tensorflow:Assets added to graph. INFO:tensorflow:No assets to write. WARNING:tensorflow:Issue encountered when serializing tft_mapper_use. Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore. 'Counter' object has no attribute 'name' INFO:tensorflow:SavedModel written to: /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/transform_graph/4/.temp_path/tftransform_tmp/259914d385c64e718981569626d0274c/saved_model.pb INFO:tensorflow:Assets added to graph. INFO:tensorflow:No assets to write. WARNING:tensorflow:Issue encountered when serializing tft_mapper_use. Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore. 'Counter' object has no attribute 'name' INFO:tensorflow:SavedModel written to: /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/transform_graph/4/.temp_path/tftransform_tmp/5a8d2f32189a42faa1a8db83c514c74e/saved_model.pb INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. WARNING:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> INFO:absl:Feature Age has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Gain has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Capital-Loss has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Country has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Education-Num has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Hours-per-week has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Marital-Status has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Occupation has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Over-50K has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Race has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Relationship has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Sex has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature Workclass has no shape. Setting to VarLenSparseTensor. INFO:absl:Feature fnlwgt has no shape. Setting to VarLenSparseTensor. WARNING:tensorflow:Tensorflow version (2.3.2) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring send_type hint: <class 'NoneType'> WARNING:apache_beam.typehints.typehints:Ignoring return_type hint: <class 'NoneType'> INFO:tensorflow:Saver not created because there are no variables in the graph to restore INFO:tensorflow:Saver not created because there are no variables in the graph to restore INFO:tensorflow:Assets added to graph. INFO:tensorflow:Assets written to: /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/transform_graph/4/.temp_path/tftransform_tmp/f4e3edcb37534b60889ae56fa82df09f/assets INFO:tensorflow:SavedModel written to: /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/transform_graph/4/.temp_path/tftransform_tmp/f4e3edcb37534b60889ae56fa82df09f/saved_model.pb WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_2:0\022-vocab_compute_and_apply_vocabulary_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_4:0\022/vocab_compute_and_apply_vocabulary_1_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_6:0\022/vocab_compute_and_apply_vocabulary_2_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_8:0\022/vocab_compute_and_apply_vocabulary_3_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_10:0\022/vocab_compute_and_apply_vocabulary_4_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_12:0\022/vocab_compute_and_apply_vocabulary_5_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_14:0\022/vocab_compute_and_apply_vocabulary_6_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_16:0\022/vocab_compute_and_apply_vocabulary_7_vocabulary" INFO:tensorflow:Saver not created because there are no variables in the graph to restore WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_2:0\022-vocab_compute_and_apply_vocabulary_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_4:0\022/vocab_compute_and_apply_vocabulary_1_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_6:0\022/vocab_compute_and_apply_vocabulary_2_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_8:0\022/vocab_compute_and_apply_vocabulary_3_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_10:0\022/vocab_compute_and_apply_vocabulary_4_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_12:0\022/vocab_compute_and_apply_vocabulary_5_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_14:0\022/vocab_compute_and_apply_vocabulary_6_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_16:0\022/vocab_compute_and_apply_vocabulary_7_vocabulary" INFO:tensorflow:Saver not created because there are no variables in the graph to restore WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_2:0\022-vocab_compute_and_apply_vocabulary_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_4:0\022/vocab_compute_and_apply_vocabulary_1_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_6:0\022/vocab_compute_and_apply_vocabulary_2_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\013\n\tConst_8:0\022/vocab_compute_and_apply_vocabulary_3_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_10:0\022/vocab_compute_and_apply_vocabulary_4_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_12:0\022/vocab_compute_and_apply_vocabulary_5_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_14:0\022/vocab_compute_and_apply_vocabulary_6_vocabulary" WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef" value: "\n\014\n\nConst_16:0\022/vocab_compute_and_apply_vocabulary_7_vocabulary" INFO:tensorflow:Saver not created because there are no variables in the graph to restore INFO:absl:Running publisher for Transform INFO:absl:MetadataStore with DB connection initialized
transform.outputs
{'transform_graph': Channel( type_name: TransformGraph artifacts: [Artifact(artifact: id: 4 type_id: 11 uri: "/tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/transform_graph/4" custom_properties { key: "name" value { string_value: "transform_graph" } } custom_properties { key: "producer_component" value { string_value: "Transform" } } custom_properties { key: "state" value { string_value: "published" } } state: LIVE , artifact_type: id: 11 name: "TransformGraph" )] ), 'transformed_examples': Channel( type_name: Examples artifacts: [Artifact(artifact: id: 5 type_id: 5 uri: "/tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/transformed_examples/4" properties { key: "split_names" value { string_value: "[\"train\", \"eval\"]" } } custom_properties { key: "name" value { string_value: "transformed_examples" } } custom_properties { key: "producer_component" value { string_value: "Transform" } } custom_properties { key: "state" value { string_value: "published" } } state: LIVE , artifact_type: id: 5 name: "Examples" properties { key: "span" value: INT } properties { key: "split_names" value: STRING } properties { key: "version" value: INT } )] ), 'updated_analyzer_cache': Channel( type_name: TransformCache artifacts: [Artifact(artifact: id: 6 type_id: 12 uri: "/tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Transform/updated_analyzer_cache/4" custom_properties { key: "name" value { string_value: "updated_analyzer_cache" } } custom_properties { key: "producer_component" value { string_value: "Transform" } } custom_properties { key: "state" value { string_value: "published" } } state: LIVE , artifact_type: id: 12 name: "TransformCache" )] )}
Huấn luyện viên
Chúng ta hãy xem một ví dụ về mã mô hình người dùng định nghĩa dưới đây (cho một giới thiệu về các Keras API TensorFlow, xem hướng dẫn ):
_census_income_trainer_module_file = 'census_income_trainer.py'
%%writefile {_census_income_trainer_module_file}
from typing import List, Text
import os
import absl
import datetime
import tensorflow as tf
import tensorflow_transform as tft
from tfx.components.trainer.executor import TrainerFnArgs
import census_income_constants
_DENSE_FLOAT_FEATURE_KEYS = census_income_constants.DENSE_FLOAT_FEATURE_KEYS
_VOCAB_FEATURE_KEYS = census_income_constants.VOCAB_FEATURE_KEYS
_VOCAB_SIZE = census_income_constants.VOCAB_SIZE
_OOV_SIZE = census_income_constants.OOV_SIZE
_FEATURE_BUCKET_COUNT = census_income_constants.FEATURE_BUCKET_COUNT
_BUCKET_FEATURE_KEYS = census_income_constants.BUCKET_FEATURE_KEYS
_CATEGORICAL_FEATURE_KEYS = census_income_constants.CATEGORICAL_FEATURE_KEYS
_MAX_CATEGORICAL_FEATURE_VALUES = census_income_constants.MAX_CATEGORICAL_FEATURE_VALUES
_LABEL_KEY = census_income_constants.LABEL_KEY
_transformed_name = census_income_constants.transformed_name
def _transformed_names(keys):
return [_transformed_name(key) for key in keys]
def _gzip_reader_fn(filenames):
"""Small utility returning a record reader that can read gzip'ed files."""
return tf.data.TFRecordDataset(
filenames,
compression_type='GZIP')
def _get_serve_tf_examples_fn(model, tf_transform_output):
"""Returns a function that parses a serialized tf.Example and applies TFT."""
model.tft_layer = tf_transform_output.transform_features_layer()
@tf.function
def serve_tf_examples_fn(serialized_tf_examples):
"""Returns the output to be used in the serving signature."""
feature_spec = tf_transform_output.raw_feature_spec()
feature_spec.pop(_LABEL_KEY)
parsed_features = tf.io.parse_example(serialized_tf_examples, feature_spec)
transformed_features = model.tft_layer(parsed_features)
if _transformed_name(_LABEL_KEY) in transformed_features:
transformed_features.pop(_transformed_name(_LABEL_KEY))
return model(transformed_features)
return serve_tf_examples_fn
def _input_fn(file_pattern: List[Text],
tf_transform_output: tft.TFTransformOutput,
batch_size: int = 200) -> tf.data.Dataset:
"""Generates features and label for tuning/training.
Args:
file_pattern: List of paths or patterns of input tfrecord files.
tf_transform_output: A TFTransformOutput.
batch_size: representing the number of consecutive elements of returned
dataset to combine in a single batch
Returns:
A dataset that contains (features, indices) tuple where features is a
dictionary of Tensors, and indices is a single Tensor of label indices.
"""
transformed_feature_spec = (
tf_transform_output.transformed_feature_spec().copy())
dataset = tf.data.experimental.make_batched_features_dataset(
file_pattern=file_pattern,
batch_size=batch_size,
features=transformed_feature_spec,
reader=_gzip_reader_fn,
label_key=_transformed_name(_LABEL_KEY))
return dataset
def _build_keras_model(hidden_units: List[int] = None) -> tf.keras.Model:
"""Creates a DNN Keras model.
Args:
hidden_units: [int], the layer sizes of the DNN (input layer first).
Returns:
A keras Model.
"""
real_valued_columns = [
tf.feature_column.numeric_column(key, shape=())
for key in _transformed_names(_DENSE_FLOAT_FEATURE_KEYS)
]
categorical_columns = [
tf.feature_column.categorical_column_with_identity(
key, num_buckets=_VOCAB_SIZE + _OOV_SIZE, default_value=0)
for key in _transformed_names(_VOCAB_FEATURE_KEYS)
]
categorical_columns += [
tf.feature_column.categorical_column_with_identity(
key, num_buckets=_FEATURE_BUCKET_COUNT, default_value=0)
for key in _transformed_names(_BUCKET_FEATURE_KEYS)
]
categorical_columns += [
tf.feature_column.categorical_column_with_identity( # pylint: disable=g-complex-comprehension
key,
num_buckets=num_buckets,
default_value=0) for key, num_buckets in zip(
_transformed_names(_CATEGORICAL_FEATURE_KEYS),
_MAX_CATEGORICAL_FEATURE_VALUES)
]
indicator_column = [
tf.feature_column.indicator_column(categorical_column)
for categorical_column in categorical_columns
]
model = _wide_and_deep_classifier(
# TODO(b/139668410) replace with premade wide_and_deep keras model
wide_columns=indicator_column,
deep_columns=real_valued_columns,
dnn_hidden_units=hidden_units or [100, 70, 50, 25])
return model
def _wide_and_deep_classifier(wide_columns, deep_columns, dnn_hidden_units):
"""Build a simple keras wide and deep model.
Args:
wide_columns: Feature columns wrapped in indicator_column for wide (linear)
part of the model.
deep_columns: Feature columns for deep part of the model.
dnn_hidden_units: [int], the layer sizes of the hidden DNN.
Returns:
A Wide and Deep Keras model
"""
# Following values are hard coded for simplicity in this example,
# However prefarably they should be passsed in as hparams.
# Keras needs the feature definitions at compile time.
# TODO(b/139081439): Automate generation of input layers from FeatureColumn.
input_layers = {
colname: tf.keras.layers.Input(name=colname, shape=(), dtype=tf.float32)
for colname in _transformed_names(_DENSE_FLOAT_FEATURE_KEYS)
}
input_layers.update({
colname: tf.keras.layers.Input(name=colname, shape=(), dtype='int32')
for colname in _transformed_names(_VOCAB_FEATURE_KEYS)
})
input_layers.update({
colname: tf.keras.layers.Input(name=colname, shape=(), dtype='int32')
for colname in _transformed_names(_BUCKET_FEATURE_KEYS)
})
input_layers.update({
colname: tf.keras.layers.Input(name=colname, shape=(), dtype='int32')
for colname in _transformed_names(_CATEGORICAL_FEATURE_KEYS)
})
# TODO(b/161816639): SparseFeatures for feature columns + Keras.
deep = tf.keras.layers.DenseFeatures(deep_columns)(input_layers)
for numnodes in dnn_hidden_units:
deep = tf.keras.layers.Dense(numnodes)(deep)
wide = tf.keras.layers.DenseFeatures(wide_columns)(input_layers)
output = tf.keras.layers.Dense(
1, activation='sigmoid')(
tf.keras.layers.concatenate([deep, wide]))
model = tf.keras.Model(input_layers, output)
model.compile(
loss='binary_crossentropy',
optimizer=tf.keras.optimizers.Adam(lr=0.001),
metrics=[tf.keras.metrics.BinaryAccuracy()])
model.summary(print_fn=absl.logging.info)
return model
# TFX Trainer will call this function.
def run_fn(fn_args: TrainerFnArgs):
"""Train the model based on given args.
Args:
fn_args: Holds args used to train the model as name/value pairs.
"""
# Number of nodes in the first layer of the DNN
first_dnn_layer_size = 100
num_dnn_layers = 4
dnn_decay_factor = 0.7
tf_transform_output = tft.TFTransformOutput(fn_args.transform_output)
train_dataset = _input_fn(fn_args.train_files, tf_transform_output, 40)
eval_dataset = _input_fn(fn_args.eval_files, tf_transform_output, 40)
model = _build_keras_model(
# Construct layers sizes with exponetial decay
hidden_units=[
max(2, int(first_dnn_layer_size * dnn_decay_factor**i))
for i in range(num_dnn_layers)
])
# This log path might change in the future.
log_dir = os.path.join(os.path.dirname(fn_args.serving_model_dir), 'logs')
tensorboard_callback = tf.keras.callbacks.TensorBoard(
log_dir=log_dir, update_freq='batch')
model.fit(
train_dataset,
steps_per_epoch=fn_args.train_steps,
validation_data=eval_dataset,
validation_steps=fn_args.eval_steps,
callbacks=[tensorboard_callback])
signatures = {
'serving_default':
_get_serve_tf_examples_fn(model,
tf_transform_output).get_concrete_function(
tf.TensorSpec(
shape=[None],
dtype=tf.string,
name='examples')),
}
model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)
Writing census_income_trainer.py
trainer = Trainer(
module_file=os.path.abspath(_census_income_trainer_module_file),
custom_executor_spec=executor_spec.ExecutorClassSpec(GenericExecutor),
examples=transform.outputs['transformed_examples'],
transform_graph=transform.outputs['transform_graph'],
schema=schema_gen.outputs['schema'],
train_args=trainer_pb2.TrainArgs(num_steps=100),
eval_args=trainer_pb2.EvalArgs(num_steps=50))
context.run(trainer)
WARNING:absl:From <ipython-input-1-6ab3bbf2f5a0>:3: The name tfx.components.base.executor_spec.ExecutorClassSpec is deprecated. Please use tfx.dsl.components.base.executor_spec.ExecutorClassSpec instead. INFO:absl:Running driver for Trainer INFO:absl:MetadataStore with DB connection initialized INFO:absl:Running executor for Trainer INFO:absl:Train on the 'train' split when train_args.splits is not set. INFO:absl:Evaluate on the 'eval' split when eval_args.splits is not set. WARNING:absl:Examples artifact does not have payload_format custom property. Falling back to FORMAT_TF_EXAMPLE WARNING:absl:Examples artifact does not have payload_format custom property. Falling back to FORMAT_TF_EXAMPLE INFO:absl:Loading /tmpfs/src/temp/model_card_toolkit/documentation/examples/census_income_trainer.py because it has not been loaded before. INFO:absl:Training model. INFO:absl:Model: "functional_1" INFO:absl:__________________________________________________________________________________________________ INFO:absl:Layer (type) Output Shape Param # Connected to INFO:absl:================================================================================================== INFO:absl:Age_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Capital-Gain_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Capital-Loss_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Country_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Education-Num_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Education_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Hours-per-week_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Marital-Status_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Occupation_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Race_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Relationship_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Sex_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:Workclass_xf (InputLayer) [(None,)] 0 INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense_features (DenseFeatures) (None, 3) 0 Age_xf[0][0] INFO:absl: Capital-Gain_xf[0][0] INFO:absl: Capital-Loss_xf[0][0] INFO:absl: Country_xf[0][0] INFO:absl: Education-Num_xf[0][0] INFO:absl: Education_xf[0][0] INFO:absl: Hours-per-week_xf[0][0] INFO:absl: Marital-Status_xf[0][0] INFO:absl: Occupation_xf[0][0] INFO:absl: Race_xf[0][0] INFO:absl: Relationship_xf[0][0] INFO:absl: Sex_xf[0][0] INFO:absl: Workclass_xf[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense (Dense) (None, 100) 400 dense_features[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense_1 (Dense) (None, 70) 7070 dense[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense_2 (Dense) (None, 48) 3408 dense_1[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense_3 (Dense) (None, 34) 1666 dense_2[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense_features_1 (DenseFeatures (None, 1710) 0 Age_xf[0][0] INFO:absl: Capital-Gain_xf[0][0] INFO:absl: Capital-Loss_xf[0][0] INFO:absl: Country_xf[0][0] INFO:absl: Education-Num_xf[0][0] INFO:absl: Education_xf[0][0] INFO:absl: Hours-per-week_xf[0][0] INFO:absl: Marital-Status_xf[0][0] INFO:absl: Occupation_xf[0][0] INFO:absl: Race_xf[0][0] INFO:absl: Relationship_xf[0][0] INFO:absl: Sex_xf[0][0] INFO:absl: Workclass_xf[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:concatenate (Concatenate) (None, 1744) 0 dense_3[0][0] INFO:absl: dense_features_1[0][0] INFO:absl:__________________________________________________________________________________________________ INFO:absl:dense_4 (Dense) (None, 1) 1745 concatenate[0][0] INFO:absl:================================================================================================== INFO:absl:Total params: 14,289 INFO:absl:Trainable params: 14,289 INFO:absl:Non-trainable params: 0 INFO:absl:__________________________________________________________________________________________________ 1/100 [..............................] - ETA: 0s - loss: 0.7236 - binary_accuracy: 0.2250WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01. Instructions for updating: use `tf.profiler.experimental.stop` instead. WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0029s vs `on_train_batch_end` time: 0.0135s). Check your callbacks. 100/100 [==============================] - 1s 9ms/step - loss: 0.5104 - binary_accuracy: 0.7710 - val_loss: 0.4469 - val_binary_accuracy: 0.8005 INFO:tensorflow:Saver not created because there are no variables in the graph to restore WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version. Instructions for updating: This property should not be used in TensorFlow 2.0, as updates are applied automatically. WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version. Instructions for updating: This property should not be used in TensorFlow 2.0, as updates are applied automatically. INFO:tensorflow:Assets written to: /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Trainer/model/5/serving_model_dir/assets INFO:absl:Training complete. Model written to /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Trainer/model/5/serving_model_dir. ModelRun written to /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Trainer/model_run/5 INFO:absl:Running publisher for Trainer INFO:absl:MetadataStore with DB connection initialized
Người đánh giá
Các Evaluator
phần tính toán số liệu hiệu suất mô hình trên các thiết lập thẩm định. Nó sử dụng TensorFlow Phân tích mẫu thư viện.
Evaluator
sẽ là đầu vào dữ liệu từ ExampleGen
, mô hình đào tạo từ Trainer
, và cấu hình cắt. Cấu hình cắt cho phép bạn cắt các chỉ số của mình trên các giá trị của tính năng. Xem ví dụ về cấu hình này bên dưới:
from google.protobuf.wrappers_pb2 import BoolValue
eval_config = tfma.EvalConfig(
model_specs=[
# This assumes a serving model with signature 'serving_default'. If
# using estimator based EvalSavedModel, add signature_name: 'eval' and
# remove the label_key.
tfma.ModelSpec(label_key="Over-50K")
],
metrics_specs=[
tfma.MetricsSpec(
# The metrics added here are in addition to those saved with the
# model (assuming either a keras model or EvalSavedModel is used).
# Any metrics added into the saved model (for example using
# model.compile(..., metrics=[...]), etc) will be computed
# automatically.
# To add validation thresholds for metrics saved with the model,
# add them keyed by metric name to the thresholds map.
metrics=[
tfma.MetricConfig(class_name='ExampleCount'),
tfma.MetricConfig(class_name='BinaryAccuracy'),
tfma.MetricConfig(class_name='FairnessIndicators',
config='{ "thresholds": [0.5] }'),
]
)
],
slicing_specs=[
# An empty slice spec means the overall slice, i.e. the whole dataset.
tfma.SlicingSpec(),
# Data can be sliced along a feature column. In this case, data is
# sliced by feature column Race and Sex.
tfma.SlicingSpec(feature_keys=['Race']),
tfma.SlicingSpec(feature_keys=['Sex']),
tfma.SlicingSpec(feature_keys=['Race', 'Sex']),
],
options = tfma.Options(compute_confidence_intervals=BoolValue(value=True))
)
# Use TFMA to compute a evaluation statistics over features of a model and
# validate them against a baseline.
evaluator = Evaluator(
examples=example_gen.outputs['examples'],
model=trainer.outputs['model'],
eval_config=eval_config)
context.run(evaluator)
INFO:absl:Running driver for Evaluator INFO:absl:MetadataStore with DB connection initialized INFO:absl:Running executor for Evaluator WARNING:absl:"maybe_add_baseline" and "maybe_remove_baseline" are deprecated, please use "has_baseline" instead. INFO:absl:Request was made to ignore the baseline ModelSpec and any change thresholds. This is likely because a baseline model was not provided: updated_config= model_specs { label_key: "Over-50K" } slicing_specs { } slicing_specs { feature_keys: "Race" } slicing_specs { feature_keys: "Sex" } slicing_specs { feature_keys: "Race" feature_keys: "Sex" } metrics_specs { metrics { class_name: "ExampleCount" } metrics { class_name: "BinaryAccuracy" } metrics { class_name: "FairnessIndicators" config: "{ \"thresholds\": [0.5] }" } } options { compute_confidence_intervals { value: true } confidence_intervals { method: JACKKNIFE } } INFO:absl:Using /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Trainer/model/5/serving_model_dir as model. INFO:absl:The 'example_splits' parameter is not set, using 'eval' split. INFO:absl:Evaluating model. INFO:absl:Request was made to ignore the baseline ModelSpec and any change thresholds. This is likely because a baseline model was not provided: updated_config= model_specs { label_key: "Over-50K" } slicing_specs { } slicing_specs { feature_keys: "Race" } slicing_specs { feature_keys: "Sex" } slicing_specs { feature_keys: "Race" feature_keys: "Sex" } metrics_specs { metrics { class_name: "ExampleCount" } metrics { class_name: "BinaryAccuracy" } metrics { class_name: "FairnessIndicators" config: "{ \"thresholds\": [0.5] }" } model_names: "" } options { compute_confidence_intervals { value: true } confidence_intervals { method: JACKKNIFE } } INFO:absl:Request was made to ignore the baseline ModelSpec and any change thresholds. This is likely because a baseline model was not provided: updated_config= model_specs { label_key: "Over-50K" } slicing_specs { } slicing_specs { feature_keys: "Race" } slicing_specs { feature_keys: "Sex" } slicing_specs { feature_keys: "Race" feature_keys: "Sex" } metrics_specs { metrics { class_name: "ExampleCount" } metrics { class_name: "BinaryAccuracy" } metrics { class_name: "FairnessIndicators" config: "{ \"thresholds\": [0.5] }" } model_names: "" } options { compute_confidence_intervals { value: true } confidence_intervals { method: JACKKNIFE } } INFO:absl:Request was made to ignore the baseline ModelSpec and any change thresholds. This is likely because a baseline model was not provided: updated_config= model_specs { label_key: "Over-50K" } slicing_specs { } slicing_specs { feature_keys: "Race" } slicing_specs { feature_keys: "Sex" } slicing_specs { feature_keys: "Race" feature_keys: "Sex" } metrics_specs { metrics { class_name: "ExampleCount" } metrics { class_name: "BinaryAccuracy" } metrics { class_name: "FairnessIndicators" config: "{ \"thresholds\": [0.5] }" } model_names: "" } options { compute_confidence_intervals { value: true } confidence_intervals { method: JACKKNIFE } } WARNING:tensorflow:5 out of the last 5 calls to <function recreate_function.<locals>.restored_function_body at 0x7f77a02d2510> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for more details. INFO:absl:Evaluation complete. Results written to /tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Evaluator/evaluation/6. INFO:absl:No threshold configured, will not validate model. INFO:absl:Running publisher for Evaluator INFO:absl:MetadataStore with DB connection initialized
evaluator.outputs
{'evaluation': Channel( type_name: ModelEvaluation artifacts: [Artifact(artifact: id: 9 type_id: 17 uri: "/tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Evaluator/evaluation/6" custom_properties { key: "name" value { string_value: "evaluation" } } custom_properties { key: "producer_component" value { string_value: "Evaluator" } } custom_properties { key: "state" value { string_value: "published" } } state: LIVE , artifact_type: id: 17 name: "ModelEvaluation" )] ), 'blessing': Channel( type_name: ModelBlessing artifacts: [Artifact(artifact: id: 10 type_id: 18 uri: "/tmp/tfx-interactive-2021-02-05T22_01_17.129037-teowo3b1/Evaluator/blessing/6" custom_properties { key: "name" value { string_value: "blessing" } } custom_properties { key: "producer_component" value { string_value: "Evaluator" } } custom_properties { key: "state" value { string_value: "published" } } state: LIVE , artifact_type: id: 18 name: "ModelBlessing" )] )}
Sử dụng evaluation
đầu ra chúng tôi có thể hiển thị hình dung mặc định của số liệu toàn cầu trên toàn bộ bộ đánh giá.
context.show(evaluator.outputs['evaluation'])
Điền các thuộc tính từ ModelCard với Bộ công cụ thẻ mô hình
Bây giờ chúng tôi đã thiết lập đường dẫn TFX của mình, chúng tôi sẽ sử dụng Bộ công cụ thẻ mô hình để trích xuất các hiện vật chính từ quá trình chạy và điền Thẻ mô hình.
Kết nối với cửa hàng MLMD được InteractiveContext sử dụng
from ml_metadata.metadata_store import metadata_store
from IPython import display
mlmd_store = metadata_store.MetadataStore(context.metadata_connection_config)
model_uri = trainer.outputs["model"].get()[0].uri
INFO:absl:MetadataStore with DB connection initialized
Sử dụng Bộ công cụ thẻ mô hình
Khởi tạo Bộ công cụ thẻ mẫu.
from model_card_toolkit import ModelCardToolkit
mct = ModelCardToolkit(mlmd_store=mlmd_store, model_uri=model_uri)
Tạo không gian làm việc Thẻ Mẫu.
model_card = mct.scaffold_assets()
Chú thích thêm thông tin vào Thẻ mẫu.
Việc ghi lại thông tin mô hình có thể quan trọng đối với người dùng phía dưới cũng rất quan trọng, chẳng hạn như các giới hạn của nó, các trường hợp sử dụng dự kiến, sự đánh đổi và các cân nhắc về đạo đức. Đối với mỗi phần này, chúng ta có thể thêm trực tiếp các đối tượng JSON mới để đại diện cho thông tin này.
model_card.model_details.name = 'Census Income Classifier'
model_card.model_details.overview = (
'This is a wide and deep Keras model which aims to classify whether or not '
'an individual has an income of over $50,000 based on various demographic '
'features. The model is trained on the UCI Census Income Dataset. This is '
'not a production model, and this dataset has traditionally only been used '
'for research purposes. In this Model Card, you can review quantitative '
'components of the model’s performance and data, as well as information '
'about the model’s intended uses, limitations, and ethical considerations.'
)
model_card.model_details.owners = [
{'name': 'Model Cards Team', 'contact': 'model-cards@google.com'}
]
model_card.considerations.use_cases = [
'This dataset that this model was trained on was originally created to '
'support the machine learning community in conducting empirical analysis '
'of ML algorithms. The Adult Data Set can be used in fairness-related '
'studies that compare inequalities across sex and race, based on '
'people’s annual incomes.'
]
model_card.considerations.limitations = [
'This is a class-imbalanced dataset across a variety of sensitive classes.'
' The ratio of male-to-female examples is about 2:1 and there are far more'
' examples with the “white” attribute than every other race combined. '
'Furthermore, the ratio of $50,000 or less earners to $50,000 or more '
'earners is just over 3:1. Due to the imbalance across income levels, we '
'can see that our true negative rate seems quite high, while our true '
'positive rate seems quite low. This is true to an even greater degree '
'when we only look at the “female” sub-group, because there are even '
'fewer female examples in the $50,000+ earner group, causing our model to '
'overfit these examples. To avoid this, we can try various remediation '
'strategies in future iterations (e.g. undersampling, hyperparameter '
'tuning, etc), but we may not be able to fix all of the fairness issues.'
]
model_card.considerations.ethical_considerations = [{
'name':
'We risk expressing the viewpoint that the attributes in this dataset '
'are the only ones that are predictive of someone’s income, even '
'though we know this is not the case.',
'mitigation_strategy':
'As mentioned, some interventions may need to be performed to address '
'the class imbalances in the dataset.'
}]
Lọc và Thêm đồ thị.
Chúng tôi có thể lọc các biểu đồ được tạo bởi các thành phần TFX để bao gồm những biểu đồ phù hợp nhất cho Thẻ mẫu bằng cách sử dụng hàm được xác định bên dưới. Trong ví dụ này, chúng tôi lọc cho race
và sex
, hai thuộc tính có khả năng nhạy cảm.
Mỗi Thẻ mô hình sẽ có tối đa ba phần dành cho đồ thị - thống kê tập dữ liệu đào tạo, thống kê tập dữ liệu đánh giá và phân tích định lượng về hiệu suất của mô hình của chúng tôi.
# These are the graphs that will appear in the Quantiative Analysis portion of
# the Model Card. Feel free to add or remove from this list.
TARGET_EVAL_GRAPH_NAMES = [
'fairness_indicators_metrics/false_positive_rate@0.5',
'fairness_indicators_metrics/false_negative_rate@0.5',
'binary_accuracy',
'example_count | Race_X_Sex',
]
# These are the graphs that will appear in both the Train Set and Eval Set
# portions of the Model Card. Feel free to add or remove from this list.
TARGET_DATASET_GRAPH_NAMES = [
'counts | Race',
'counts | Sex',
]
def filter_graphs(graphics, target_graph_names):
result = []
for graph in graphics:
for target_graph_name in target_graph_names:
if graph.name.startswith(target_graph_name):
result.append(graph)
result.sort(key=lambda g: g.name)
return result
# Populating the three different sections using the filter defined above. To
# see all the graphs available in a section, we can iterate through each of the
# different collections.
model_card.quantitative_analysis.graphics.collection = filter_graphs(
model_card.quantitative_analysis.graphics.collection, TARGET_EVAL_GRAPH_NAMES)
model_card.model_parameters.data.eval.graphics.collection = filter_graphs(
model_card.model_parameters.data.eval.graphics.collection, TARGET_DATASET_GRAPH_NAMES)
model_card.model_parameters.data.train.graphics.collection = filter_graphs(
model_card.model_parameters.data.train.graphics.collection, TARGET_DATASET_GRAPH_NAMES)
Sau đó, chúng tôi thêm các mô tả (tùy chọn) cho từng phần của từng phần biểu đồ.
model_card.model_parameters.data.train.graphics.description = (
'This section includes graphs displaying the class distribution for the '
'“Race” and “Sex” attributes in our training dataset. We chose to '
'show these graphs in particular because we felt it was important that '
'users see the class imbalance.'
)
model_card.model_parameters.data.eval.graphics.description = (
'Like the training set, we provide graphs showing the class distribution '
'of the data we used to evaluate our model’s performance. '
)
model_card.quantitative_analysis.graphics.description = (
'These graphs show how the model performs for data sliced by “Race”, '
'“Sex” and the intersection of these attributes. The metrics we chose '
'to display are “Accuracy”, “False Positive Rate”, and “False '
'Negative Rate”, because we anticipated that the class imbalances might '
'cause our model to underperform for certain groups.'
)
mct.update_model_card_json(model_card)
Tạo thẻ mẫu.
Bây giờ chúng ta có thể hiển thị Thẻ mẫu ở định dạng HTML.
html = mct.export_format()
display.display(display.HTML(html))