Visualizza su TensorFlow.org | Esegui in Google Colab | Visualizza l'origine su GitHub | Scarica quaderno |
L'addestramento di un modello di solito comporta una certa quantità di preelaborazione delle funzionalità, in particolare quando si tratta di dati strutturati. Quando si esegue l'addestramento di un tf.estimator.Estimator
in TF1, questa preelaborazione delle funzionalità viene in genere eseguita con l'API tf.feature_column
. In TF2, questa preelaborazione può essere eseguita direttamente con i livelli Keras, chiamati livelli di preelaborazione .
In questa guida alla migrazione, eseguirai alcune trasformazioni di funzionalità comuni utilizzando sia le colonne delle funzionalità che i livelli di preelaborazione, seguite dal training di un modello completo con entrambe le API.
Innanzitutto, inizia con un paio di importazioni necessarie,
import tensorflow as tf
import tensorflow.compat.v1 as tf1
import math
e aggiungi un'utilità per chiamare una colonna di funzionalità per la dimostrazione:
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)
Gestione dell'input
Per utilizzare le colonne delle caratteristiche con uno stimatore, ci si aspetta sempre che gli input del modello siano un dizionario di tensori:
input_dict = {
'foo': tf.constant([1]),
'bar': tf.constant([0]),
'baz': tf.constant([-1])
}
Ogni colonna di funzionalità deve essere creata con una chiave da indicizzare nei dati di origine. L'output di tutte le colonne delle caratteristiche viene concatenato e utilizzato dal modello di stima.
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)>
In Keras, l'input del modello è molto più flessibile. Un tf.keras.Model
può gestire un singolo input tensore, un elenco di funzioni tensoriali o un dizionario di funzioni tensoriali. È possibile gestire l'input del dizionario passando un dizionario di tf.keras.Input
alla creazione del modello. Gli input non verranno concatenati automaticamente, il che consente di utilizzarli in modi molto più flessibili. Possono essere concatenati con 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 interi di codifica one-hot
Una trasformazione caratteristica comune è costituita da input interi di codifica one-hot di un intervallo noto. Ecco un esempio che utilizza le colonne delle funzioni:
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)>
Utilizzando i livelli di preelaborazione Keras, queste colonne possono essere sostituite da un singolo livello tf.keras.layers.CategoryEncoding
con output_mode
impostato su '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)>
Normalizzazione delle caratteristiche numeriche
Quando si gestiscono funzionalità continue a virgola mobile con colonne di funzionalità, è necessario utilizzare un tf.feature_column.numeric_column
. Nel caso in cui l'input sia già normalizzato, convertirlo in Keras è banale. Puoi semplicemente usare un tf.keras.Input
direttamente nel tuo modello, come mostrato sopra.
Una numeric_column
può anche essere utilizzata per normalizzare l'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)>
Al contrario, con Keras, questa normalizzazione può essere eseguita con 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)>
Funzioni numeriche di bucket e codifica one-hot
Un'altra trasformazione comune degli input a virgola mobile continui consiste nel bucketizzare quindi in numeri interi di un intervallo fisso.
Nelle colonne delle funzionalità, questo può essere ottenuto con un 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)>
In Keras, questo può essere sostituito da 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)>
Dati di stringa di codifica one-hot con un vocabolario
La gestione delle caratteristiche delle stringhe spesso richiede una ricerca del vocabolario per tradurre le stringhe in indici. Ecco un esempio che utilizza le colonne delle funzionalità per cercare le stringhe e quindi codificare gli indici a caldo:
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)>
Usando i livelli di preelaborazione Keras, usa il livello tf.keras.layers.StringLookup
con output_mode
impostato su '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)>
Incorporamento di dati di stringa con un vocabolario
Per vocabolari più ampi, è spesso necessario un incorporamento per ottenere buone prestazioni. Ecco un esempio di incorporamento di una funzione di stringa utilizzando le colonne di funzione:
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)>
Utilizzando i livelli di preelaborazione Keras, questo può essere ottenuto combinando un livello tf.keras.layers.StringLookup
e un livello tf.keras.layers.Embedding
. L'output predefinito per StringLookup
saranno indici interi che possono essere inseriti direttamente in un incorporamento.
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)>
Somma di dati categoriali ponderati
In alcuni casi, è necessario gestire dati categoriali in cui ogni occorrenza di una categoria ha un peso associato. Nelle colonne delle funzioni, questo viene gestito con tf.feature_column.weighted_categorical_column
. Se associato a un indicator_column
, ha l'effetto di sommare i pesi per categoria.
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)>
In Keras, questo può essere fatto passando un input count_weights
a tf.keras.layers.CategoryEncoding
con 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)>
Incorporamento di dati categoriali ponderati
In alternativa potresti voler incorporare input categoriali ponderati. Nelle colonne delle funzioni, embedding_column
contiene un argomento combiner
. Se un campione contiene più voci per una categoria, verranno combinate in base all'impostazione dell'argomento (per impostazione predefinita '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)>
In Keras, non esiste un'opzione di tf.keras.layers.Embedding
combiner
ma puoi ottenere lo stesso effetto con tf.keras.layers.Dense
. La embedding_column
sopra sta semplicemente combinando linearmente i vettori di incorporamento in base al peso della categoria. Sebbene all'inizio non sia ovvio, equivale esattamente a rappresentare i tuoi input categoriali come un vettore di dimensioni (num_tokens)
e a moltiplicarli per un kernel Dense
di forma (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)>
Esempio di formazione completo
Per mostrare un flusso di lavoro di formazione completo, prepara prima alcuni dati con tre caratteristiche di diverso tipo:
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]}
Definisci alcune costanti comuni per i flussi di lavoro TF1 e TF2:
vocab = ['small', 'medium', 'large']
one_hot_dims = 3
embedding_dims = 4
weight_mean = 2.0
weight_variance = 1.0
Con colonne caratteristiche
Le colonne delle caratteristiche devono essere passate come elenco allo stimatore al momento della creazione e verranno chiamate implicitamente durante l'addestramento.
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>
Le colonne delle funzioni verranno utilizzate anche per trasformare i dati di input durante l'esecuzione dell'inferenza sul modello.
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)}
Con i livelli di preelaborazione Keras
I livelli di preelaborazione Keras sono più flessibili in cui possono essere richiamati. Un livello può essere applicato direttamente ai tensori, utilizzato all'interno di una pipeline di input tf.data
o integrato direttamente in un modello Keras addestrabile.
In questo esempio, applicherai livelli di preelaborazione all'interno di una pipeline di input tf.data
. Per fare ciò, puoi definire un tf.keras.Model
separato per preelaborare le tue caratteristiche di input. Questo modello non è addestrabile, ma è un modo conveniente per raggruppare i livelli di preelaborazione.
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)
Ora puoi applicare questo modello all'interno di una chiamata a tf.data.Dataset.map
. Tieni presente che la funzione passata a map
verrà automaticamente convertita in tf.function
e si applicano le solite avvertenze per la scrittura del codice tf.function
(nessun effetto collaterale).
# 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))
Successivamente, puoi definire un Model
separato contenente i livelli addestrabili. Nota come gli input di questo modello ora riflettano i tipi e le forme delle feature preelaborate.
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)
Ora puoi addestrare training_model
con 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>
Infine, al momento dell'inferenza, può essere utile combinare queste fasi separate in un unico modello che gestisce gli input delle feature grezze.
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)
Questo modello composto può essere salvato come SavedModel per un uso successivo.
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)
Tabella di equivalenza delle colonne delle funzioni
Per riferimento, ecco una corrispondenza approssimativa tra le colonne delle caratteristiche e i livelli di preelaborazione:
* output_mode
può essere passato a layers.CategoryEncoding
, layers.StringLookup
, layers.IntegerLookup
e layers.TextVectorization
.
† layers.TextVectorization
può gestire direttamente l'input di testo a mano libera (ad es. intere frasi o paragrafi). Questo non è un sostituto uno a uno per la gestione delle sequenze categoriali in TF1, ma può offrire un sostituto conveniente per la preelaborazione del testo ad hoc.
Prossimi passi
- Per ulteriori informazioni sui livelli di preelaborazione keras, vedere la guida ai livelli di preelaborazione .
- Per un esempio più approfondito dell'applicazione dei livelli di preelaborazione ai dati strutturati, vedere l'esercitazione sui dati strutturati .