לשמור את התאריך! קלט / פלט של Google חוזר 18-20 במאי הירשם עכשיו
דף זה תורגם על ידי Cloud Translation API.
Switch to English

סיווג טקסט באמצעות BERT

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה ב- GitHub הורד מחברת ראה מודל רכזת TF

מדריך זה מכיל קוד מלא כדי לכוונן את BERT לביצוע ניתוח סנטימנט במערך של ביקורות סרטי IMDB בטקסט רגיל. בנוסף להכשרת מודל, תלמד כיצד לעבד טקסט מראש לפורמט מתאים.

במחברת זו תוכלו:

  • טען את מערך הנתונים IMDB
  • טען מודל BERT מ- TensorFlow Hub
  • בנה מודל משלך על ידי שילוב של BERT עם מסווג
  • תאמן את המודל שלך, וכוונן את BERT כחלק מכך
  • שמור את המודל שלך והשתמש בו לסיווג משפטים

אם אתה לא עובד עם מערך הנתונים IMDB, עיין בסיווג טקסט בסיסי לפרטים נוספים.

אודות BERT

BERT וארכיטקטורות מקודדות שנאי אחרות הצליחו מאוד במגוון משימות ב- NLP (עיבוד שפה טבעית). הם מחשבים ייצוגים וקטור-מרחביים של שפה טבעית המתאימים לשימוש במודלים של למידה עמוקה. משפחת המודלים של BERT משתמשת בארכיטקטורת המקודדים של רובוטריקים כדי לעבד כל אסימון של טקסט קלט בהקשר המלא של כל האסימונים לפני ואחרי, ומכאן השם: דו כיווני מקודד ייצוגים מרובוטריקים.

מודלים של BERT מאומנים בדרך כלל בקורפוס גדול של טקסט, ואז מכוונים למשימות ספציפיות.

להכין

# A dependency of the preprocessing for BERT inputs
pip install -q tensorflow-text

תוכלו להשתמש בכלי האופטימיזציה של AdamW מ- tensorflow / דגמים .

pip install -q tf-models-official
import os
import shutil

import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_text as text
from official.nlp import optimization  # to create AdamW optimizer

import matplotlib.pyplot as plt

tf.get_logger().setLevel('ERROR')

ניתוח הסנטימנט

מחברת זו מכשירה מודל לניתוח סנטימנט כדי לסווג ביקורות על סרטים כחיוביות או שליליות , על סמך טקסט הביקורת.

תשתמש במערכת הנתונים של סקירת סרטים גדולה המכילה את הטקסט של 50,000 ביקורות סרטים ממאגר הסרטים האינטרנטי .

הורד את מערך ה- IMDB

בואו נוריד ונחלץ את מערך הנתונים ואז נבדוק את מבנה הספריה.

url = 'https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz'

dataset = tf.keras.utils.get_file('aclImdb_v1.tar.gz', url,
                                  untar=True, cache_dir='.',
                                  cache_subdir='')

dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')

train_dir = os.path.join(dataset_dir, 'train')

# remove unused folders to make it easier to load the data
remove_dir = os.path.join(train_dir, 'unsup')
shutil.rmtree(remove_dir)
Downloading data from https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
84131840/84125825 [==============================] - 7s 0us/step

לאחר מכן, תשתמש text_dataset_from_directory השירות text_dataset_from_directory כדי ליצורtf.data.Dataset שכותרתו.

מערך ה- IMDB כבר חולק לרכבת ולבדיקה, אך חסר ערכת אימות. בואו ליצור ערכת אימות באמצעות פיצול 80:20 של נתוני האימון באמצעות הארגומנט validation_split להלן.

AUTOTUNE = tf.data.AUTOTUNE
batch_size = 32
seed = 42

raw_train_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train',
    batch_size=batch_size,
    validation_split=0.2,
    subset='training',
    seed=seed)

class_names = raw_train_ds.class_names
train_ds = raw_train_ds.cache().prefetch(buffer_size=AUTOTUNE)

val_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/train',
    batch_size=batch_size,
    validation_split=0.2,
    subset='validation',
    seed=seed)

val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

test_ds = tf.keras.preprocessing.text_dataset_from_directory(
    'aclImdb/test',
    batch_size=batch_size)

test_ds = test_ds.cache().prefetch(buffer_size=AUTOTUNE)
Found 25000 files belonging to 2 classes.
Using 20000 files for training.
Found 25000 files belonging to 2 classes.
Using 5000 files for validation.
Found 25000 files belonging to 2 classes.

בואו נסתכל על כמה ביקורות.

for text_batch, label_batch in train_ds.take(1):
  for i in range(3):
    print(f'Review: {text_batch.numpy()[i]}')
    label = label_batch.numpy()[i]
    print(f'Label : {label} ({class_names[label]})')
Review: b'"Pandemonium" is a horror movie spoof that comes off more stupid than funny. Believe me when I tell you, I love comedies. Especially comedy spoofs. "Airplane", "The Naked Gun" trilogy, "Blazing Saddles", "High Anxiety", and "Spaceballs" are some of my favorite comedies that spoof a particular genre. "Pandemonium" is not up there with those films. Most of the scenes in this movie had me sitting there in stunned silence because the movie wasn\'t all that funny. There are a few laughs in the film, but when you watch a comedy, you expect to laugh a lot more than a few times and that\'s all this film has going for it. Geez, "Scream" had more laughs than this film and that was more of a horror film. How bizarre is that?<br /><br />*1/2 (out of four)'
Label : 0 (neg)
Review: b"David Mamet is a very interesting and a very un-equal director. His first movie 'House of Games' was the one I liked best, and it set a series of films with characters whose perspective of life changes as they get into complicated situations, and so does the perspective of the viewer.<br /><br />So is 'Homicide' which from the title tries to set the mind of the viewer to the usual crime drama. The principal characters are two cops, one Jewish and one Irish who deal with a racially charged area. The murder of an old Jewish shop owner who proves to be an ancient veteran of the Israeli Independence war triggers the Jewish identity in the mind and heart of the Jewish detective.<br /><br />This is were the flaws of the film are the more obvious. The process of awakening is theatrical and hard to believe, the group of Jewish militants is operatic, and the way the detective eventually walks to the final violent confrontation is pathetic. The end of the film itself is Mamet-like smart, but disappoints from a human emotional perspective.<br /><br />Joe Mantegna and William Macy give strong performances, but the flaws of the story are too evident to be easily compensated."
Label : 0 (neg)
Review: b'Great documentary about the lives of NY firefighters during the worst terrorist attack of all time.. That reason alone is why this should be a must see collectors item.. What shocked me was not only the attacks, but the"High Fat Diet" and physical appearance of some of these firefighters. I think a lot of Doctors would agree with me that,in the physical shape they were in, some of these firefighters would NOT of made it to the 79th floor carrying over 60 lbs of gear. Having said that i now have a greater respect for firefighters and i realize becoming a firefighter is a life altering job. The French have a history of making great documentary\'s and that is what this is, a Great Documentary.....'
Label : 1 (pos)

טוען דגמים מ- TensorFlow Hub

כאן תוכל לבחור איזה דגם BERT תטען מ- TensorFlow Hub וכוונון עדין. ישנם מספר דגמי BERT זמינים.

  • BERT-Base , ללא סגר ושבעה דגמים נוספים עם משקולות מאומנות ששוחררו על ידי מחברי ה- BERT המקוריים.
  • ל- BERTs קטנים אותה ארכיטקטורה כללית אך פחות ו / או חסימות שנאי קטנות יותר, המאפשרות לחקור פשרות בין מהירות, גודל ואיכות.
  • ALBERT : ארבעה גדלים שונים של "A Lite BERT" המפחית את גודל הדגם (אך לא את זמן החישוב) על ידי שיתוף פרמטרים בין שכבות.
  • מומחים ל- BERT : שמונה דגמים שכולם בעלי ארכיטקטורת בסיס ה- BERT אך מציעים בחירה בין תחומים שונים לפני הכשרה, כדי להתאים יותר מקרוב למשימת היעד.
  • לאלקטרה ארכיטקטורה זהה לזו של BERT (בשלושה גדלים שונים), אך עוברת הכשרה מוקדמת כמפלה במערך הדומה לרשת גנטית-אדברסרית (GAN).
  • ל- BERT עם קשב מדבר-ראשים ו- GELU מגודרת [ בסיס , גדול ] שני שיפורים בליבת ארכיטקטורת הרובוטריקים.

בתיעוד המודל ב- TensorFlow Hub יש פרטים נוספים והפניות לספרות המחקר. עקוב אחר הקישורים שלמעלה, או לחץ על כתובת האתר tfhub.dev המודפס לאחר ביצוע התא הבא.

ההצעה היא להתחיל עם BERT קטן (עם פחות פרמטרים) מכיוון שהם מהירים יותר לכוונון. אם אתה אוהב דגם קטן אך עם דיוק גבוה יותר, ALBERT עשויה להיות האפשרות הבאה שלך. אם אתה רוצה דיוק טוב עוד יותר, בחר באחד מגדלי ה- BERT הקלאסיים או בחידודים האחרונים שלהם כמו אלקטרה, ראשים מדברים או מומחה ל- BERT.

מלבד הדגמים הקיימים להלן, ישנן גרסאות מרובות של הדגמים גדולים יותר ויכולים להניב דיוק טוב עוד יותר, אך הם גדולים מכדי להיות מכוונים על GPU יחיד. תוכל לעשות זאת במשימות הפתרון של GLUE באמצעות BERT ב- cola TPU .

תראה בקוד שלמטה כי החלפת כתובת ה- URL tfhub.dev מספיקה כדי לנסות את כל אחד מהדגמים הללו, מכיוון שכל ההבדלים ביניהם נעטפים ב- SavedModels מ- TF Hub.

בחר דגם BERT לכוונון עדין

BERT model selected           : https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1
Preprocess model auto-selected: https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3

מודל העיבוד המקדים

יש להפוך את קלט הטקסט למזהים אסימוניים מספריים ולסדר אותם בכמה טנזורים לפני שהם מוזנים ל- BERT. TensorFlow Hub מספק מודל עיבוד מקדים תואם לכל אחד מדגמי ה- BERT שנדונו לעיל, אשר מיישם טרנספורמציה זו באמצעות אופי TF מספריית TF.text. אין צורך להריץ קוד פייתון טהור מחוץ למודל TensorFlow שלך כדי לעבד טקסט מראש.

המודל לעיבוד מקדים חייב להיות זה שמפנה אליו בתיעוד של מודל ה- BERT, אותו תוכלו לקרוא בכתובת האתר המודפסת לעיל. עבור דגמי BERT מהתפריט הנפתח שלמעלה, מודל העיבוד המקדים נבחר באופן אוטומטי.

bert_preprocess_model = hub.KerasLayer(tfhub_handle_preprocess)

בואו ננסה את מודל העיבוד המקדים בטקסט כלשהו ונראה את הפלט:

text_test = ['this is such an amazing movie!']
text_preprocessed = bert_preprocess_model(text_test)

print(f'Keys       : {list(text_preprocessed.keys())}')
print(f'Shape      : {text_preprocessed["input_word_ids"].shape}')
print(f'Word Ids   : {text_preprocessed["input_word_ids"][0, :12]}')
print(f'Input Mask : {text_preprocessed["input_mask"][0, :12]}')
print(f'Type Ids   : {text_preprocessed["input_type_ids"][0, :12]}')
Keys       : ['input_word_ids', 'input_mask', 'input_type_ids']
Shape      : (1, 128)
Word Ids   : [ 101 2023 2003 2107 2019 6429 3185  999  102    0    0    0]
Input Mask : [1 1 1 1 1 1 1 1 1 0 0 0]
Type Ids   : [0 0 0 0 0 0 0 0 0 0 0 0]

כפי שאתה יכול לראות, כעת יש לך את 3 היציאות input_words_id המוקדם שדגם BERT ישתמש בהן ( input_words_id , input_mask ו- input_type_ids ).

כמה נקודות חשובות אחרות:

  • הקלט נחתך ל 128 אסימונים. ניתן להתאים את מספר האסימונים ותוכלו לראות פרטים נוספים על משימות הפתרון של GLUE באמצעות BERT בקולבה של TPU .
  • ל- input_type_ids יש ערך אחד בלבד (0) מכיוון שמדובר בקלט משפט יחיד. עבור קלט רב משפט, יהיה בו מספר אחד לכל קלט.

מכיוון שמעבד טקסט זה הוא מודל TensorFlow, הוא יכול להיכלל ישירות במודל שלך.

באמצעות מודל BERT

לפני שנכניס את BERT למודל משלך, בוא נסתכל על התפוקות שלו. תטען אותו מ- TF Hub ותראה את הערכים שהוחזרו.

bert_model = hub.KerasLayer(tfhub_handle_encoder)
bert_results = bert_model(text_preprocessed)

print(f'Loaded BERT: {tfhub_handle_encoder}')
print(f'Pooled Outputs Shape:{bert_results["pooled_output"].shape}')
print(f'Pooled Outputs Values:{bert_results["pooled_output"][0, :12]}')
print(f'Sequence Outputs Shape:{bert_results["sequence_output"].shape}')
print(f'Sequence Outputs Values:{bert_results["sequence_output"][0, :12]}')
Loaded BERT: https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1
Pooled Outputs Shape:(1, 512)
Pooled Outputs Values:[ 0.76262873  0.9928097  -0.18611881  0.36673862  0.15233737  0.6550447
  0.9681153  -0.9486272   0.00216161 -0.9877732   0.06842697 -0.9763058 ]
Sequence Outputs Shape:(1, 128, 512)
Sequence Outputs Values:[[-0.28946346  0.34321272  0.33231515 ...  0.21300808  0.71020764
  -0.05771098]
 [-0.28742087  0.31980985 -0.23018607 ...  0.58455014 -0.21329728
   0.72692114]
 [-0.6615697   0.6887685  -0.87432986 ...  0.10877222 -0.2617324
   0.4785539 ]
 ...
 [-0.22561133 -0.2892562  -0.07064445 ...  0.47565985  0.83277136
   0.40025374]
 [-0.29824236 -0.27473187 -0.05450562 ...  0.48849723  1.0955356
   0.1816333 ]
 [-0.4437813   0.00930756  0.07223685 ...  0.17290069  1.1833248
   0.07897997]]

דגמי ה- BERT מחזירים מפה עם 3 מקשים חשובים: pooled_output , pooled_output sequence_output , encoder_outputs :

  • pooled_output מייצג כל רצף קלט בכללותו. הצורה היא [batch_size, H] . אתה יכול לחשוב על זה כהטבעה לכל ביקורת הסרט.
  • sequence_output מייצג כל אסימון קלט בהקשר. הצורה היא [batch_size, seq_length, H] . אתה יכול לחשוב על זה כעל הטבעה בהקשר לכל אסימון בביקורת הסרט.
  • encoder_outputs הם הפעלות ביניים של בלוקי שנאי L outputs["encoder_outputs"][i] הם טנסור של צורה [batch_size, seq_length, 1024] עם הפלטים של בלוק שנאי i-th, עבור 0 <= i < L . הערך האחרון של הרשימה שווה sequence_output .

לצורך כוונון עדין אתה הולך להשתמש במערך pooled_output .

הגדירו את המודל שלכם

תיצור דגם פשוט מאוד מכוון, עם דגם העיבוד המקדים, דגם ה- BERT שנבחר, אחד צפוף ושכבת נשירה.

def build_classifier_model():
  text_input = tf.keras.layers.Input(shape=(), dtype=tf.string, name='text')
  preprocessing_layer = hub.KerasLayer(tfhub_handle_preprocess, name='preprocessing')
  encoder_inputs = preprocessing_layer(text_input)
  encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True, name='BERT_encoder')
  outputs = encoder(encoder_inputs)
  net = outputs['pooled_output']
  net = tf.keras.layers.Dropout(0.1)(net)
  net = tf.keras.layers.Dense(1, activation=None, name='classifier')(net)
  return tf.keras.Model(text_input, net)

בואו לבדוק שהמודל פועל עם הפלט של המודל לעיבוד מקדים.

classifier_model = build_classifier_model()
bert_raw_result = classifier_model(tf.constant(text_test))
print(tf.sigmoid(bert_raw_result))
tf.Tensor([[0.6391119]], shape=(1, 1), dtype=float32)

התפוקה חסרת משמעות, כמובן מכיוון שהמודל טרם הוכשר.

בואו נסתכל על מבנה המודל.

tf.keras.utils.plot_model(classifier_model)

png

אימון מודלים

כעת יש לך את כל החלקים להכשרת מודל, כולל מודול העיבוד המקדים, מקודד ה- BERT, הנתונים והמסווג.

תפקוד אובדן

מכיוון שמדובר בבעיית סיווג בינארי והמודל מפיק הסתברות (שכבה של יחידה יחידה), תשתמש בפונקציות losses.BinaryCrossentropy .

loss = tf.keras.losses.BinaryCrossentropy(from_logits=True)
metrics = tf.metrics.BinaryAccuracy()

מיטוב

לצורך כוונון עדין, בואו נשתמש באותו אופטימיזציה שעליו הוכשר במקור BERT: "הרגעים המסתגלים" (אדם). אופטימיזציה זו ממזערת את אובדן החיזוי ועושה רגולציה על ידי ריקבון משקל (ללא שימוש ברגעים), המכונה גם AdamW .

עבור קצב הלמידה ( init_lr ), תשתמש באותו לוח זמנים כמו אימון מקדים של BERT: ריקבון ליניארי של קצב למידה ראשוני רעיוני, עם קידומת שלב חימום ליניארי במהלך 10% הראשונים של שלבי האימון ( num_warmup_steps ). בהתאם לנייר BERT, קצב הלמידה הראשוני קטן יותר לכוונון עדין (הטוב ביותר מ- 5e-5, 3e-5, 2e-5).

epochs = 5
steps_per_epoch = tf.data.experimental.cardinality(train_ds).numpy()
num_train_steps = steps_per_epoch * epochs
num_warmup_steps = int(0.1*num_train_steps)

init_lr = 3e-5
optimizer = optimization.create_optimizer(init_lr=init_lr,
                                          num_train_steps=num_train_steps,
                                          num_warmup_steps=num_warmup_steps,
                                          optimizer_type='adamw')

טוען את מודל ה- BERT והדרכה

באמצעות classifier_model שיצרת קודם לכן, אתה יכול לקמפל את המודל עם אובדן, מדד ומייעל.

classifier_model.compile(optimizer=optimizer,
                         loss=loss,
                         metrics=metrics)
print(f'Training model with {tfhub_handle_encoder}')
history = classifier_model.fit(x=train_ds,
                               validation_data=val_ds,
                               epochs=epochs)
Training model with https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1
Epoch 1/5
625/625 [==============================] - 88s 133ms/step - loss: 0.5722 - binary_accuracy: 0.6656 - val_loss: 0.3858 - val_binary_accuracy: 0.8352
Epoch 2/5
625/625 [==============================] - 81s 130ms/step - loss: 0.3570 - binary_accuracy: 0.8398 - val_loss: 0.3737 - val_binary_accuracy: 0.8472
Epoch 3/5
625/625 [==============================] - 81s 130ms/step - loss: 0.2663 - binary_accuracy: 0.8843 - val_loss: 0.3903 - val_binary_accuracy: 0.8502
Epoch 4/5
625/625 [==============================] - 81s 129ms/step - loss: 0.2030 - binary_accuracy: 0.9204 - val_loss: 0.4328 - val_binary_accuracy: 0.8512
Epoch 5/5
625/625 [==============================] - 82s 131ms/step - loss: 0.1640 - binary_accuracy: 0.9362 - val_loss: 0.4767 - val_binary_accuracy: 0.8540

הערך את המודל

בואו נראה איך הביצועים של המודל. יוחזרו שני ערכים. הפסד (מספר המייצג את השגיאה, ערכים נמוכים טובים יותר) ודיוק.

loss, accuracy = classifier_model.evaluate(test_ds)

print(f'Loss: {loss}')
print(f'Accuracy: {accuracy}')
782/782 [==============================] - 58s 74ms/step - loss: 0.4573 - binary_accuracy: 0.8534
Loss: 0.4572588801383972
Accuracy: 0.8533999919891357

זממו את הדיוק והאובדן לאורך זמן

מבוסס על אובייקט History שהוחזר על ידי model.fit() . אתה יכול לשרטט את איבוד האימון והאימות לצורך השוואה, כמו גם את דיוק האימון והאימות:

history_dict = history.history
print(history_dict.keys())

acc = history_dict['binary_accuracy']
val_acc = history_dict['val_binary_accuracy']
loss = history_dict['loss']
val_loss = history_dict['val_loss']

epochs = range(1, len(acc) + 1)
fig = plt.figure(figsize=(10, 6))
fig.tight_layout()

plt.subplot(2, 1, 1)
# "bo" is for "blue dot"
plt.plot(epochs, loss, 'r', label='Training loss')
# b is for "solid blue line"
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
# plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

plt.subplot(2, 1, 2)
plt.plot(epochs, acc, 'r', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
dict_keys(['loss', 'binary_accuracy', 'val_loss', 'val_binary_accuracy'])
<matplotlib.legend.Legend at 0x7f1d2043eeb8>

png

בעלילה זו, הקווים האדומים מייצגים את אובדן האימון והדיוק, והקווים הכחולים הם אובדן האימות והדיוק.

ייצא למסקנה

עכשיו אתה פשוט שומר את הדגם המותאם שלך לשימוש מאוחר יותר.

dataset_name = 'imdb'
saved_model_path = './{}_bert'.format(dataset_name.replace('/', '_'))

classifier_model.save(saved_model_path, include_optimizer=False)
WARNING:absl:Found untraced functions such as restored_function_body, restored_function_body, restored_function_body, restored_function_body, restored_function_body while saving (showing 5 of 310). These functions will not be directly callable after loading.
WARNING:absl:Found untraced functions such as restored_function_body, restored_function_body, restored_function_body, restored_function_body, restored_function_body while saving (showing 5 of 310). These functions will not be directly callable after loading.

בואו וטען מחדש את הדגם, כך שתוכלו לנסות אותו זה לצד זה עם הדגם שעדיין נמצא בזיכרון.

reloaded_model = tf.saved_model.load(saved_model_path)

כאן תוכלו לבדוק את המודל שלכם על כל משפט שתרצו, פשוט הוסיפו למשתנה הדוגמאות שלמטה.

def print_my_examples(inputs, results):
  result_for_printing = \
    [f'input: {inputs[i]:<30} : score: {results[i][0]:.6f}'
                         for i in range(len(inputs))]
  print(*result_for_printing, sep='\n')
  print()


examples = [
    'this is such an amazing movie!',  # this is the same sentence tried earlier
    'The movie was great!',
    'The movie was meh.',
    'The movie was okish.',
    'The movie was terrible...'
]

reloaded_results = tf.sigmoid(reloaded_model(tf.constant(examples)))
original_results = tf.sigmoid(classifier_model(tf.constant(examples)))

print('Results from the saved model:')
print_my_examples(examples, reloaded_results)
print('Results from the model in memory:')
print_my_examples(examples, original_results)
Results from the saved model:
input: this is such an amazing movie! : score: 0.999298
input: The movie was great!           : score: 0.997045
input: The movie was meh.             : score: 0.984519
input: The movie was okish.           : score: 0.091834
input: The movie was terrible...      : score: 0.001963

Results from the model in memory:
input: this is such an amazing movie! : score: 0.999298
input: The movie was great!           : score: 0.997045
input: The movie was meh.             : score: 0.984519
input: The movie was okish.           : score: 0.091834
input: The movie was terrible...      : score: 0.001963

אם אתה רוצה להשתמש במודל שלך ב- TF Serving , זכור שהוא יתקשר ל- SavedModel שלך באמצעות אחת החתימות שלו. בפייתון תוכלו לבדוק אותם באופן הבא:

serving_results = reloaded_model \
            .signatures['serving_default'](tf.constant(examples))

serving_results = tf.sigmoid(serving_results['classifier'])

print_my_examples(examples, serving_results)
input: this is such an amazing movie! : score: 0.999298
input: The movie was great!           : score: 0.997045
input: The movie was meh.             : score: 0.984519
input: The movie was okish.           : score: 0.091834
input: The movie was terrible...      : score: 0.001963

הצעדים הבאים

כשלב הבא, תוכלו לנסות לפתור משימות של GLUE באמצעות BERT במדריך TPU , הפועל על גבי TPU ומראה לכם כיצד לעבוד עם מספר כניסות.