Làm việc với các lớp tiền xử lý

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

Tiền xử lý Keras

API lớp tiền xử lý Keras cho phép các nhà phát triển xây dựng các đường ống xử lý đầu vào gốc Keras. Các đường ống xử lý đầu vào này có thể được sử dụng làm mã tiền xử lý độc lập trong quy trình làm việc không phải của Keras, kết hợp trực tiếp với các mô hình Keras và được xuất như một phần của Keras SavedModel.

Với các lớp tiền xử lý của Keras, bạn có thể xây dựng và xuất các mô hình thực sự từ đầu đến cuối: mô hình chấp nhận hình ảnh thô hoặc dữ liệu có cấu trúc thô làm đầu vào; các mô hình tự xử lý việc chuẩn hóa tính năng hoặc lập chỉ mục giá trị tính năng.

Xử lý trước có sẵn

Xử lý trước văn bản

  • tf.keras.layers.TextVectorization : biến chuỗi thô thành một đại diện được mã hóa có thể được đọc bởi một Embedding lớp hoặc Dense lớp.

Xử lý trước các tính năng số

Các tính năng phân loại tiền xử lý

  • tf.keras.layers.CategoryEncoding : lần lượt số nguyên tính năng phân loại vào cơ quan đại diện dày đặc một nóng, đa nóng, hoặc đếm.
  • tf.keras.layers.Hashing : Thực hiện phân loại tính năng băm, còn được gọi là "băm lừa".
  • tf.keras.layers.StringLookup : lượt chuỗi phân loại đánh giá cao một đại diện được mã hóa có thể được đọc bởi một Embedding lớp hoặc Dense lớp.
  • tf.keras.layers.IntegerLookup : lần lượt số nguyên giá trị phân loại vào một đại diện được mã hóa có thể được đọc bởi một Embedding lớp hoặc Dense lớp.

Xử lý trước hình ảnh

Các lớp này dùng để chuẩn hóa các đầu vào của mô hình hình ảnh.

  • tf.keras.layers.Resizing : thay đổi kích thước một loạt hình ảnh đến một kích thước mục tiêu.
  • tf.keras.layers.Rescaling : lại tỷ lệ chia và offsets các giá trị của một loạt các hình ảnh (ví dụ đi từ nguyên liệu đầu vào trong [0, 255] phạm vi đầu vào trong [0, 1] phạm vi.
  • tf.keras.layers.CenterCrop : trả về một vụ trung tâm của một loạt các hình ảnh.

Tăng dữ liệu hình ảnh

Các lớp này áp dụng các phép biến đổi tăng ngẫu nhiên cho một loạt ảnh. Họ chỉ hoạt động trong quá trình đào tạo.

Các adapt() phương pháp

Một số lớp tiền xử lý có trạng thái bên trong có thể được tính toán dựa trên một mẫu dữ liệu huấn luyện. Danh sách các lớp tiền xử lý trạng thái là:

  • TextVectorization : giữ một ánh xạ giữa thẻ chuỗi và các chỉ số số nguyên
  • StringLookupIntegerLookup : giữ một ánh xạ giữa các giá trị đầu vào và chỉ số số nguyên.
  • Normalization : giữ độ lệch trung bình và tiêu chuẩn của các tính năng.
  • Discretization : chứa thông tin về ranh giới xô giá trị.

Quan trọng hơn, các lớp đều là phòng không khả năng huấn luyện. Trạng thái của họ không được thiết lập trong quá trình đào tạo; nó phải được đặt trước đào tạo, hoặc bằng cách khởi tạo chúng từ một hằng số precomputed, hoặc bằng cách "thích nghi" chúng trên dữ liệu.

Bạn đặt trạng thái của một lớp tiền xử lý bằng cách phơi bày nó cho dữ liệu huấn luyện, thông qua adapt() phương pháp:

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers

data = np.array([[0.1, 0.2, 0.3], [0.8, 0.9, 1.0], [1.5, 1.6, 1.7],])
layer = layers.Normalization()
layer.adapt(data)
normalized_data = layer(data)

print("Features mean: %.2f" % (normalized_data.numpy().mean()))
print("Features std: %.2f" % (normalized_data.numpy().std()))
Features mean: -0.00
Features std: 1.00

Các adapt() phương pháp mất hoặc là một mảng NumPy hoặc một tf.data.Dataset đối tượng. Trong trường hợp của StringLookupTextVectorization , bạn cũng có thể vượt qua một danh sách các chuỗi:

data = [
    "ξεῖν᾽, ἦ τοι μὲν ὄνειροι ἀμήχανοι ἀκριτόμυθοι",
    "γίγνοντ᾽, οὐδέ τι πάντα τελείεται ἀνθρώποισι.",
    "δοιαὶ γάρ τε πύλαι ἀμενηνῶν εἰσὶν ὀνείρων:",
    "αἱ μὲν γὰρ κεράεσσι τετεύχαται, αἱ δ᾽ ἐλέφαντι:",
    "τῶν οἳ μέν κ᾽ ἔλθωσι διὰ πριστοῦ ἐλέφαντος,",
    "οἵ ῥ᾽ ἐλεφαίρονται, ἔπε᾽ ἀκράαντα φέροντες:",
    "οἱ δὲ διὰ ξεστῶν κεράων ἔλθωσι θύραζε,",
    "οἵ ῥ᾽ ἔτυμα κραίνουσι, βροτῶν ὅτε κέν τις ἴδηται.",
]
layer = layers.TextVectorization()
layer.adapt(data)
vectorized_text = layer(data)
print(vectorized_text)
tf.Tensor(
[[37 12 25  5  9 20 21  0  0]
 [51 34 27 33 29 18  0  0  0]
 [49 52 30 31 19 46 10  0  0]
 [ 7  5 50 43 28  7 47 17  0]
 [24 35 39 40  3  6 32 16  0]
 [ 4  2 15 14 22 23  0  0  0]
 [36 48  6 38 42  3 45  0  0]
 [ 4  2 13 41 53  8 44 26 11]], shape=(8, 9), dtype=int64)

Ngoài ra, các lớp có thể thích ứng luôn hiển thị một tùy chọn để thiết lập trực tiếp trạng thái thông qua các đối số của hàm tạo hoặc phép gán trọng số. Nếu các giá trị nhà nước dành được biết vào thời điểm xây dựng lớp, hoặc được tính toán bên ngoài của adapt() cuộc gọi, họ có thể được thiết lập mà không dựa vào tính toán nội bộ của lớp. Ví dụ, nếu các tập tin từ vựng bên ngoài cho TextVectorization , StringLookup , hoặc IntegerLookup lớp đã tồn tại, những người có thể được nạp trực tiếp vào các bảng tra cứu bằng cách thông qua một đường dẫn đến file từ vựng trong lập luận constructor của lớp.

Dưới đây là một ví dụ mà chúng ta khởi tạo một StringLookup lớp với từ vựng precomputed:

vocab = ["a", "b", "c", "d"]
data = tf.constant([["a", "c", "d"], ["d", "z", "b"]])
layer = layers.StringLookup(vocabulary=vocab)
vectorized_data = layer(data)
print(vectorized_data)
tf.Tensor(
[[1 3 4]
 [4 0 2]], shape=(2, 3), dtype=int64)

Xử lý trước dữ liệu trước mô hình hoặc bên trong mô hình

Có hai cách bạn có thể sử dụng các lớp tiền xử lý:

Lựa chọn 1: Làm cho họ một phần của mô hình, như thế này:

inputs = keras.Input(shape=input_shape)
x = preprocessing_layer(inputs)
outputs = rest_of_the_model(x)
model = keras.Model(inputs, outputs)

Với tùy chọn này, quá trình tiền xử lý sẽ xảy ra trên thiết bị, đồng bộ với phần còn lại của quá trình thực thi mô hình, có nghĩa là nó sẽ được hưởng lợi từ việc tăng tốc GPU. Nếu bạn đào tạo đang ở trên GPU, đây là lựa chọn tốt nhất cho Normalization lớp, và cho tất cả các hình ảnh tiền xử lý và các lớp dữ liệu tăng thêm.

Phương án 2: áp dụng nó cho bạn tf.data.Dataset , để có được một tập dữ liệu mà sản lượng lô dữ liệu xử lý trước, như thế này:

dataset = dataset.map(lambda x, y: (preprocessing_layer(x), y))

Với tùy chọn này, quá trình xử lý trước của bạn sẽ xảy ra trên CPU, không đồng bộ và sẽ được lưu vào bộ đệm trước khi đi vào mô hình. Ngoài ra, nếu bạn gọi dataset.prefetch(tf.data.AUTOTUNE) trên bộ dữ liệu của bạn, tiền xử lý sẽ xảy ra một cách hiệu quả song song với đào tạo:

dataset = dataset.map(lambda x, y: (preprocessing_layer(x), y))
dataset = dataset.prefetch(tf.data.AUTOTUNE)
model.fit(dataset, ...)

Đây là tùy chọn tốt nhất cho TextVectorization , và tất cả các dữ liệu có cấu trúc tiền xử lý lớp. Nó cũng có thể là một lựa chọn tốt nếu bạn đang đào tạo về CPU và bạn sử dụng các lớp tiền xử lý hình ảnh.

Khi chạy trên TPU, bạn nên luôn luôn đặt tiền xử lý lớp trong tf.data đường ống (với ngoại lệ của NormalizationRescaling , mà chạy tốt trên TPU và thường được sử dụng như lớp đầu tiên là một mô hình hình ảnh).

Lợi ích của việc xử lý trước bên trong mô hình tại thời điểm suy luận

Ngay cả khi bạn chọn tùy chọn 2, sau này bạn có thể muốn xuất một mô hình end-to-end chỉ có thể suy luận sẽ bao gồm các lớp tiền xử lý. Lợi ích quan trọng để làm điều này là nó làm cho mô hình của bạn xách tay và nó giúp làm giảm đào tạo / phục vụ nghiêng .

Khi tất cả quá trình xử lý trước dữ liệu là một phần của mô hình, những người khác có thể tải và sử dụng mô hình của bạn mà không cần phải biết về cách mỗi tính năng dự kiến ​​sẽ được mã hóa và chuẩn hóa. Mô hình suy luận của bạn sẽ có thể xử lý hình ảnh thô hoặc dữ liệu có cấu trúc thô và sẽ không yêu cầu người dùng mô hình biết các chi tiết, ví dụ như lược đồ mã hóa được sử dụng cho văn bản, lược đồ lập chỉ mục được sử dụng cho các đối tượng phân loại, giá trị pixel hình ảnh được chuẩn hóa để [-1, +1] hoặc [0, 1] , vv Điều này là đặc biệt mạnh mẽ nếu bạn đang xuất khẩu mô hình của bạn để thời gian chạy khác, chẳng hạn như TensorFlow.js: bạn sẽ không phải reimplement tiền xử lý của bạn đường dẫn trong JavaScript.

Nếu ban đầu bạn đặt lớp tiền xử lý của bạn trong tf.data đường ống, bạn có thể xuất một mô hình suy luận rằng gói các tiền xử lý. Chỉ cần khởi tạo một mô hình mới liên kết các lớp tiền xử lý và mô hình đào tạo của bạn:

inputs = keras.Input(shape=input_shape)
x = preprocessing_layer(inputs)
outputs = training_model(x)
inference_model = keras.Model(inputs, outputs)

Công thức nấu ăn nhanh

Tăng dữ liệu hình ảnh

Lưu ý rằng các lớp dữ liệu hình ảnh tăng thêm là chỉ hoạt động trong đào tạo (tương tự như Dropout lớp).

from tensorflow import keras
from tensorflow.keras import layers

# Create a data augmentation stage with horizontal flipping, rotations, zooms
data_augmentation = keras.Sequential(
    [
        layers.RandomFlip("horizontal"),
        layers.RandomRotation(0.1),
        layers.RandomZoom(0.1),
    ]
)

# Load some data
(x_train, y_train), _ = keras.datasets.cifar10.load_data()
input_shape = x_train.shape[1:]
classes = 10

# Create a tf.data pipeline of augmented images (and their labels)
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.batch(16).map(lambda x, y: (data_augmentation(x), y))


# Create a model and train it on the augmented image data
inputs = keras.Input(shape=input_shape)
x = layers.Rescaling(1.0 / 255)(inputs)  # Rescale inputs
outputs = keras.applications.ResNet50(  # Add the rest of the model
    weights=None, input_shape=input_shape, classes=classes
)(x)
model = keras.Model(inputs, outputs)
model.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy")
model.fit(train_dataset, steps_per_epoch=5)
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 6s 0us/step
170508288/170498071 [==============================] - 6s 0us/step
5/5 [==============================] - 11s 44ms/step - loss: 8.8927
<keras.callbacks.History at 0x7f1c0c3f16d0>

Bạn có thể thấy một thiết lập tương tự trong hành động trong ví dụ phân loại hình ảnh từ đầu .

Chuẩn hóa các tính năng số

# Load some data
(x_train, y_train), _ = keras.datasets.cifar10.load_data()
x_train = x_train.reshape((len(x_train), -1))
input_shape = x_train.shape[1:]
classes = 10

# Create a Normalization layer and set its internal state using the training data
normalizer = layers.Normalization()
normalizer.adapt(x_train)

# Create a model that include the normalization layer
inputs = keras.Input(shape=input_shape)
x = normalizer(inputs)
outputs = layers.Dense(classes, activation="softmax")(x)
model = keras.Model(inputs, outputs)

# Train the model
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy")
model.fit(x_train, y_train)
1563/1563 [==============================] - 3s 2ms/step - loss: 2.1304
<keras.callbacks.History at 0x7f1bc43f40d0>

Mã hóa các tính năng phân loại chuỗi thông qua mã hóa một nóng

# Define some toy data
data = tf.constant([["a"], ["b"], ["c"], ["b"], ["c"], ["a"]])

# Use StringLookup to build an index of the feature values and encode output.
lookup = layers.StringLookup(output_mode="one_hot")
lookup.adapt(data)

# Convert new test data (which includes unknown feature values)
test_data = tf.constant([["a"], ["b"], ["c"], ["d"], ["e"], [""]])
encoded_data = lookup(test_data)
print(encoded_data)
tf.Tensor(
[[0. 0. 0. 1.]
 [0. 0. 1. 0.]
 [0. 1. 0. 0.]
 [1. 0. 0. 0.]
 [1. 0. 0. 0.]
 [1. 0. 0. 0.]], shape=(6, 4), dtype=float32)

Lưu ý rằng, ở đây, chỉ số 0 được dành riêng cho out-of-từ vựng giá trị (giá trị mà không được nhìn thấy trong adapt() ).

Bạn có thể xem StringLookup trong hành động trong phân loại dữ liệu có cấu trúc từ đầu ví dụ.

Mã hóa các tính năng phân loại số nguyên thông qua mã hóa một nóng

# Define some toy data
data = tf.constant([[10], [20], [20], [10], [30], [0]])

# Use IntegerLookup to build an index of the feature values and encode output.
lookup = layers.IntegerLookup(output_mode="one_hot")
lookup.adapt(data)

# Convert new test data (which includes unknown feature values)
test_data = tf.constant([[10], [10], [20], [50], [60], [0]])
encoded_data = lookup(test_data)
print(encoded_data)
tf.Tensor(
[[0. 0. 1. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 1. 0. 0. 0.]
 [1. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1.]], shape=(6, 5), dtype=float32)

Lưu ý rằng chỉ số 0 được dành riêng cho các giá trị bị mất tích (mà bạn nên xác định là giá trị 0), và chỉ số 1 được dành riêng cho out-of-từ vựng giá trị (giá trị mà không được nhìn thấy trong adapt() ). Bạn có thể cấu hình này bằng cách sử dụng các mask_tokenoov_token đối số nhà xây dựng của IntegerLookup .

Bạn có thể xem IntegerLookup trong hành động trong ví dụ có cấu trúc phân loại dữ liệu từ đầu .

Áp dụng thủ thuật băm cho một đối tượng phân loại số nguyên

Nếu bạn có một đối tượng phân loại có thể nhận nhiều giá trị khác nhau (theo thứ tự từ 10e3 trở lên), trong đó mỗi giá trị chỉ xuất hiện một vài lần trong dữ liệu, thì việc lập chỉ mục và mã hóa một lần các giá trị của đối tượng sẽ trở nên không thực tế và không hiệu quả. Thay vào đó, bạn có thể áp dụng "thủ thuật băm": băm các giá trị cho một vectơ có kích thước cố định. Điều này giúp kích thước của không gian tính năng có thể quản lý được và loại bỏ nhu cầu lập chỉ mục rõ ràng.

# Sample data: 10,000 random integers with values between 0 and 100,000
data = np.random.randint(0, 100000, size=(10000, 1))

# Use the Hashing layer to hash the values to the range [0, 64]
hasher = layers.Hashing(num_bins=64, salt=1337)

# Use the CategoryEncoding layer to multi-hot encode the hashed values
encoder = layers.CategoryEncoding(num_tokens=64, output_mode="multi_hot")
encoded_data = encoder(hasher(data))
print(encoded_data.shape)
(10000, 64)

Mã hóa văn bản dưới dạng một chuỗi các chỉ số mã thông báo

Đây là cách bạn nên preprocess văn bản sẽ được chuyển đến một Embedding lớp.

# Define some text data to adapt the layer
adapt_data = tf.constant(
    [
        "The Brain is wider than the Sky",
        "For put them side by side",
        "The one the other will contain",
        "With ease and You beside",
    ]
)

# Create a TextVectorization layer
text_vectorizer = layers.TextVectorization(output_mode="int")
# Index the vocabulary via `adapt()`
text_vectorizer.adapt(adapt_data)

# Try out the layer
print(
    "Encoded text:\n", text_vectorizer(["The Brain is deeper than the sea"]).numpy(),
)

# Create a simple model
inputs = keras.Input(shape=(None,), dtype="int64")
x = layers.Embedding(input_dim=text_vectorizer.vocabulary_size(), output_dim=16)(inputs)
x = layers.GRU(8)(x)
outputs = layers.Dense(1)(x)
model = keras.Model(inputs, outputs)

# Create a labeled dataset (which includes unknown tokens)
train_dataset = tf.data.Dataset.from_tensor_slices(
    (["The Brain is deeper than the sea", "for if they are held Blue to Blue"], [1, 0])
)

# Preprocess the string inputs, turning them into int sequences
train_dataset = train_dataset.batch(2).map(lambda x, y: (text_vectorizer(x), y))
# Train the model on the int sequences
print("\nTraining model...")
model.compile(optimizer="rmsprop", loss="mse")
model.fit(train_dataset)

# For inference, you can export a model that accepts strings as input
inputs = keras.Input(shape=(1,), dtype="string")
x = text_vectorizer(inputs)
outputs = model(x)
end_to_end_model = keras.Model(inputs, outputs)

# Call the end-to-end model on test data (which includes unknown tokens)
print("\nCalling end-to-end model on test string...")
test_data = tf.constant(["The one the other will absorb"])
test_output = end_to_end_model(test_data)
print("Model output:", test_output)
Encoded text:
 [[ 2 19 14  1  9  2  1]]

Training model...
1/1 [==============================] - 3s 3s/step - loss: 0.4776

Calling end-to-end model on test string...
Model output: tf.Tensor([[0.04233753]], shape=(1, 1), dtype=float32)

Bạn có thể xem TextVectorization lớp trong hành động, kết hợp với một Embedding chế độ, trong ví dụ phân loại văn bản từ đầu .

Lưu ý rằng khi đào tạo một mô hình như vậy, cho hiệu suất tốt nhất, bạn nên luôn luôn sử dụng TextVectorization lớp như là một phần của đường ống đầu vào.

Mã hóa văn bản dưới dạng ma trận ngram dày đặc với mã hóa đa điểm

Đây là cách bạn nên preprocess văn bản được thông qua với một Dense lớp.

# Define some text data to adapt the layer
adapt_data = tf.constant(
    [
        "The Brain is wider than the Sky",
        "For put them side by side",
        "The one the other will contain",
        "With ease and You beside",
    ]
)
# Instantiate TextVectorization with "multi_hot" output_mode
# and ngrams=2 (index all bigrams)
text_vectorizer = layers.TextVectorization(output_mode="multi_hot", ngrams=2)
# Index the bigrams via `adapt()`
text_vectorizer.adapt(adapt_data)

# Try out the layer
print(
    "Encoded text:\n", text_vectorizer(["The Brain is deeper than the sea"]).numpy(),
)

# Create a simple model
inputs = keras.Input(shape=(text_vectorizer.vocabulary_size(),))
outputs = layers.Dense(1)(inputs)
model = keras.Model(inputs, outputs)

# Create a labeled dataset (which includes unknown tokens)
train_dataset = tf.data.Dataset.from_tensor_slices(
    (["The Brain is deeper than the sea", "for if they are held Blue to Blue"], [1, 0])
)

# Preprocess the string inputs, turning them into int sequences
train_dataset = train_dataset.batch(2).map(lambda x, y: (text_vectorizer(x), y))
# Train the model on the int sequences
print("\nTraining model...")
model.compile(optimizer="rmsprop", loss="mse")
model.fit(train_dataset)

# For inference, you can export a model that accepts strings as input
inputs = keras.Input(shape=(1,), dtype="string")
x = text_vectorizer(inputs)
outputs = model(x)
end_to_end_model = keras.Model(inputs, outputs)

# Call the end-to-end model on test data (which includes unknown tokens)
print("\nCalling end-to-end model on test string...")
test_data = tf.constant(["The one the other will absorb"])
test_output = end_to_end_model(test_data)
print("Model output:", test_output)
WARNING:tensorflow:5 out of the last 1567 calls to <function PreprocessingLayer.make_adapt_function.<locals>.adapt_step at 0x7f1b9c5c5290> 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/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
Encoded text:
 [[1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 0. 0. 0. 0. 0.

  0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0.]]

Training model...
1/1 [==============================] - 0s 231ms/step - loss: 1.0046

Calling end-to-end model on test string...
Model output: tf.Tensor([[-0.54753447]], shape=(1, 1), dtype=float32)

Mã hóa văn bản dưới dạng ma trận dày đặc của ngram với trọng số TF-IDF

Đây là một cách khác để tiền xử lý văn bản trước khi đi qua nó để một Dense lớp.

# Define some text data to adapt the layer
adapt_data = tf.constant(
    [
        "The Brain is wider than the Sky",
        "For put them side by side",
        "The one the other will contain",
        "With ease and You beside",
    ]
)
# Instantiate TextVectorization with "tf-idf" output_mode
# (multi-hot with TF-IDF weighting) and ngrams=2 (index all bigrams)
text_vectorizer = layers.TextVectorization(output_mode="tf-idf", ngrams=2)
# Index the bigrams and learn the TF-IDF weights via `adapt()`

with tf.device("CPU"):
    # A bug that prevents this from running on GPU for now.
    text_vectorizer.adapt(adapt_data)

# Try out the layer
print(
    "Encoded text:\n", text_vectorizer(["The Brain is deeper than the sea"]).numpy(),
)

# Create a simple model
inputs = keras.Input(shape=(text_vectorizer.vocabulary_size(),))
outputs = layers.Dense(1)(inputs)
model = keras.Model(inputs, outputs)

# Create a labeled dataset (which includes unknown tokens)
train_dataset = tf.data.Dataset.from_tensor_slices(
    (["The Brain is deeper than the sea", "for if they are held Blue to Blue"], [1, 0])
)

# Preprocess the string inputs, turning them into int sequences
train_dataset = train_dataset.batch(2).map(lambda x, y: (text_vectorizer(x), y))
# Train the model on the int sequences
print("\nTraining model...")
model.compile(optimizer="rmsprop", loss="mse")
model.fit(train_dataset)

# For inference, you can export a model that accepts strings as input
inputs = keras.Input(shape=(1,), dtype="string")
x = text_vectorizer(inputs)
outputs = model(x)
end_to_end_model = keras.Model(inputs, outputs)

# Call the end-to-end model on test data (which includes unknown tokens)
print("\nCalling end-to-end model on test string...")
test_data = tf.constant(["The one the other will absorb"])
test_output = end_to_end_model(test_data)
print("Model output:", test_output)
WARNING:tensorflow:6 out of the last 1568 calls to <function PreprocessingLayer.make_adapt_function.<locals>.adapt_step at 0x7f1b9f6eae60> 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/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
Encoded text:
 [[5.461647  1.6945957 0.        0.        0.        0.        0.

  0.        0.        0.        0.        0.        0.        0.
  0.        0.        1.0986123 1.0986123 1.0986123 0.        0.
  0.        0.        0.        0.        0.        0.        0.
  1.0986123 0.        0.        0.        0.        0.        0.
  0.        1.0986123 1.0986123 0.        0.        0.       ]]

Training model...
1/1 [==============================] - 0s 239ms/step - loss: 4.4868

Calling end-to-end model on test string...
Model output: tf.Tensor([[0.25670475]], shape=(1, 1), dtype=float32)

Gotchas quan trọng

Làm việc với các lớp tra cứu có từ vựng rất lớn

Bạn có thể thấy mình làm việc với một vốn từ vựng rất lớn trong một TextVectorization , một StringLookup lớp, hoặc một IntegerLookup lớp. Thông thường, một từ vựng lớn hơn 500MB sẽ được coi là "rất lớn".

Trong trường hợp như vậy, để thực hiện tốt nhất, bạn nên tránh sử dụng adapt() . Thay vào đó, hãy tính toán trước từ vựng của bạn (bạn có thể sử dụng Apache Beam hoặc TF Transform cho việc này) và lưu trữ nó trong một tệp. Sau đó tải từ vựng vào lớp lúc xây dựng bằng cách truyền filepath như vocabulary tranh cãi.

Sử dụng lớp tra cứu trên một pod TPU hoặc với ParameterServerStrategy .

Có một vấn đề nổi cộm gây hiệu suất phân huỷ khi sử dụng một TextVectorization , StringLookup , hoặc IntegerLookup lớp trong khi đào tạo trên một pod TPU hoặc trên nhiều máy tính qua ParameterServerStrategy . Điều này dự kiến ​​sẽ được khắc phục trong TensorFlow 2.7.