روز جامعه ML 9 نوامبر است! برای به روز رسانی از TensorFlow، JAX به ما بپیوندید، و بیشتر بیشتر بدانید

مهاجرت ستون های ویژگی به لایه های پیش پردازش Keras TF2

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

آموزش یک مدل معمولاً با مقداری پیش پردازش ویژگی همراه است، به ویژه هنگامی که با داده های ساخت یافته سروکار داریم. هنگامی که آموزش یک tf.estimator.Estimator در TF1، این ویژگی پیش پردازش است که معمولا با انجام tf.feature_column API. در TF2، این فرآیندی می تواند به طور مستقیم با لایه Keras انجام می شود، به نام از پیش پردازش لایه.

در این راهنمای مهاجرت، شما با استفاده از ستون‌های ویژگی و لایه‌های پیش‌پردازش، برخی از تبدیل‌های ویژگی مشترک را انجام می‌دهید و سپس یک مدل کامل را با هر دو API آموزش می‌دهید.

ابتدا با چند واردات ضروری شروع کنید

import tensorflow as tf
import tensorflow.compat.v1 as tf1
import math

و یک ابزار برای فراخوانی یک ستون ویژگی برای نمایش اضافه کنید:

def call_feature_columns(feature_columns, inputs):
  # This is a convenient way to call a `feature_column` outside of an estimator
  # to display its output.
  feature_layer = tf1.keras.layers.DenseFeatures(feature_columns)
  return feature_layer(inputs)

مدیریت ورودی

برای استفاده از ستون‌های ویژگی با تخمین‌گر، انتظار می‌رود ورودی‌های مدل همیشه فرهنگ لغت تانسورها باشند:

input_dict = {
  'foo': tf.constant([1]),
  'bar': tf.constant([0]),
  'baz': tf.constant([-1])
}

هر ستون ویژگی باید با یک کلید ایجاد شود تا در داده های منبع فهرست شود. خروجی تمام ستون های ویژگی به هم پیوسته و توسط مدل برآوردگر استفاده می شود.

columns = [
  tf1.feature_column.numeric_column('foo'),
  tf1.feature_column.numeric_column('bar'),
  tf1.feature_column.numeric_column('baz'),
]
call_feature_columns(columns, input_dict)
<tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[ 0., -1.,  1.]], dtype=float32)>

در Keras، ورودی مدل بسیار انعطاف پذیرتر است. tf.keras.Model می توانید یک ورودی تک تانسور، لیستی از ویژگی های تانسور، و یا یک فرهنگ لغت از تانسور ویژگی های اداره کند. شما می توانید ورودی دیکشنری با عبور یک فرهنگ لغت از رسیدگی tf.keras.Input در ایجاد مدل. ورودی ها به طور خودکار به هم متصل نمی شوند، که به آنها اجازه می دهد تا به روش های بسیار انعطاف پذیرتری استفاده شوند. آنها را می توان با الحاق tf.keras.layers.Concatenate .

inputs = {
  'foo': tf.keras.Input(shape=()),
  'bar': tf.keras.Input(shape=()),
  'baz': tf.keras.Input(shape=()),
}
# Inputs are typically transformed by preprocessing layers before concatenation.
outputs = tf.keras.layers.Concatenate()(inputs.values())
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model(input_dict)
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([ 1.,  0., -1.], dtype=float32)>

شناسه‌های اعداد صحیح رمزگذاری یک‌طرفه

یک تبدیل ویژگی رایج، ورودی‌های عدد صحیح کدگذاری یک‌طرفه یک محدوده شناخته شده است. در اینجا یک مثال با استفاده از ستون های ویژگی آورده شده است:

categorical_col = tf1.feature_column.categorical_column_with_identity(
    'type', num_buckets=3)
indicator_col = tf1.feature_column.indicator_column(categorical_col)
call_feature_columns(indicator_col, {'type': [0, 1, 2]})
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]], dtype=float32)>

با استفاده از Keras پیش پردازش لایه، این ستون ها را می توان با یک جایگزین tf.keras.layers.CategoryEncoding لایه با output_mode مجموعه به 'one_hot' :

one_hot_layer = tf.keras.layers.CategoryEncoding(
    num_tokens=3, output_mode='one_hot')
one_hot_layer([0, 1, 2])
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]], dtype=float32)>

عادی سازی ویژگی های عددی

هنگامی که دست زدن مداوم، ممیز شناور ویژگی های با ستون قابلیت، شما نیاز به استفاده از یک tf.feature_column.numeric_column . در مواردی که ورودی از قبل نرمال شده است، تبدیل آن به Keras بی اهمیت است. شما می توانید به سادگی با استفاده از یک tf.keras.Input به طور مستقیم به مدل خود را، به عنوان بالا نشان داده شده.

numeric_column همچنین می توانید به ورودی عادی مورد استفاده قرار گیرد:

def normalize(x):
  mean, variance = (2.0, 1.0)
  return (x - mean) / math.sqrt(variance)
numeric_col = tf1.feature_column.numeric_column('col', normalizer_fn=normalize)
call_feature_columns(numeric_col, {'col': tf.constant([[0.], [1.], [2.]])})
<tf.Tensor: shape=(3, 1), dtype=float32, numpy=
array([[-2.],
       [-1.],
       [ 0.]], dtype=float32)>

در مقابل، با Keras، این عادی را می توان با انجام tf.keras.layers.Normalization .

normalization_layer = tf.keras.layers.Normalization(mean=2.0, variance=1.0)
normalization_layer(tf.constant([[0.], [1.], [2.]]))
<tf.Tensor: shape=(3, 1), dtype=float32, numpy=
array([[-2.],
       [-1.],
       [ 0.]], dtype=float32)>

ویژگی‌های عددی سطل‌سازی و رمزگذاری یک‌طرفه

یکی دیگر از تبدیل‌های رایج ورودی‌های ممیز شناور پیوسته، سطل‌سازی و سپس به اعداد صحیح یک محدوده ثابت است.

در ستون ویژگی، این را می توان با دست tf.feature_column.bucketized_column :

numeric_col = tf1.feature_column.numeric_column('col')
bucketized_col = tf1.feature_column.bucketized_column(numeric_col, [1, 4, 5])
call_feature_columns(bucketized_col, {'col': tf.constant([1., 2., 3., 4., 5.])})
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[0., 1., 0., 0.],
       [0., 1., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]], dtype=float32)>

در Keras، این را می توان با جایگزین tf.keras.layers.Discretization :

discretization_layer = tf.keras.layers.Discretization(bin_boundaries=[1, 4, 5])
one_hot_layer = tf.keras.layers.CategoryEncoding(
    num_tokens=4, output_mode='one_hot')
one_hot_layer(discretization_layer([1., 2., 3., 4., 5.]))
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[0., 1., 0., 0.],
       [0., 1., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]], dtype=float32)>

داده های رشته ای رمزگذاری یکباره با واژگان

مدیریت ویژگی های رشته اغلب به جستجوی واژگان برای ترجمه رشته ها به شاخص نیاز دارد. در اینجا یک مثال با استفاده از ستون های ویژگی برای جستجوی رشته ها و سپس رمزگذاری یکباره شاخص ها آورده شده است:

vocab_col = tf1.feature_column.categorical_column_with_vocabulary_list(
    'sizes',
    vocabulary_list=['small', 'medium', 'large'],
    num_oov_buckets=0)
indicator_col = tf1.feature_column.indicator_column(vocab_col)
call_feature_columns(indicator_col, {'sizes': ['small', 'medium', 'large']})
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]], dtype=float32)>

با استفاده از لایه های از پیش پردازش Keras، استفاده از tf.keras.layers.StringLookup لایه با output_mode مجموعه به 'one_hot' :

string_lookup_layer = tf.keras.layers.StringLookup(
    vocabulary=['small', 'medium', 'large'],
    num_oov_indices=0,
    output_mode='one_hot')
string_lookup_layer(['small', 'medium', 'large'])
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]], dtype=float32)>

جاسازی داده های رشته ای با واژگان

برای دایره لغات بزرگتر، اغلب برای اجرای خوب به جاسازی نیاز است. در اینجا نمونه ای از تعبیه یک ویژگی رشته با استفاده از ستون های ویژگی آورده شده است:

vocab_col = tf1.feature_column.categorical_column_with_vocabulary_list(
    'col',
    vocabulary_list=['small', 'medium', 'large'],
    num_oov_buckets=0)
embedding_col = tf1.feature_column.embedding_column(vocab_col, 4)
call_feature_columns(embedding_col, {'col': ['small', 'medium', 'large']})
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[-0.01798586, -0.2808677 ,  0.27639154,  0.06081508],
       [ 0.05771849,  0.02464074,  0.20080602,  0.50164527],
       [-0.9208247 , -0.40816694, -0.49132794,  0.9203153 ]],
      dtype=float32)>

با استفاده از لایه های از پیش پردازش Keras، این می تواند با ترکیب یک دست tf.keras.layers.StringLookup لایه و tf.keras.layers.Embedding لایه. خروجی پیش فرض برای StringLookup خواهد عدد صحیح شاخص است که می تواند به طور مستقیم به تعبیه تغذیه می شود.

string_lookup_layer = tf.keras.layers.StringLookup(
    vocabulary=['small', 'medium', 'large'], num_oov_indices=0)
embedding = tf.keras.layers.Embedding(3, 4)
embedding(string_lookup_layer(['small', 'medium', 'large']))
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[ 0.04838837, -0.04014301,  0.02001903, -0.01150769],
       [-0.04580117, -0.04319514,  0.03725603, -0.00572466],
       [-0.0401094 ,  0.00997342,  0.00111955,  0.00132702]],
      dtype=float32)>

جمع بندی داده های طبقه بندی وزن دار

در برخی موارد، باید با داده‌های طبقه‌بندی برخورد کنید، جایی که هر رخداد یک دسته با وزن مرتبطی همراه است. در ستون ویژگی، این است که با به کار گرفته tf.feature_column.weighted_categorical_column . هنگامی که با یک زوج indicator_column ، این است که اثر جمع وزن در هر رده.

ids = tf.constant([[5, 11, 5, 17, 17]])
weights = tf.constant([[0.5, 1.5, 0.7, 1.8, 0.2]])

categorical_col = tf1.feature_column.categorical_column_with_identity(
    'ids', num_buckets=20)
weighted_categorical_col = tf1.feature_column.weighted_categorical_column(
    categorical_col, 'weights')
indicator_col = tf1.feature_column.indicator_column(weighted_categorical_col)
call_feature_columns(indicator_col, {'ids': ids, 'weights': weights})
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/feature_column/feature_column_v2.py:4203: sparse_merge (from tensorflow.python.ops.sparse_ops) is deprecated and will be removed in a future version.
Instructions for updating:
No similar op available at this time.
<tf.Tensor: shape=(1, 20), dtype=float32, numpy=
array([[0. , 0. , 0. , 0. , 0. , 1.2, 0. , 0. , 0. , 0. , 0. , 1.5, 0. ,

        0. , 0. , 0. , 0. , 2. , 0. , 0. ]], dtype=float32)>

در Keras، این را می توان با عبور از یک انجام count_weights ورودی به tf.keras.layers.CategoryEncoding با output_mode='count' .

ids = tf.constant([[5, 11, 5, 17, 17]])
weights = tf.constant([[0.5, 1.5, 0.7, 1.8, 0.2]])

# Using sparse output is more efficient when `num_tokens` is large.
count_layer = tf.keras.layers.CategoryEncoding(
    num_tokens=20, output_mode='count', sparse=True)
tf.sparse.to_dense(count_layer(ids, count_weights=weights))
<tf.Tensor: shape=(1, 20), dtype=float32, numpy=
array([[0. , 0. , 0. , 0. , 0. , 1.2, 0. , 0. , 0. , 0. , 0. , 1.5, 0. ,

        0. , 0. , 0. , 0. , 2. , 0. , 0. ]], dtype=float32)>

جاسازی داده های دسته بندی وزن دار

ممکن است به طور متناوب بخواهید ورودی های دسته بندی وزنی را جاسازی کنید. در ستون ویژگی، embedding_column شامل یک combiner استدلال است. اگر هر کدام از نمونه حاوی چند ورودی برای یک دسته بندی، آنها را با توجه به تنظیمات استدلال (به طور پیش فرض همراه 'mean' ).

ids = tf.constant([[5, 11, 5, 17, 17]])
weights = tf.constant([[0.5, 1.5, 0.7, 1.8, 0.2]])

categorical_col = tf1.feature_column.categorical_column_with_identity(
    'ids', num_buckets=20)
weighted_categorical_col = tf1.feature_column.weighted_categorical_column(
    categorical_col, 'weights')
embedding_col = tf1.feature_column.embedding_column(
    weighted_categorical_col, 4, combiner='mean')
call_feature_columns(embedding_col, {'ids': ids, 'weights': weights})
<tf.Tensor: shape=(1, 4), dtype=float32, numpy=
array([[ 0.02666993,  0.289671  ,  0.18065728, -0.21045178]],
      dtype=float32)>

در Keras است، هیچ وجود دارد combiner گزینه ای برای tf.keras.layers.Embedding ، اما شما می توانید همان اثر را با دستیابی به tf.keras.layers.Dense . embedding_column بالا است که به سادگی خطی ترکیب بردار تعبیه با توجه به وزن. هر چند در ابتدا آشکار نیست، آن را دقیقا به نمایندگی از ورودی طبقه خود را به عنوان یک بردار وزن پراکنده از اندازه معادل است (num_tokens) ، و mutiplying آنها را با یک Dense هسته شکل (embedding_size, num_tokens) .

ids = tf.constant([[5, 11, 5, 17, 17]])
weights = tf.constant([[0.5, 1.5, 0.7, 1.8, 0.2]])

# For `combiner='mean'`, normalize your weights to sum to 1. Removing this line
# would be eqivalent to an `embedding_column` with `combiner='sum'`.
weights = weights / tf.reduce_sum(weights, axis=-1, keepdims=True)

count_layer = tf.keras.layers.CategoryEncoding(
    num_tokens=20, output_mode='count', sparse=True)
embedding_layer = tf.keras.layers.Dense(4, use_bias=False)
embedding_layer(count_layer(ids, count_weights=weights))
<tf.Tensor: shape=(1, 4), dtype=float32, numpy=
array([[-0.03897291, -0.27131438,  0.09332469,  0.04333957]],
      dtype=float32)>

نمونه آموزش کامل

برای نمایش یک گردش کار آموزشی کامل، ابتدا تعدادی داده با سه ویژگی از انواع مختلف آماده کنید:

features = {
    'type': [0, 1, 1],
    'size': ['small', 'small', 'medium'],
    'weight': [2.7, 1.8, 1.6],
}
labels = [1, 1, 0]
predict_features = {'type': [0], 'size': ['foo'], 'weight': [-0.7]}

برخی از ثابت های رایج را برای هر دو گردش کار TF1 و TF2 تعریف کنید:

vocab = ['small', 'medium', 'large']
one_hot_dims = 3
embedding_dims = 4
weight_mean = 2.0
weight_variance = 1.0

با ستون های ویژگی

ستون‌های ویژگی باید به‌عنوان فهرستی به تخمین‌گر در هنگام ایجاد ارسال شوند و در طول آموزش به طور ضمنی فراخوانی می‌شوند.

categorical_col = tf1.feature_column.categorical_column_with_identity(
    'type', num_buckets=one_hot_dims)
# Convert index to one-hot; e.g. [2] -> [0,0,1].
indicator_col = tf1.feature_column.indicator_column(categorical_col)

# Convert strings to indices; e.g. ['small'] -> [1].
vocab_col = tf1.feature_column.categorical_column_with_vocabulary_list(
    'size', vocabulary_list=vocab, num_oov_buckets=1)
# Embed the indices.
embedding_col = tf1.feature_column.embedding_column(vocab_col, embedding_dims)

normalizer_fn = lambda x: (x - weight_mean) / math.sqrt(weight_variance)
# Normalize the numeric inputs; e.g. [2.0] -> [0.0].
numeric_col = tf1.feature_column.numeric_column(
    'weight', normalizer_fn=normalizer_fn)

estimator = tf1.estimator.DNNClassifier(
    feature_columns=[indicator_col, embedding_col, numeric_col],
    hidden_units=[1])

def _input_fn():
  return tf1.data.Dataset.from_tensor_slices((features, labels)).batch(1)

estimator.train(_input_fn)
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp8lwbuor2
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp8lwbuor2', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_checkpoint_save_graph_def': True, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/training/adagrad.py:77: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp8lwbuor2/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 0.54634213, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 3...
INFO:tensorflow:Saving checkpoints for 3 into /tmp/tmp8lwbuor2/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 3...
INFO:tensorflow:Loss for final step: 0.7308526.
<tensorflow_estimator.python.estimator.canned.dnn.DNNClassifier at 0x7f90685d53d0>

ستون های ویژگی همچنین برای تبدیل داده های ورودی هنگام اجرای استنتاج بر روی مدل استفاده خواهند شد.

def _predict_fn():
  return tf1.data.Dataset.from_tensor_slices(predict_features).batch(1)

next(estimator.predict(_predict_fn))
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmp8lwbuor2/model.ckpt-3
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
{'logits': array([0.5172372], dtype=float32),
 'logistic': array([0.6265015], dtype=float32),
 'probabilities': array([0.37349847, 0.6265015 ], dtype=float32),
 'class_ids': array([1]),
 'classes': array([b'1'], dtype=object),
 'all_class_ids': array([0, 1], dtype=int32),
 'all_classes': array([b'0', b'1'], dtype=object)}

با لایه های پیش پردازش Keras

لایه های پیش پردازش Keras در جایی که می توان آنها را فراخوانی کرد انعطاف پذیرتر هستند. یک لایه می تواند به طور مستقیم به تانسورها اعمال می شود، مورد استفاده قرار در داخل یک tf.data خط لوله ورودی، یا به طور مستقیم به یک مدل Keras تربیت شدنی ساخته شده است.

در این مثال، شما اعمال خواهد شد از پیش پردازش لایه داخل یک tf.data خط لوله ورودی. برای این کار، شما می توانید یک جداگانه تعریف tf.keras.Model پیش پردازش ویژگی های ورودی خود را. این مدل قابل آموزش نیست، اما راهی مناسب برای گروه بندی لایه های پیش پردازش است.

inputs = {
  'type': tf.keras.Input(shape=(), dtype='int64'),
  'size': tf.keras.Input(shape=(), dtype='string'),
  'weight': tf.keras.Input(shape=(), dtype='float32'),
}
# Convert index to one-hot; e.g. [2] -> [0,0,1].
type_output = tf.keras.layers.CategoryEncoding(
      one_hot_dims, output_mode='one_hot')(inputs['type'])
# Convert size strings to indices; e.g. ['small'] -> [1].
size_output = tf.keras.layers.StringLookup(vocabulary=vocab)(inputs['size'])
# Normalize the numeric inputs; e.g. [2.0] -> [0.0].
weight_output = tf.keras.layers.Normalization(
      axis=None, mean=weight_mean, variance=weight_variance)(inputs['weight'])
outputs = {
  'type': type_output,
  'size': size_output,
  'weight': weight_output,
}
preprocessing_model = tf.keras.Model(inputs, outputs)

شما هم اکنون می توانید این مدل در داخل یک پاسخ به درخواست tf.data.Dataset.map . لطفا توجه داشته باشید که تابع به تصویب رسید به map به طور خودکار به تبدیل می شود tf.function و هشدارهای معمول برای نوشتن tf.function کد اعمال می شود (بدون عوارض جانبی).

# Apply the preprocessing in tf.data.Dataset.map.
dataset = tf.data.Dataset.from_tensor_slices((features, labels)).batch(1)
dataset = dataset.map(lambda x, y: (preprocessing_model(x), y),
                      num_parallel_calls=tf.data.AUTOTUNE)
# Display a preprocessed input sample.
next(dataset.take(1).as_numpy_iterator())
({'type': array([[1., 0., 0.]], dtype=float32),
  'size': array([1]),
  'weight': array([0.70000005], dtype=float32)},
 array([1], dtype=int32))

بعد، شما می توانید یک جداگانه تعریف Model حاوی لایه های تربیت شدنی توجه داشته باشید که چگونه ورودی های این مدل اکنون انواع و اشکال ویژگی های از پیش پردازش شده را منعکس می کنند.

inputs = {
  'type': tf.keras.Input(shape=(one_hot_dims,), dtype='float32'),
  'size': tf.keras.Input(shape=(), dtype='int64'),
  'weight': tf.keras.Input(shape=(), dtype='float32'),
}
# Since the embedding is trainable, it needs to be part of the training model.
embedding = tf.keras.layers.Embedding(len(vocab), embedding_dims)
outputs = tf.keras.layers.Concatenate()([
  inputs['type'],
  embedding(inputs['size']),
  tf.expand_dims(inputs['weight'], -1),
])
outputs = tf.keras.layers.Dense(1)(outputs)
training_model = tf.keras.Model(inputs, outputs)

شما هم اکنون می توانید آموزش training_model با tf.keras.Model.fit .

# Train on the preprocessed data.
training_model.compile(
    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True))
training_model.fit(dataset)
3/3 [==============================] - 0s 3ms/step - loss: 0.7248
<keras.callbacks.History at 0x7f9041a294d0>

در نهایت، در زمان استنتاج، ترکیب این مراحل جداگانه در یک مدل واحد که ورودی های ویژگی خام را مدیریت می کند، می تواند مفید باشد.

inputs = preprocessing_model.input
outpus = training_model(preprocessing_model(inputs))
inference_model = tf.keras.Model(inputs, outpus)

predict_dataset = tf.data.Dataset.from_tensor_slices(predict_features).batch(1)
inference_model.predict(predict_dataset)
array([[0.936637]], dtype=float32)

این مدل تشکیل شده می تواند به عنوان یک ذخیره SavedModel برای استفاده های بعدی.

inference_model.save('model')
restored_model = tf.keras.models.load_model('model')
restored_model.predict(predict_dataset)
WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.
2021-10-27 01:23:25.649967: 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: model/assets
WARNING:tensorflow:No training configuration found in save file, so the model was *not* compiled. Compile it manually.
array([[0.936637]], dtype=float32)

جدول معادل ستون ویژگی

برای مرجع، در اینجا یک مطابقت تقریبی بین ستون های ویژگی و لایه های پیش پردازش وجود دارد:

ستون ویژگی لایه کراس
feature_column.bucketized_column layers.Discretization
feature_column.categorical_column_with_hash_bucket layers.Hashing
feature_column.categorical_column_with_identity layers.CategoryEncoding
feature_column.categorical_column_with_vocabulary_file layers.StringLookup یا layers.IntegerLookup
feature_column.categorical_column_with_vocabulary_list layers.StringLookup یا layers.IntegerLookup
feature_column.crossed_column اجرا نشده.
feature_column.embedding_column layers.Embedding
feature_column.indicator_column output_mode='one_hot' یا output_mode='multi_hot' *
feature_column.numeric_column layers.Normalization
feature_column.sequence_categorical_column_with_hash_bucket layers.Hashing
feature_column.sequence_categorical_column_with_identity layers.CategoryEncoding
feature_column.sequence_categorical_column_with_vocabulary_file layers.StringLookup ، layers.IntegerLookup یا layer.TextVectorization
feature_column.sequence_categorical_column_with_vocabulary_list layers.StringLookup ، layers.IntegerLookup یا layer.TextVectorization
feature_column.sequence_numeric_column layers.Normalization
feature_column.weighted_categorical_column layers.CategoryEncoding

* output_mode را می توان به تصویب layers.CategoryEncoding ، layers.StringLookup ، layers.IntegerLookup و layers.TextVectorization .

layers.TextVectorization می توانید ورودی متن freeform مستقیم (به عنوان مثال کل جملات و پاراگرافها) را اداره کند. این جایگزینی یک به یک برای مدیریت توالی طبقه بندی شده در TF1 نیست، اما ممکن است جایگزین مناسبی برای پیش پردازش متن ad-hoc باشد.

مراحل بعدی