العمل مع طبقات المعالجة المسبقة

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

Keras المعالجة المسبقة

تسمح واجهة برمجة تطبيقات طبقات المعالجة المسبقة Keras للمطورين ببناء خطوط أنابيب معالجة المدخلات الأصلية لـ Keras. يمكن استخدام خطوط أنابيب معالجة الإدخال هذه كرمز معالجة مسبق مستقل في مهام سير العمل بخلاف Keras ، جنبًا إلى جنب مباشرة مع نماذج Keras ، وتصديرها كجزء من Keras SavedModel.

باستخدام طبقات المعالجة المسبقة لـ Keras ، يمكنك بناء وتصدير نماذج شاملة حقًا: نماذج تقبل الصور الأولية أو البيانات المهيكلة الأولية كمدخلات ؛ النماذج التي تتعامل مع تطبيع الميزة أو ميزة فهرسة القيمة من تلقاء نفسها.

المعالجة المسبقة المتاحة

معالجة النص

  • tf.keras.layers.TextVectorization : تحول سلاسل الخام إلى تمثيل المشفرة التي يمكن قراءتها من قبل Embedding طبقة أو Dense طبقة.

الميزات العددية المعالجة المسبقة

الميزات الفئوية المعالجة المسبقة

  • tf.keras.layers.CategoryEncoding : يتحول صحيح ميزات القاطع في التمثيل كثيفة الساخنة واحد، متعدد الساخنة، أو العد.
  • tf.keras.layers.Hashing : ينفذ القاطع التجزئة الميزة، التي تعرف أيضا باسم "خدعة التجزئة".
  • tf.keras.layers.StringLookup : يتحول سلسلة القاطع قيم تمثيل المشفرة التي يمكن قراءتها من قبل Embedding طبقة أو Dense طبقة.
  • tf.keras.layers.IntegerLookup : يتحول صحيح القيم الفئوية إلى التمثيل المشفرة التي يمكن قراءتها من قبل Embedding طبقة أو Dense طبقة.

معالجة الصور

هذه الطبقات لتوحيد مدخلات نموذج الصورة.

  • tf.keras.layers.Resizing : تغيير حجم مجموعة من الصور إلى حجم الهدف.
  • tf.keras.layers.Rescaling : rescales وإزاحة قيم مجموعة من الصور (مثل الانتقال من المدخلات في [0, 255] مجموعة من المدخلات في [0, 1] مجموعة.
  • tf.keras.layers.CenterCrop : إرجاع المحاصيل وسط مجموعة من الصور.

زيادة بيانات الصورة

تطبق هذه الطبقات تحولات زيادة عشوائية على مجموعة من الصور. هم فقط نشطون أثناء التدريب.

على adapt() طريقة

تحتوي بعض طبقات المعالجة المسبقة على حالة داخلية يمكن حسابها بناءً على عينة من بيانات التدريب. قائمة طبقات المعالجة المسبقة ذات الحالة هي:

  • TextVectorization : حاصل على تعيين بين الرموز سلسلة ومؤشرات صحيح
  • StringLookup و IntegerLookup : عقد التعيين بين قيم الإدخال ومؤشرات صحيح.
  • Normalization : يحمل الانحراف المتوسط و المستوى من الميزات.
  • Discretization : يحمل معلومات عن حدود دلو القيمة.

بشكل حاسم، وهذه الطبقات هي غير قابلة للتدريب. لم يتم تحديد حالتهم أثناء التدريب ؛ فإنه يجب تعيين قبل التدريب، إما عن طريق تهيئة لهم من ثابت precomputed، أو "التكيف" لهم على البيانات.

تعيين حالة طبقة تجهيزها عن طريق تعريضها لبيانات التدريب، عن طريق adapt() الأسلوب:

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

على adapt() يأخذ طريقة إما مجموعة نمباي أو tf.data.Dataset الكائن. في حالة StringLookup و TextVectorization ، يمكنك أيضا تمرير قائمة سلاسل:

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)

بالإضافة إلى ذلك ، تعرض الطبقات القابلة للتكيف دائمًا خيارًا لتعيين الحالة مباشرةً عبر وسيطات المُنشئ أو تعيين الوزن. إذا عرفت القيم دولة المقصود في طبقة وقت البناء، أو تحسب خارج adapt() الدعوة، فإنها يمكن تعيين دون الاعتماد على الحساب الداخلي الطبقة. على سبيل المثال، إذا كانت ملفات المفردات الخارجية لل TextVectorization ، StringLookup ، أو IntegerLookup طبقات موجودة بالفعل، وتلك يمكن تحميلها مباشرة في جداول بحث عن طريق تمرير المسار إلى الملف المفردات في الحجج منشئ الطبقة.

وإليك مثال حيث أننا مثيل StringLookup طبقة مع المفردات 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)

المعالجة المسبقة للبيانات قبل النموذج أو داخل النموذج

هناك طريقتان يمكنك من خلالهما استخدام طبقات المعالجة المسبقة:

الخيار 1: جعلها جزءا من النموذج، مثل هذا:

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

باستخدام هذا الخيار ، ستحدث المعالجة المسبقة على الجهاز ، بشكل متزامن مع بقية تنفيذ النموذج ، مما يعني أنه سيستفيد من تسريع وحدة معالجة الرسومات. إذا كنت التدريب كنت على GPU، وهذا هو الخيار الأفضل ل Normalization طبقة، ولكل صورة تجهيزها وطبقات زيادة البيانات.

الخيار 2: تطبيقه على الخاص tf.data.Dataset ، وذلك للحصول على بيانات يمكن أن ينتج دفعات من البيانات preprocessed، مثل هذا:

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

باستخدام هذا الخيار ، ستحدث المعالجة المسبقة الخاصة بك على وحدة المعالجة المركزية ، بشكل غير متزامن ، وسيتم تخزينها مؤقتًا قبل الانتقال إلى النموذج. وبالإضافة إلى ذلك، إذا كنت استدعاء dataset.prefetch(tf.data.AUTOTUNE) على مجموعة البيانات الخاصة بك، وتجهيزها يحدث بكفاءة بالتوازي مع التدريب:

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

هذا هو الخيار الأفضل ل TextVectorization ، وجميع البيانات المهيكلة تجهيزها طبقات. يمكن أن يكون أيضًا خيارًا جيدًا إذا كنت تتدرب على وحدة المعالجة المركزية وتستخدم طبقات المعالجة المسبقة للصور.

عند تشغيل TPU، يجب أن تضع دائما تجهيزها الطبقات في tf.data خط أنابيب (باستثناء Normalization و Rescaling ، والتي تعمل بشكل جيد على TPU وتستخدم عادة باسم الطبقة الأولى هي نموذج الصورة).

فوائد القيام بالمعالجة المسبقة داخل النموذج في وقت الاستدلال

حتى إذا اخترت الخيار 2 ، فقد ترغب لاحقًا في تصدير نموذج استدلال فقط من طرف إلى طرف يتضمن طبقات المعالجة المسبقة. وتتمثل الفائدة الرئيسية إلى القيام بذلك هو أنه يجعل النموذج الخاص بك المحمولة ويساعد في تقليل التدريب / خدمة انحراف .

عندما تكون جميع البيانات المسبقة المعالجة جزءًا من النموذج ، يمكن للأشخاص الآخرين تحميل النموذج الخاص بك واستخدامه دون الحاجة إلى أن يكونوا على دراية بكيفية توقع ترميز كل ميزة وتوحيدها. سيكون نموذج الاستدلال الخاص بك قادرًا على معالجة الصور الأولية أو البيانات المنظمة الأولية ، ولن يتطلب من مستخدمي النموذج أن يكونوا على دراية بتفاصيل على سبيل المثال مخطط الترميز المستخدم للنص ، ونظام الفهرسة المستخدم للميزات الفئوية ، سواء كانت قيم بكسل الصورة وتطبيع لل [-1, +1] أو [0, 1] ، وما إلى ذلك هي قوية وخاصة إذا كنت تقوم بتصدير نموذج لوقت آخر، مثل TensorFlow.js: أنك لن تضطر إلى reimplement تجهيزها الخاص بك خط الأنابيب في جافا سكريبت.

إذا وضعت في البداية طبقات تجهيزها بشكل صحيح في ملفك tf.data خط أنابيب، يمكنك تصدير نموذج الاستدلال أن الحزم تجهيزها. ما عليك سوى إنشاء مثيل لنموذج جديد يربط طبقات المعالجة المسبقة ونموذج التدريب الخاص بك:

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

وصفات سريعة

زيادة بيانات الصورة

لاحظ أن طبقات تكبير بيانات الصورة هي النشطة فقط أثناء التدريب (على غرار Dropout طبقة).

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>

يمكنك ان ترى الإعداد مماثل في العمل في المثال تصنيف صورة من الصفر .

تطبيع السمات العددية

# 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>

ميزات سلسلة ترميز قاطعة عبر ترميز واحد ساخن

# 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)

لاحظ أنه، هنا، يتم حجز الرقم القياسي 0 للخارج مفردات القيم (القيم التي لم ينظر إليها خلال adapt() ).

تستطيع أن ترى في StringLookup في العمل في تصنيف البيانات الهيكلية من الصفر سبيل المثال.

ترميز الميزات الفئوية لعدد صحيح عبر ترميز واحد ساخن

# 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)

علما بأن الرقم القياسي 0 محجوز للقيم مفقودة (والذي يجب أن يحدد كقيمة 0)، ومؤشر 1 مخصص للخارج مفردات القيم (القيم التي لم ينظر إليها خلال adapt() ). يمكنك تكوين هذه باستخدام mask_token و oov_token الحجج منشئ IntegerLookup .

تستطيع أن ترى في IntegerLookup في العمل في المثال هيكلة تصنيف البيانات من نقطة الصفر .

تطبيق خدعة التجزئة على ميزة فئوية لعدد صحيح

إذا كانت لديك ميزة فئوية يمكن أن تأخذ العديد من القيم المختلفة (بترتيب 10e3 أو أعلى) ، حيث تظهر كل قيمة عدة مرات فقط في البيانات ، يصبح من غير العملي وغير الفعال فهرسة قيم الميزة وتشفيرها. بدلاً من ذلك ، قد يكون تطبيق "خدعة التجزئة" فكرة جيدة: تجزئة القيم إلى متجه ذي حجم ثابت. هذا يحافظ على حجم مساحة الميزة قابلة للإدارة ، ويزيل الحاجة إلى فهرسة صريحة.

# 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)

ترميز النص كسلسلة من مؤشرات الرمز المميز

هذه هي الطريقة التي يجب أن المعالجة المسبقة النص لتمريرها إلى Embedding طبقة.

# 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)

تستطيع أن ترى في TextVectorization طبقة في العمل، جنبا إلى جنب مع Embedding واسطة، في المثال تصنيف النص من نقطة الصفر .

لاحظ أنه عند تدريب نموذج مثل هذا، للحصول على أفضل أداء، يجب عليك دائما استخدام TextVectorization طبقة كجزء من خط أنابيب الإدخال.

ترميز النص كمصفوفة كثيفة من ngrams مع تشفير متعدد التشغيل

هذه هي الطريقة التي يجب أن المعالجة المسبقة النص لتمريرها إلى Dense طبقة.

# 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)

ترميز النص كمصفوفة كثيفة من ngrams مع ترجيح TF-IDF

هذا هو وسيلة بديلة لتجهيزها النص قبل تمريرها إلى Dense طبقة.

# 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)

مسكوت مهمة

العمل مع طبقات البحث ذات المفردات الكبيرة جدًا

قد تجد نفسك تعمل مع مفردات كبيرة جدا في TextVectorization ، و StringLookup طبقة، أو IntegerLookup طبقة. عادة ، تعتبر المفردات الأكبر من 500 ميغا بايت "كبيرة جدًا".

في مثل هذه الحالة، للحصول على أفضل أداء، يجب تجنب استخدام adapt() . بدلاً من ذلك ، احسب مفرداتك مسبقًا (يمكنك استخدام Apache Beam أو TF Transform لهذا الغرض) وقم بتخزينها في ملف. ثم تحميل المفردات في طبقة في وقت الإنشاء عن طريق تمرير أسم دليل مثل vocabulary حجة.

باستخدام طبقات بحث في جراب TPU أو مع ParameterServerStrategy .

هناك مشكلة العالقة التي تسبب الأداء لتتحلل عند استخدام TextVectorization ، StringLookup ، أو IntegerLookup طبقة في حين أن التدريب على جراب TPU أو على أجهزة متعددة عبر ParameterServerStrategy . تم تحديد هذا ليتم إصلاحه في TensorFlow 2.7.