แก้ไขงาน GLUE โดยใช้ BERT บน TPU

BERT สามารถใช้แก้ปัญหาต่างๆ ในการประมวลผลภาษาธรรมชาติได้ คุณจะได้เรียนรู้วิธีการ BERT ปรับแต่งสำหรับงานจำนวนมากจาก มาตรฐานกาว :

  1. โคล่า (คอร์ปัสของภาษาศาสตร์ยอมรับ): เป็นประโยคที่ถูกต้องตามหลักไวยากรณ์?

  2. SST-2 (Stanford ความเชื่อมั่น Treebank): งานคือการคาดการณ์ความเชื่อมั่นของประโยคที่กำหนด

  3. MRPC (Microsoft Research แปลความหมาย Corpus): ตรวจสอบว่าคู่ของประโยคที่มีความหมายเทียบเท่า

  4. QQP (Quora คำถาม Pairs2): ตรวจสอบว่าคู่ของคำถามจะเทียบเท่าความหมาย

  5. MNLI (Multi-แนวธรรมชาติภาษาอนุมาน): ให้เป็นประโยคที่สถานที่ตั้งและประโยคสมมติฐานของงานคือการคาดการณ์ว่าจะเป็นสถานที่สร้างความสมมติฐาน (entailment) ขัดแย้งกับสมมติฐาน (ขัดแย้ง) หรือไม่ (กลาง)

  6. QNLI (คำถาม-ตอบภาษาธรรมชาติอนุมาน): งานคือการตรวจสอบว่าประโยคบริบทมีคำตอบสำหรับคำถามที่

  7. RTE (ตระหนักถึงข้อความ entailment): ตรวจสอบว่าประโยค entails สมมติฐานที่กำหนดหรือไม่

  8. WNLI (Winograd ภาษาธรรมชาติอนุมาน): งานคือการคาดการณ์ถ้าประโยคที่มีคำสรรพนามแทนจะถูกยกให้โดยประโยคเดิม

บทแนะนำนี้ประกอบด้วยโค้ดแบบ end-to-end ที่สมบูรณ์เพื่อฝึกโมเดลเหล่านี้บน TPU คุณยังสามารถเรียกใช้โน้ตบุ๊กเครื่องนี้บน GPU โดยเปลี่ยนหนึ่งบรรทัด (อธิบายด้านล่าง)

ในสมุดบันทึกนี้ คุณจะ:

  • โหลดโมเดล BERT จาก TensorFlow Hub
  • เลือกงาน GLUE และดาวน์โหลดชุดข้อมูล
  • ประมวลผลข้อความล่วงหน้า
  • ปรับแต่ง BERT (ตัวอย่างมีให้สำหรับชุดข้อมูลแบบประโยคเดียวและหลายประโยค)
  • บันทึกรูปแบบการฝึกอบรมและใช้งาน

ติดตั้ง

คุณจะใช้แบบจำลองแยกต่างหากเพื่อประมวลผลข้อความล่วงหน้าก่อนที่จะใช้เพื่อปรับแต่ง BERT รุ่นนี้ขึ้นอยู่กับ tensorflow / ข้อความ ซึ่งคุณจะติดตั้งอยู่ด้านล่าง

pip install -q -U tensorflow-text

คุณจะใช้เพิ่มประสิทธิภาพ AdamW จาก tensorflow / รุ่น เพื่อ BERT ปรับแต่งซึ่งคุณจะติดตั้งได้เป็นอย่างดี

pip install -q -U tf-models-official
pip install -U tfds-nightly
import os
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_datasets as tfds
import tensorflow_text as text  # A dependency of the preprocessing model
import tensorflow_addons as tfa
from official.nlp import optimization
import numpy as np

tf
.get_logger().setLevel('ERROR')
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (2.3.0)/charset_normalizer (2.0.7) doesn't match a supported version!
  RequestsDependencyWarning)

ถัดไป กำหนดค่า TFHub ให้อ่านจุดตรวจสอบโดยตรงจากที่เก็บข้อมูล Cloud Storage ของ TFHub แนะนำให้ใช้เฉพาะเมื่อใช้งานรุ่น TFHub บน TPU

หากไม่มีการตั้งค่านี้ TFHub จะดาวน์โหลดไฟล์บีบอัดและแยกจุดตรวจในเครื่อง ความพยายามที่จะโหลดจากไฟล์ในเครื่องเหล่านี้จะล้มเหลวโดยมีข้อผิดพลาดดังต่อไปนี้:

InvalidArgumentError: Unimplemented: File system scheme '[local]' not implemented

เพราะนี่คือ TPU สามารถอ่านได้อย่างเดียวโดยตรงจากบุ้งกี๋ Cloud Storage

os.environ["TFHUB_MODEL_LOAD_FORMAT"]="UNCOMPRESSED"

เชื่อมต่อกับคนงาน TPU

รหัสต่อไปนี้เชื่อมต่อกับผู้ปฏิบัติงาน TPU และเปลี่ยนอุปกรณ์เริ่มต้นของ TensorFlow เป็นอุปกรณ์ CPU บนตัวปฏิบัติงาน TPU นอกจากนี้ยังกำหนดกลยุทธ์การกระจาย TPU ที่คุณจะใช้เพื่อแจกจ่ายการฝึกโมเดลไปยังแกน TPU 8 ตัวที่แยกจากกันซึ่งมีอยู่ในพนักงาน TPU รายนี้ ดู TensorFlow ของ TPU คู่มือ สำหรับข้อมูลเพิ่มเติม

import os

if os.environ['COLAB_TPU_ADDR']:
  cluster_resolver
= tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')
  tf
.config.experimental_connect_to_cluster(cluster_resolver)
  tf
.tpu.experimental.initialize_tpu_system(cluster_resolver)
  strategy
= tf.distribute.TPUStrategy(cluster_resolver)
 
print('Using TPU')
elif tf.config.list_physical_devices('GPU'):
  strategy
= tf.distribute.MirroredStrategy()
 
print('Using GPU')
else:
 
raise ValueError('Running on CPU is not recommended.')
Using TPU

กำลังโหลดโมเดลจาก TensorFlow Hub

ที่นี่คุณสามารถเลือกรุ่น BERT ที่คุณจะโหลดจาก TensorFlow Hub และปรับแต่งได้ มี BERT ให้เลือกหลายรุ่น

  • BERT-Base , uncased และ อีกเจ็ดรุ่น ที่มีน้ำหนักการฝึกอบรมที่ออกโดยผู้เขียน BERT เดิม
  • BERTs ขนาดเล็ก มีสถาปัตยกรรมทั่วไปเหมือนกัน แต่น้อยลงและ / หรือเล็กบล็อกหม้อแปลงไฟฟ้าซึ่งจะช่วยให้คุณสำรวจความสมดุลระหว่างความเร็ว, ขนาดและคุณภาพ
  • ALBERT : สี่ขนาดที่แตกต่างกัน "A Lite BERT" ที่ช่วยลดขนาดของรูปแบบ ( แต่ไม่ใช่เวลาในการคำนวณ) โดยการแบ่งปันพารามิเตอร์ระหว่างชั้น
  • ผู้เชี่ยวชาญ BERT : แปดรูปแบบที่ทุกคนมีสถาปัตยกรรม BERT ฐาน แต่เสนอทางเลือกระหว่างโดเมนก่อนการฝึกอบรมที่แตกต่างกันในการจัดขึ้นอย่างใกล้ชิดกับงานเป้าหมาย
  • Electra มีสถาปัตยกรรมเดียวกับเบิร์ต (ในสามขนาดที่แตกต่างกัน) แต่ได้รับก่อนการฝึกอบรมเป็น discriminator ในการตั้งค่าที่คล้ายกำเนิดขัดแย้งเครือข่าย (GAN)
  • BERT กับ Talking Heads-เรียนและรั้วรอบขอบชิด Gelu [ ฐาน , ขนาดใหญ่ ] มีสองการปรับปรุงหลักของสถาปัตยกรรมหม้อแปลง

ดูเอกสารแบบจำลองที่ลิงก์ด้านบนสำหรับรายละเอียดเพิ่มเติม

ในบทช่วยสอนนี้ คุณจะเริ่มด้วย BERT-base คุณสามารถใช้รุ่นที่ใหญ่กว่าและใหม่กว่าเพื่อความแม่นยำที่สูงขึ้น หรือใช้รุ่นที่เล็กกว่าเพื่อการฝึกฝนที่เร็วขึ้น หากต้องการเปลี่ยนโมเดล คุณต้องเปลี่ยนโค้ดเพียงบรรทัดเดียว (แสดงด้านล่าง) ความแตกต่างทั้งหมดถูกห่อหุ้มไว้ใน SavedModel ที่คุณจะดาวน์โหลดจาก TensorFlow Hub

เลือกรุ่น BERT เพื่อปรับแต่ง

bert_model_name = 'bert_en_uncased_L-12_H-768_A-12' 

map_name_to_handle
= {
   
'bert_en_uncased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3',
   
'bert_en_uncased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_L-24_H-1024_A-16/3',
   
'bert_en_wwm_uncased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_wwm_uncased_L-24_H-1024_A-16/3',
   
'bert_en_cased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_cased_L-12_H-768_A-12/3',
   
'bert_en_cased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_cased_L-24_H-1024_A-16/3',
   
'bert_en_wwm_cased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_wwm_cased_L-24_H-1024_A-16/3',
   
'bert_multi_cased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_multi_cased_L-12_H-768_A-12/3',
   
'small_bert/bert_en_uncased_L-2_H-128_A-2':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-128_A-2/1',
   
'small_bert/bert_en_uncased_L-2_H-256_A-4':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-256_A-4/1',
   
'small_bert/bert_en_uncased_L-2_H-512_A-8':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-512_A-8/1',
   
'small_bert/bert_en_uncased_L-2_H-768_A-12':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-768_A-12/1',
   
'small_bert/bert_en_uncased_L-4_H-128_A-2':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-128_A-2/1',
   
'small_bert/bert_en_uncased_L-4_H-256_A-4':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-256_A-4/1',
   
'small_bert/bert_en_uncased_L-4_H-512_A-8':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1',
   
'small_bert/bert_en_uncased_L-4_H-768_A-12':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-768_A-12/1',
   
'small_bert/bert_en_uncased_L-6_H-128_A-2':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-128_A-2/1',
   
'small_bert/bert_en_uncased_L-6_H-256_A-4':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-256_A-4/1',
   
'small_bert/bert_en_uncased_L-6_H-512_A-8':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-512_A-8/1',
   
'small_bert/bert_en_uncased_L-6_H-768_A-12':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-768_A-12/1',
   
'small_bert/bert_en_uncased_L-8_H-128_A-2':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-128_A-2/1',
   
'small_bert/bert_en_uncased_L-8_H-256_A-4':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-256_A-4/1',
   
'small_bert/bert_en_uncased_L-8_H-512_A-8':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-512_A-8/1',
   
'small_bert/bert_en_uncased_L-8_H-768_A-12':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-768_A-12/1',
   
'small_bert/bert_en_uncased_L-10_H-128_A-2':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-128_A-2/1',
   
'small_bert/bert_en_uncased_L-10_H-256_A-4':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-256_A-4/1',
   
'small_bert/bert_en_uncased_L-10_H-512_A-8':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-512_A-8/1',
   
'small_bert/bert_en_uncased_L-10_H-768_A-12':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-768_A-12/1',
   
'small_bert/bert_en_uncased_L-12_H-128_A-2':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-128_A-2/1',
   
'small_bert/bert_en_uncased_L-12_H-256_A-4':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-256_A-4/1',
   
'small_bert/bert_en_uncased_L-12_H-512_A-8':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-512_A-8/1',
   
'small_bert/bert_en_uncased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-768_A-12/1',
   
'albert_en_base':
       
'https://tfhub.dev/tensorflow/albert_en_base/2',
   
'albert_en_large':
       
'https://tfhub.dev/tensorflow/albert_en_large/2',
   
'albert_en_xlarge':
       
'https://tfhub.dev/tensorflow/albert_en_xlarge/2',
   
'albert_en_xxlarge':
       
'https://tfhub.dev/tensorflow/albert_en_xxlarge/2',
   
'electra_small':
       
'https://tfhub.dev/google/electra_small/2',
   
'electra_base':
       
'https://tfhub.dev/google/electra_base/2',
   
'experts_pubmed':
       
'https://tfhub.dev/google/experts/bert/pubmed/2',
   
'experts_wiki_books':
       
'https://tfhub.dev/google/experts/bert/wiki_books/2',
   
'talking-heads_base':
       
'https://tfhub.dev/tensorflow/talkheads_ggelu_bert_en_base/1',
   
'talking-heads_large':
       
'https://tfhub.dev/tensorflow/talkheads_ggelu_bert_en_large/1',
}

map_model_to_preprocess
= {
   
'bert_en_uncased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'bert_en_uncased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'bert_en_wwm_cased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_cased_preprocess/3',
   
'bert_en_cased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_cased_preprocess/3',
   
'bert_en_cased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_cased_preprocess/3',
   
'bert_en_wwm_uncased_L-24_H-1024_A-16':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-2_H-128_A-2':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-2_H-256_A-4':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-2_H-512_A-8':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-2_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-4_H-128_A-2':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-4_H-256_A-4':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-4_H-512_A-8':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-4_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-6_H-128_A-2':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-6_H-256_A-4':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-6_H-512_A-8':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-6_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-8_H-128_A-2':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-8_H-256_A-4':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-8_H-512_A-8':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-8_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-10_H-128_A-2':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-10_H-256_A-4':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-10_H-512_A-8':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-10_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-12_H-128_A-2':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-12_H-256_A-4':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-12_H-512_A-8':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'small_bert/bert_en_uncased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'bert_multi_cased_L-12_H-768_A-12':
       
'https://tfhub.dev/tensorflow/bert_multi_cased_preprocess/3',
   
'albert_en_base':
       
'https://tfhub.dev/tensorflow/albert_en_preprocess/3',
   
'albert_en_large':
       
'https://tfhub.dev/tensorflow/albert_en_preprocess/3',
   
'albert_en_xlarge':
       
'https://tfhub.dev/tensorflow/albert_en_preprocess/3',
   
'albert_en_xxlarge':
       
'https://tfhub.dev/tensorflow/albert_en_preprocess/3',
   
'electra_small':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'electra_base':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'experts_pubmed':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'experts_wiki_books':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'talking-heads_base':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
   
'talking-heads_large':
       
'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',
}

tfhub_handle_encoder
= map_name_to_handle[bert_model_name]
tfhub_handle_preprocess
= map_model_to_preprocess[bert_model_name]

print('BERT model selected           :', tfhub_handle_encoder)
print('Preprocessing model auto-selected:', tfhub_handle_preprocess)

BERT model selected           : https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3
Preprocessing model auto-selected: https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3

ประมวลผลข้อความล่วงหน้า

ใน ข้อความประเภทกับ BERT Colab รุ่น preprocessing จะใช้ฝังโดยตรงด้วยการเข้ารหัส BERT

บทช่วยสอนนี้สาธิตวิธีทำการประมวลผลล่วงหน้าซึ่งเป็นส่วนหนึ่งของไปป์ไลน์อินพุตสำหรับการฝึกอบรม โดยใช้ Dataset.map จากนั้นผสานเข้ากับโมเดลที่ส่งออกเพื่อการอนุมาน ด้วยวิธีนี้ ทั้งการฝึกและการอนุมานสามารถทำงานได้จากอินพุตข้อความดิบ แม้ว่า TPU เองจะต้องการอินพุตที่เป็นตัวเลข

ต้องการ TPU กันก็สามารถช่วยให้ประสิทธิภาพการทำงานที่ได้ทำ preprocessing ถ่ายทอดสดในท่อป้อนข้อมูล (คุณสามารถเรียนรู้เพิ่มเติมใน คู่มือการปฏิบัติงาน tf.data )

บทช่วยสอนนี้ยังสาธิตวิธีสร้างแบบจำลองหลายอินพุต และวิธีปรับความยาวลำดับของอินพุตเป็น BERT

มาสาธิตโมเดลก่อนการประมวลผลกัน

bert_preprocess = hub.load(tfhub_handle_preprocess)
tok
= bert_preprocess.tokenize(tf.constant(['Hello TensorFlow!']))
print(tok)
<tf.RaggedTensor [[[7592], [23435, 12314], [999]]]>

แต่ละรุ่น preprocessing นอกจากนี้ยังมีวิธีการ .bert_pack_inputs(tensors, seq_length) ซึ่งจะนำรายชื่อของสัญญาณ (เช่น tok ด้านบน) และความยาวลำดับอาร์กิวเมนต์ ซึ่งบรรจุอินพุตเพื่อสร้างพจนานุกรมของเทนเซอร์ในรูปแบบที่โมเดล BERT คาดไว้

text_preprocessed = bert_preprocess.bert_pack_inputs([tok, tok], tf.constant(20))

print('Shape Word Ids : ', text_preprocessed['input_word_ids'].shape)
print('Word Ids       : ', text_preprocessed['input_word_ids'][0, :16])
print('Shape Mask     : ', text_preprocessed['input_mask'].shape)
print('Input Mask     : ', text_preprocessed['input_mask'][0, :16])
print('Shape Type Ids : ', text_preprocessed['input_type_ids'].shape)
print('Type Ids       : ', text_preprocessed['input_type_ids'][0, :16])
Shape Word Ids :  (1, 20)
Word Ids       :  tf.Tensor(
[  101  7592 23435 12314   999   102  7592 23435 12314   999   102     0
     0     0     0     0], shape=(16,), dtype=int32)
Shape Mask     :  (1, 20)
Input Mask     :  tf.Tensor([1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0], shape=(16,), dtype=int32)
Shape Type Ids :  (1, 20)
Type Ids       :  tf.Tensor([0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0], shape=(16,), dtype=int32)

นี่คือรายละเอียดบางส่วนที่ควรคำนึงถึง:

  • input_mask หน้ากากช่วยให้รูปแบบที่แตกต่างหมดจดระหว่างเนื้อหาและช่องว่างที่ หน้ากากมีรูปร่างเช่นเดียวกับ input_word_ids และมี 1 ทุกที่ input_word_ids ไม่ได้รอง
  • input_type_ids มีรูปร่างเช่นเดียวกับ input_mask แต่ภายในภูมิภาคที่ไม่ใช่เบาะมี 0 หรือ 1 ระบุว่าประโยคโทเค็นเป็นส่วนหนึ่งของ

ถัดไป คุณจะต้องสร้างโมเดลการประมวลผลล่วงหน้าที่สรุปตรรกะทั้งหมดนี้ โมเดลของคุณจะรับสตริงเป็นอินพุต และส่งคืนอ็อบเจ็กต์ที่จัดรูปแบบอย่างเหมาะสมซึ่งสามารถส่งผ่านไปยัง BERT ได้

โมเดล BERT แต่ละรุ่นมีรูปแบบการประมวลผลล่วงหน้าเฉพาะ ตรวจสอบให้แน่ใจว่าได้ใช้แบบจำลองที่เหมาะสมที่อธิบายไว้ในเอกสารประกอบแบบจำลองของ BERT

def make_bert_preprocess_model(sentence_features, seq_length=128):
 
"""Returns Model mapping string features to BERT inputs.

  Args:
    sentence_features: a list with the names of string-valued features.
    seq_length: an integer that defines the sequence length of BERT inputs.

  Returns:
    A Keras Model that can be called on a list or dict of string Tensors
    (with the order or names, resp., given by sentence_features) and
    returns a dict of tensors for input to BERT.
  """


  input_segments
= [
      tf
.keras.layers.Input(shape=(), dtype=tf.string, name=ft)
     
for ft in sentence_features]

 
# Tokenize the text to word pieces.
  bert_preprocess
= hub.load(tfhub_handle_preprocess)
  tokenizer
= hub.KerasLayer(bert_preprocess.tokenize, name='tokenizer')
  segments
= [tokenizer(s) for s in input_segments]

 
# Optional: Trim segments in a smart way to fit seq_length.
 
# Simple cases (like this example) can skip this step and let
 
# the next step apply a default truncation to approximately equal lengths.
  truncated_segments
= segments

 
# Pack inputs. The details (start/end token ids, dict of output tensors)
 
# are model-dependent, so this gets loaded from the SavedModel.
  packer
= hub.KerasLayer(bert_preprocess.bert_pack_inputs,
                          arguments
=dict(seq_length=seq_length),
                          name
='packer')
  model_inputs
= packer(truncated_segments)
 
return tf.keras.Model(input_segments, model_inputs)

มาสาธิตโมเดลก่อนการประมวลผลกัน คุณจะสร้างการทดสอบด้วยการป้อนสองประโยค (input1 และ input2) เอาท์พุทคือสิ่งที่รุ่น BERT จะคาดหวังเป็น input: input_word_ids , input_masks และ input_type_ids

test_preprocess_model = make_bert_preprocess_model(['my_input1', 'my_input2'])
test_text
= [np.array(['some random test sentence']),
             np
.array(['another sentence'])]
text_preprocessed
= test_preprocess_model(test_text)

print('Keys           : ', list(text_preprocessed.keys()))
print('Shape Word Ids : ', text_preprocessed['input_word_ids'].shape)
print('Word Ids       : ', text_preprocessed['input_word_ids'][0, :16])
print('Shape Mask     : ', text_preprocessed['input_mask'].shape)
print('Input Mask     : ', text_preprocessed['input_mask'][0, :16])
print('Shape Type Ids : ', text_preprocessed['input_type_ids'].shape)
print('Type Ids       : ', text_preprocessed['input_type_ids'][0, :16])
Keys           :  ['input_word_ids', 'input_mask', 'input_type_ids']
Shape Word Ids :  (1, 128)
Word Ids       :  tf.Tensor(
[ 101 2070 6721 3231 6251  102 2178 6251  102    0    0    0    0    0
    0    0], shape=(16,), dtype=int32)
Shape Mask     :  (1, 128)
Input Mask     :  tf.Tensor([1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0], shape=(16,), dtype=int32)
Shape Type Ids :  (1, 128)
Type Ids       :  tf.Tensor([0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0], shape=(16,), dtype=int32)

มาดูโครงสร้างของโมเดลกัน โดยให้ความสนใจกับอินพุตทั้งสองที่คุณเพิ่งกำหนด

tf.keras.utils.plot_model(test_preprocess_model, show_shapes=True, show_dtype=True)
('You must install pydot (`pip install pydot`) and install graphviz (see instructions at https://graphviz.gitlab.io/download/) ', 'for plot_model/model_to_dot to work.')

เพื่อนำไปใช้ประมวลผลเบื้องต้นในปัจจัยการผลิตทั้งหมดจากชุดข้อมูลที่คุณจะใช้ map ฟังก์ชั่นจากชุดข้อมูล ผลที่ได้คือที่เก็บไว้ชั่วคราวแล้วสำหรับ ผลการดำเนินงาน

AUTOTUNE = tf.data.AUTOTUNE


def load_dataset_from_tfds(in_memory_ds, info, split, batch_size,
                           bert_preprocess_model
):
  is_training
= split.startswith('train')
  dataset
= tf.data.Dataset.from_tensor_slices(in_memory_ds[split])
  num_examples
= info.splits[split].num_examples

 
if is_training:
    dataset
= dataset.shuffle(num_examples)
    dataset
= dataset.repeat()
  dataset
= dataset.batch(batch_size)
  dataset
= dataset.map(lambda ex: (bert_preprocess_model(ex), ex['label']))
  dataset
= dataset.cache().prefetch(buffer_size=AUTOTUNE)
 
return dataset, num_examples

กำหนดรุ่นของคุณ

ตอนนี้คุณพร้อมที่จะกำหนดแบบจำลองของคุณสำหรับการจำแนกคู่ประโยคหรือประโยคโดยป้อนอินพุตที่ประมวลผลล่วงหน้าผ่านตัวเข้ารหัส BERT และวางตัวแยกประเภทเชิงเส้นไว้ด้านบน

def build_classifier_model(num_classes):

 
class Classifier(tf.keras.Model):
   
def __init__(self, num_classes):
     
super(Classifier, self).__init__(name="prediction")
     
self.encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True)
     
self.dropout = tf.keras.layers.Dropout(0.1)
     
self.dense = tf.keras.layers.Dense(num_classes)

   
def call(self, preprocessed_text):
      encoder_outputs
= self.encoder(preprocessed_text)
      pooled_output
= encoder_outputs["pooled_output"]
      x
= self.dropout(pooled_output)
      x
= self.dense(x)
     
return x

  model
= Classifier(num_classes)
 
return model

มาลองเรียกใช้โมเดลกับอินพุตที่ประมวลผลล่วงหน้า

test_classifier_model = build_classifier_model(2)
bert_raw_result
= test_classifier_model(text_preprocessed)
print(tf.sigmoid(bert_raw_result))
tf.Tensor([[0.29329836 0.44367802]], shape=(1, 2), dtype=float32)

เลือกงานจาก GLUE

คุณจะใช้ TensorFlow ชุดข้อมูลจาก กาว ชุดมาตรฐาน

Colab ให้คุณดาวน์โหลดชุดข้อมูลขนาดเล็กเหล่านี้ไปยังระบบไฟล์ในเครื่อง และโค้ดด้านล่างอ่านทั้งหมดลงในหน่วยความจำ เนื่องจากโฮสต์ของผู้ปฏิบัติงาน TPU ที่แยกจากกันไม่สามารถเข้าถึงระบบไฟล์ในเครื่องของรันไทม์ colab

สำหรับชุดข้อมูลขนาดใหญ่ที่คุณจะต้องสร้างของคุณเอง ข้อมูล Google Cloud Storage ถังและมีคนงาน TPU อ่านข้อมูลจากที่นั่น คุณสามารถเรียนรู้เพิ่มเติมใน คู่มือ TPU

ขอแนะนำให้เริ่มต้นด้วยชุดข้อมูล CoLa (สำหรับประโยคเดียว) หรือ MRPC (สำหรับหลายประโยค) เนื่องจากชุดข้อมูลเหล่านี้มีขนาดเล็กและไม่ใช้เวลาในการปรับแต่งนาน

tfds_name = 'glue/cola' 

tfds_info
= tfds.builder(tfds_name).info

sentence_features
= list(tfds_info.features.keys())
sentence_features
.remove('idx')
sentence_features
.remove('label')

available_splits
= list(tfds_info.splits.keys())
train_split
= 'train'
validation_split
= 'validation'
test_split
= 'test'
if tfds_name == 'glue/mnli':
  validation_split
= 'validation_matched'
  test_split
= 'test_matched'

num_classes
= tfds_info.features['label'].num_classes
num_examples
= tfds_info.splits.total_num_examples

print(f'Using {tfds_name} from TFDS')
print(f'This dataset has {num_examples} examples')
print(f'Number of classes: {num_classes}')
print(f'Features {sentence_features}')
print(f'Splits {available_splits}')

with tf.device('/job:localhost'):
 
# batch_size=-1 is a way to load the dataset into memory
  in_memory_ds
= tfds.load(tfds_name, batch_size=-1, shuffle_files=True)

# The code below is just to show some samples from the selected dataset
print(f'Here are some sample rows from {tfds_name} dataset')
sample_dataset
= tf.data.Dataset.from_tensor_slices(in_memory_ds[train_split])

labels_names
= tfds_info.features['label'].names
print(labels_names)
print()

sample_i
= 1
for sample_row in sample_dataset.take(5):
  samples
= [sample_row[feature] for feature in sentence_features]
 
print(f'sample row {sample_i}')
 
for sample in samples:
   
print(sample.numpy())
  sample_label
= sample_row['label']

 
print(f'label: {sample_label} ({labels_names[sample_label]})')
 
print()
  sample_i
+= 1

Using glue/cola from TFDS
This dataset has 10657 examples
Number of classes: 2
Features ['sentence']
Splits ['train', 'validation', 'test']
Here are some sample rows from glue/cola dataset
['unacceptable', 'acceptable']

sample row 1
b'It is this hat that it is certain that he was wearing.'
label: 1 (acceptable)

sample row 2
b'Her efficient looking up of the answer pleased the boss.'
label: 1 (acceptable)

sample row 3
b'Both the workers will wear carnations.'
label: 1 (acceptable)

sample row 4
b'John enjoyed drawing trees for his syntax homework.'
label: 1 (acceptable)

sample row 5
b'We consider Leslie rather foolish, and Lou a complete idiot.'
label: 1 (acceptable)

ชุดข้อมูลยังกำหนดประเภทของปัญหา (การจำแนกหรือการถดถอย) และฟังก์ชันการสูญเสียที่เหมาะสมสำหรับการฝึกอบรม

def get_configuration(glue_task):

  loss
= tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

 
if glue_task == 'glue/cola':
    metrics
= tfa.metrics.MatthewsCorrelationCoefficient(num_classes=2)
 
else:
    metrics
= tf.keras.metrics.SparseCategoricalAccuracy(
       
'accuracy', dtype=tf.float32)

 
return metrics, loss

ฝึกโมเดลของคุณ

สุดท้าย คุณสามารถฝึกโมเดล end-to-end บนชุดข้อมูลที่คุณเลือกได้

การกระจาย

เรียกคืนรหัสการตั้งค่าที่ด้านบน ซึ่งเชื่อมต่อรันไทม์ของ colab กับผู้ปฏิบัติงาน TPU ที่มีอุปกรณ์ TPU หลายเครื่อง ในการเผยแพร่การฝึกอบรม คุณจะต้องสร้างและรวบรวมโมเดล Keras หลักของคุณภายในขอบเขตของกลยุทธ์การกระจาย TPU (โปรดดูรายละเอียด ที่กระจายการฝึกอบรมกับ Keras .)

ในทางกลับกัน การประมวลผลล่วงหน้าทำงานบน CPU ของโฮสต์ผู้ปฏิบัติงาน ไม่ใช่ TPU ดังนั้นโมเดล Keras สำหรับการประมวลผลล่วงหน้ารวมถึงชุดข้อมูลการฝึกอบรมและการตรวจสอบความถูกต้องที่แมปด้วยจะถูกสร้างขึ้นนอกขอบเขตกลยุทธ์การแจกจ่าย เรียกร้องให้ Model.fit() จะดูแลการจัดจำหน่ายผ่านในชุดข้อมูลที่จำลองรูปแบบ

เครื่องมือเพิ่มประสิทธิภาพ

ปรับจูนต่อไปเพิ่มประสิทธิภาพการตั้งค่าจาก BERT ก่อนการฝึกอบรม (ในขณะที่ ข้อความประเภทกับ BERT ): จะใช้เพิ่มประสิทธิภาพ AdamW กับการสลายตัวเชิงเส้นของอัตราการเรียนรู้ความคิดเริ่มต้นนำหน้าด้วยขั้นตอนการอุ่นเครื่องเชิงเส้นในช่วงแรก 10% ของขั้นตอนการฝึกอบรม ( num_warmup_steps ) ตามรายงานของ BERT อัตราการเรียนรู้เริ่มต้นจะน้อยกว่าสำหรับการปรับแต่งอย่างละเอียด (ดีที่สุดของ 5e-5, 3e-5, 2e-5)

epochs = 3
batch_size
= 32
init_lr
= 2e-5

print(f'Fine tuning {tfhub_handle_encoder} model')
bert_preprocess_model
= make_bert_preprocess_model(sentence_features)

with strategy.scope():

 
# metric have to be created inside the strategy scope
  metrics
, loss = get_configuration(tfds_name)

  train_dataset
, train_data_size = load_dataset_from_tfds(
      in_memory_ds
, tfds_info, train_split, batch_size, bert_preprocess_model)
  steps_per_epoch
= train_data_size // batch_size
  num_train_steps
= steps_per_epoch * epochs
  num_warmup_steps
= num_train_steps // 10

  validation_dataset
, validation_data_size = load_dataset_from_tfds(
      in_memory_ds
, tfds_info, validation_split, batch_size,
      bert_preprocess_model
)
  validation_steps
= validation_data_size // batch_size

  classifier_model
= build_classifier_model(num_classes)

  optimizer
= optimization.create_optimizer(
      init_lr
=init_lr,
      num_train_steps
=num_train_steps,
      num_warmup_steps
=num_warmup_steps,
      optimizer_type
='adamw')

  classifier_model
.compile(optimizer=optimizer, loss=loss, metrics=[metrics])

  classifier_model
.fit(
      x
=train_dataset,
      validation_data
=validation_dataset,
      steps_per_epoch
=steps_per_epoch,
      epochs
=epochs,
      validation_steps
=validation_steps)
Fine tuning https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3 model
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/keras/engine/functional.py:585: UserWarning: Input dict contained keys ['idx', 'label'] which did not match any model input. They will be ignored by the model.
  [n for n in tensors.keys() if n not in ref_input_names])
Epoch 1/3
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/framework/indexed_slices.py:449: UserWarning: Converting sparse IndexedSlices(IndexedSlices(indices=Tensor("AdamWeightDecay/gradients/StatefulPartitionedCall:1", shape=(None,), dtype=int32), values=Tensor("clip_by_global_norm/clip_by_global_norm/_0:0", dtype=float32), dense_shape=Tensor("AdamWeightDecay/gradients/StatefulPartitionedCall:2", shape=(None,), dtype=int32))) to a dense Tensor of unknown shape. This may consume a large amount of memory.
  "shape. This may consume a large amount of memory." % value)
267/267 [==============================] - 86s 81ms/step - loss: 0.6092 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.4846 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 2/3
267/267 [==============================] - 14s 53ms/step - loss: 0.3774 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.5322 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 3/3
267/267 [==============================] - 14s 53ms/step - loss: 0.2623 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.6469 - val_MatthewsCorrelationCoefficient: 0.0000e+00

ส่งออกเพื่อการอนุมาน

คุณจะสร้างแบบจำลองขั้นสุดท้ายที่มีส่วนประมวลผลล่วงหน้าและ BERT ที่ปรับแต่งแล้วที่เราเพิ่งสร้างขึ้น

ณ เวลาอนุมาน การประมวลผลล่วงหน้าจะต้องเป็นส่วนหนึ่งของโมเดล (เนื่องจากไม่มีคิวอินพุตแยกต่างหากอีกต่อไปสำหรับข้อมูลการฝึกที่ทำ) การประมวลผลล่วงหน้าไม่ได้เป็นเพียงการคำนวณเท่านั้น มีทรัพยากรของตัวเอง (ตารางคำศัพท์) ที่ต้องแนบกับ Keras Model ที่บันทึกไว้สำหรับการส่งออก การชุมนุมครั้งสุดท้ายนี้คือสิ่งที่จะรอด

คุณกำลังจะบันทึกรูปแบบบน Colab และต่อมาคุณสามารถดาวน์โหลดเพื่อเก็บไว้สำหรับอนาคต (ดู -> สารบัญ -> ไฟล์)

main_save_path = './my_models'
bert_type
= tfhub_handle_encoder.split('/')[-2]
saved_model_name
= f'{tfds_name.replace("/", "_")}_{bert_type}'

saved_model_path
= os.path.join(main_save_path, saved_model_name)

preprocess_inputs
= bert_preprocess_model.inputs
bert_encoder_inputs
= bert_preprocess_model(preprocess_inputs)
bert_outputs
= classifier_model(bert_encoder_inputs)
model_for_export
= tf.keras.Model(preprocess_inputs, bert_outputs)

print('Saving', saved_model_path)

# Save everything on the Colab host (even the variables from TPU memory)
save_options
= tf.saved_model.SaveOptions(experimental_io_device='/job:localhost')
model_for_export
.save(saved_model_path, include_optimizer=False,
                      options
=save_options)
Saving ./my_models/glue_cola_bert_en_uncased_L-12_H-768_A-12
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 910). These functions will not be directly callable after loading.

ทดสอบโมเดล

ขั้นตอนสุดท้ายคือการทดสอบผลลัพธ์ของแบบจำลองที่ส่งออกของคุณ

เพื่อทำการเปรียบเทียบ ให้โหลดแบบจำลองใหม่และทดสอบโดยใช้อินพุตบางส่วนจากการแยกการทดสอบจากชุดข้อมูล

with tf.device('/job:localhost'):
  reloaded_model
= tf.saved_model.load(saved_model_path)

วิธียูทิลิตี้

def prepare(record):
  model_inputs
= [[record[ft]] for ft in sentence_features]
 
return model_inputs


def prepare_serving(record):
  model_inputs
= {ft: record[ft] for ft in sentence_features}
 
return model_inputs


def print_bert_results(test, bert_result, dataset_name):

  bert_result_class
= tf.argmax(bert_result, axis=1)[0]

 
if dataset_name == 'glue/cola':
   
print('sentence:', test[0].numpy())
   
if bert_result_class == 1:
     
print('This sentence is acceptable')
   
else:
     
print('This sentence is unacceptable')

 
elif dataset_name == 'glue/sst2':
   
print('sentence:', test[0])
   
if bert_result_class == 1:
     
print('This sentence has POSITIVE sentiment')
   
else:
     
print('This sentence has NEGATIVE sentiment')

 
elif dataset_name == 'glue/mrpc':
   
print('sentence1:', test[0])
   
print('sentence2:', test[1])
   
if bert_result_class == 1:
     
print('Are a paraphrase')
   
else:
     
print('Are NOT a paraphrase')

 
elif dataset_name == 'glue/qqp':
   
print('question1:', test[0])
   
print('question2:', test[1])
   
if bert_result_class == 1:
     
print('Questions are similar')
   
else:
     
print('Questions are NOT similar')

 
elif dataset_name == 'glue/mnli':
   
print('premise   :', test[0])
   
print('hypothesis:', test[1])
   
if bert_result_class == 1:
     
print('This premise is NEUTRAL to the hypothesis')
   
elif bert_result_class == 2:
     
print('This premise CONTRADICTS the hypothesis')
   
else:
     
print('This premise ENTAILS the hypothesis')

 
elif dataset_name == 'glue/qnli':
   
print('question:', test[0])
   
print('sentence:', test[1])
   
if bert_result_class == 1:
     
print('The question is NOT answerable by the sentence')
   
else:
     
print('The question is answerable by the sentence')

 
elif dataset_name == 'glue/rte':
   
print('sentence1:', test[0])
   
print('sentence2:', test[1])
   
if bert_result_class == 1:
     
print('Sentence1 DOES NOT entails sentence2')
   
else:
     
print('Sentence1 entails sentence2')

 
elif dataset_name == 'glue/wnli':
   
print('sentence1:', test[0])
   
print('sentence2:', test[1])
   
if bert_result_class == 1:
     
print('Sentence1 DOES NOT entails sentence2')
   
else:
     
print('Sentence1 entails sentence2')

 
print('BERT raw results:', bert_result[0])
 
print()

ทดสอบ

with tf.device('/job:localhost'):
  test_dataset
= tf.data.Dataset.from_tensor_slices(in_memory_ds[test_split])
 
for test_row in test_dataset.shuffle(1000).map(prepare).take(5):
   
if len(sentence_features) == 1:
      result
= reloaded_model(test_row[0])
   
else:
      result
= reloaded_model(list(test_row))

    print_bert_results
(test_row, result, tfds_name)
sentence: [b'An old woman languished in the forest.']
This sentence is acceptable
BERT raw results: tf.Tensor([-1.7032353  3.3714833], shape=(2,), dtype=float32)

sentence: [b"I went to the movies and didn't pick up the shirts."]
This sentence is acceptable
BERT raw results: tf.Tensor([-0.73970896  1.0806316 ], shape=(2,), dtype=float32)

sentence: [b"Every essay that she's written and which I've read is on that pile."]
This sentence is acceptable
BERT raw results: tf.Tensor([-0.7034159  0.6236454], shape=(2,), dtype=float32)

sentence: [b'Either Bill ate the peaches, or Harry.']
This sentence is unacceptable
BERT raw results: tf.Tensor([ 0.05972151 -0.08620442], shape=(2,), dtype=float32)

sentence: [b'I ran into the baker from whom I bought these bagels.']
This sentence is acceptable
BERT raw results: tf.Tensor([-1.6862067  3.285925 ], shape=(2,), dtype=float32)

หากคุณต้องการที่จะใช้รูปแบบของคุณบน TF การแสดง , จำไว้ว่ามันจะเรียก SavedModel ของคุณผ่านทางหนึ่งของลายเซ็นชื่อของมัน สังเกตว่าอินพุตมีความแตกต่างเล็กน้อย ใน Python คุณสามารถทดสอบได้ดังนี้:

with tf.device('/job:localhost'):
  serving_model
= reloaded_model.signatures['serving_default']
 
for test_row in test_dataset.shuffle(1000).map(prepare_serving).take(5):
    result
= serving_model(**test_row)
   
# The 'prediction' key is the classifier's defined model name.
    print_bert_results
(list(test_row.values()), result['prediction'], tfds_name)
sentence: b'Everyone attended more than two seminars.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.5594155  2.862155 ], shape=(2,), dtype=float32)

sentence: b'Most columnists claim that a senior White House official has been briefing them.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.6298996  3.3155093], shape=(2,), dtype=float32)

sentence: b"That my father, he's lived here all his life is well known to those cops."
This sentence is acceptable
BERT raw results: tf.Tensor([-1.2048947  1.8589772], shape=(2,), dtype=float32)

sentence: b'Ourselves like us.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.2723312  2.0494034], shape=(2,), dtype=float32)

sentence: b'John is clever.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.6516167  3.3147635], shape=(2,), dtype=float32)

คุณทำได้! โมเดลที่บันทึกไว้ของคุณสามารถใช้สำหรับการแสดงผลหรือการอนุมานอย่างง่ายในกระบวนการ โดยมี api ที่ง่ายกว่าซึ่งมีโค้ดน้อยกว่าและดูแลรักษาง่ายกว่า

ขั้นตอนถัดไป

เมื่อคุณได้ลองใช้รุ่น BERT พื้นฐานแล้ว คุณสามารถลองใช้รุ่นอื่นเพื่อให้ได้ความแม่นยำมากขึ้นหรืออาจใช้กับรุ่นขนาดเล็กกว่าก็ได้

คุณยังสามารถลองใช้ชุดข้อมูลอื่นๆ ได้อีกด้วย