Lihat di TensorFlow.org | Jalankan di Google Colab | Lihat sumber di GitHub | Unduh buku catatan |
Melatih model biasanya akan disertai dengan sejumlah fitur prapemrosesan, terutama saat menangani data terstruktur. Saat melatih tf.estimator.Estimator
di TF1, prapemrosesan fitur ini biasanya dilakukan dengan API tf.feature_column
. Pada TF2, preprocessing ini dapat dilakukan secara langsung dengan lapisan Keras, yang disebut lapisan preprocessing .
Dalam panduan migrasi ini, Anda akan melakukan beberapa transformasi fitur umum menggunakan kolom fitur dan lapisan prapemrosesan, diikuti dengan melatih model lengkap dengan kedua API.
Pertama, mulailah dengan beberapa impor yang diperlukan,
import tensorflow as tf
import tensorflow.compat.v1 as tf1
import math
dan tambahkan utilitas untuk memanggil kolom fitur untuk demonstrasi:
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)
Penanganan masukan
Untuk menggunakan kolom fitur dengan estimator, input model selalu diharapkan menjadi kamus tensor:
input_dict = {
'foo': tf.constant([1]),
'bar': tf.constant([0]),
'baz': tf.constant([-1])
}
Setiap kolom fitur perlu dibuat dengan kunci untuk mengindeks ke data sumber. Output dari semua kolom fitur digabungkan dan digunakan oleh model estimator.
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)>
Di Keras, input model jauh lebih fleksibel. tf.keras.Model
dapat menangani satu input tensor, daftar fitur tensor, atau kamus fitur tensor. Anda dapat menangani input kamus dengan melewatkan kamus tf.keras.Input
pada pembuatan model. Input tidak akan digabungkan secara otomatis, yang memungkinkannya digunakan dengan cara yang jauh lebih fleksibel. Mereka dapat digabungkan dengan 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)>
ID integer enkode satu-panas
Transformasi fitur umum adalah input integer pengkodean satu-panas dari rentang yang diketahui. Berikut adalah contoh menggunakan kolom fitur:
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)>
Menggunakan lapisan prapemrosesan Keras, kolom-kolom ini dapat diganti dengan satu lapisan tf.keras.layers.CategoryEncoding
dengan output_mode
disetel ke '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)>
Menormalkan fitur numerik
Saat menangani fitur floating-point berkelanjutan dengan kolom fitur, Anda perlu menggunakan tf.feature_column.numeric_column
. Dalam kasus di mana input sudah dinormalisasi, mengonversinya ke Keras adalah hal yang sepele. Anda cukup menggunakan tf.keras.Input
langsung ke model Anda, seperti yang ditunjukkan di atas.
numeric_column
juga dapat digunakan untuk menormalkan input:
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)>
Berbeda dengan Keras, normalisasi ini dapat dilakukan dengan 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)>
Fitur numerik pengkodean Bucketizing dan one-hot
Transformasi umum lainnya dari input floating point berkelanjutan adalah mengelompokkan kemudian ke bilangan bulat dari rentang tetap.
Di kolom fitur, ini dapat dicapai dengan 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)>
Di Keras, ini bisa diganti dengan 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)>
Data string penyandian satu-panas dengan kosakata
Menangani fitur string seringkali membutuhkan pencarian kosakata untuk menerjemahkan string ke dalam indeks. Berikut adalah contoh menggunakan kolom fitur untuk mencari string dan kemudian mengkodekan indeks secara one-hot:
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)>
Menggunakan lapisan pra-pemrosesan Keras, gunakan lapisan tf.keras.layers.StringLookup
dengan output_mode
disetel ke '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)>
Menanamkan data string dengan kosakata
Untuk kosakata yang lebih besar, penyematan sering kali diperlukan untuk kinerja yang baik. Berikut adalah contoh penyematan fitur string menggunakan kolom fitur:
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)>
Menggunakan lapisan prapemrosesan Keras, ini dapat dicapai dengan menggabungkan lapisan tf.keras.layers.StringLookup
dan lapisan tf.keras.layers.Embedding
. Output default untuk StringLookup
akan berupa indeks integer yang dapat dimasukkan langsung ke dalam embedding.
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)>
Menjumlahkan data kategorikal berbobot
Dalam beberapa kasus, Anda perlu berurusan dengan data kategorikal di mana setiap kemunculan kategori datang dengan bobot terkait. Di kolom fitur, ini ditangani dengan tf.feature_column.weighted_categorical_column
. Saat dipasangkan dengan indicator_column
, ini memiliki efek menjumlahkan bobot per kategori.
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)>
Di Keras, ini dapat dilakukan dengan meneruskan input count_weights
ke tf.keras.layers.CategoryEncoding
dengan 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)>
Menyematkan data kategorikal berbobot
Anda mungkin ingin menyematkan input kategorikal berbobot secara bergantian. Di kolom fitur, embedding_column
berisi argumen combiner
. Jika ada sampel yang berisi beberapa entri untuk suatu kategori, mereka akan digabungkan sesuai dengan pengaturan argumen (secara default '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)>
Di Keras, tidak ada opsi combiner
untuk tf.keras.layers.Embedding
, tetapi Anda dapat mencapai efek yang sama dengan tf.keras.layers.Dense
. Kolom embedding_column
di atas secara sederhana menggabungkan vektor embedding menurut bobot kategori. Meskipun tidak jelas pada awalnya, ini persis sama dengan mewakili input kategoris Anda sebagai vektor ukuran berat yang jarang (num_tokens)
, dan mengalikannya dengan kernel bentuk yang 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)>
Contoh pelatihan lengkap
Untuk menampilkan alur kerja pelatihan yang lengkap, pertama-tama siapkan beberapa data dengan tiga fitur dari jenis yang berbeda:
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]}
Tentukan beberapa konstanta umum untuk alur kerja TF1 dan TF2:
vocab = ['small', 'medium', 'large']
one_hot_dims = 3
embedding_dims = 4
weight_mean = 2.0
weight_variance = 1.0
Dengan kolom fitur
Kolom fitur harus diteruskan sebagai daftar ke estimator saat pembuatan, dan akan dipanggil secara implisit selama pelatihan.
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>
Kolom fitur juga akan digunakan untuk mengubah data input saat menjalankan inferensi pada model.
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)}
Dengan lapisan pra-pemrosesan Keras
Lapisan preprocessing keras lebih fleksibel di mana mereka dapat dipanggil. Lapisan dapat diterapkan langsung ke tensor, digunakan di dalam pipa input tf.data
, atau dibangun langsung ke dalam model Keras yang dapat dilatih.
Dalam contoh ini, Anda akan menerapkan lapisan prapemrosesan di dalam pipa input tf.data
. Untuk melakukan ini, Anda dapat menentukan tf.keras.Model
terpisah untuk memproses fitur input terlebih dahulu. Model ini tidak dapat dilatih, tetapi merupakan cara mudah untuk mengelompokkan lapisan prapemrosesan.
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)
Anda sekarang dapat menerapkan model ini di dalam panggilan ke tf.data.Dataset.map
. Harap dicatat bahwa fungsi yang diteruskan ke map
akan secara otomatis diubah menjadi tf.function
, dan peringatan biasa untuk penulisan kode tf.function
berlaku (tanpa efek samping).
# 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))
Selanjutnya, Anda dapat menentukan Model
terpisah yang berisi lapisan yang dapat dilatih. Perhatikan bagaimana input ke model ini sekarang mencerminkan jenis dan bentuk fitur yang telah diproses sebelumnya.
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)
Anda sekarang dapat melatih training_model
dengan 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>
Terakhir, pada waktu inferensi, akan berguna untuk menggabungkan tahapan terpisah ini menjadi satu model yang menangani input fitur mentah.
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)
Model tersusun ini dapat disimpan sebagai SavedModel untuk digunakan nanti.
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)
Fitur tabel kesetaraan kolom
Untuk referensi, berikut adalah perkiraan korespondensi antara kolom fitur dan lapisan prapemrosesan:
* output_mode
dapat diteruskan ke layers.CategoryEncoding
, layers.StringLookup
, layers.IntegerLookup
, dan layers.TextVectorization
.
layers.TextVectorization
dapat menangani input teks bentuk bebas secara langsung (misalnya seluruh kalimat atau paragraf). Ini bukan pengganti satu-ke-satu untuk penanganan urutan kategorikal di TF1, tetapi mungkin menawarkan pengganti yang nyaman untuk prapemrosesan teks ad-hoc.
Langkah selanjutnya
- Untuk informasi lebih lanjut tentang lapisan preprocessing keras, lihat panduan untuk lapisan preprocessing .
- Untuk contoh yang lebih mendalam tentang penerapan lapisan prapemrosesan ke data terstruktur, lihat tutorial data terstruktur .