หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

โหลดข้อความ

ดูใน TensorFlow.org เรียกใช้ใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดสมุดบันทึก

บทช่วยสอนนี้สาธิตสองวิธีในการโหลดและประมวลผลข้อความล่วงหน้า

  • ขั้นแรกคุณจะใช้ยูทิลิตี้และเลเยอร์ของ Keras หากคุณยังใหม่กับ TensorFlow คุณควรเริ่มจากสิ่งเหล่านี้

  • จากนั้นคุณจะใช้ยูทิลิตี้ระดับล่างเช่น tf.data.TextLineDataset เพื่อโหลดไฟล์ข้อความและ tf.text เพื่อประมวลผลข้อมูลล่วงหน้าเพื่อการควบคุมที่ละเอียดยิ่งขึ้น

import collections
import pathlib
import re
import string

import tensorflow as tf

from tensorflow.keras import layers
from tensorflow.keras import losses
from tensorflow.keras import preprocessing
from tensorflow.keras import utils
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization

import tensorflow_datasets as tfds
pip install tensorflow-text
Collecting tensorflow-text
[?25l  Downloading https://files.pythonhosted.org/packages/28/b2/2dbd90b93913afd07e6101b8b84327c401c394e60141c1e98590038060b3/tensorflow_text-2.3.0-cp36-cp36m-manylinux1_x86_64.whl (2.6MB)
[K     |████████████████████████████████| 2.6MB 2.9MB/s 
[?25hRequirement already satisfied: tensorflow<2.4,>=2.3.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-text) (2.3.0)
Requirement already satisfied: numpy<1.19.0,>=1.16.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.18.5)
Requirement already satisfied: keras-preprocessing<1.2,>=1.1.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.1.2)
Requirement already satisfied: scipy==1.4.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.4.1)
Requirement already satisfied: tensorboard<3,>=2.3.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (2.3.0)
Requirement already satisfied: h5py<2.11.0,>=2.10.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (2.10.0)
Requirement already satisfied: google-pasta>=0.1.8 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (0.2.0)
Requirement already satisfied: astunparse==1.6.3 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.6.3)
Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.15.0)
Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (0.35.1)
Requirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.12.1)
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.32.0)
Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (3.3.0)
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (1.1.0)
Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (0.10.0)
Requirement already satisfied: protobuf>=3.9.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (3.12.4)
Requirement already satisfied: gast==0.3.3 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (0.3.3)
Requirement already satisfied: tensorflow-estimator<2.4.0,>=2.3.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow<2.4,>=2.3.0->tensorflow-text) (2.3.0)
Requirement already satisfied: google-auth<2,>=1.6.3 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (1.17.2)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (1.0.1)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (3.3.2)
Requirement already satisfied: setuptools>=41.0.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (50.3.0)
Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (2.23.0)
Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (1.7.0)
Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.6/dist-packages (from tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (0.4.1)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (0.2.8)
Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (4.1.1)
Requirement already satisfied: rsa<5,>=3.1.4; python_version >= "3" in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (4.6)
Requirement already satisfied: importlib-metadata; python_version < "3.8" in /usr/local/lib/python3.6/dist-packages (from markdown>=2.6.8->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (2.0.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (2020.6.20)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (1.24.3)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (2.10)
Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (1.3.0)
Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.6/dist-packages (from pyasn1-modules>=0.2.1->google-auth<2,>=1.6.3->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (0.4.8)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.6/dist-packages (from importlib-metadata; python_version < "3.8"->markdown>=2.6.8->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (3.3.1)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.6/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<3,>=2.3.0->tensorflow<2.4,>=2.3.0->tensorflow-text) (3.1.0)
Installing collected packages: tensorflow-text
Successfully installed tensorflow-text-2.3.0

import tensorflow_text as tf_text

ตัวอย่างที่ 1: คาดคะเนแท็กสำหรับคำถาม Stack Overflow

ตัวอย่างแรกคุณจะดาวน์โหลดชุดข้อมูลคำถามการเขียนโปรแกรมจาก Stack Overflow คำถามแต่ละข้อ ("ฉันจะเรียงพจนานุกรมตามค่าได้อย่างไร") มีป้ายกำกับด้วยแท็กเดียว ( Python , CSharp , JavaScript หรือ Java ) งานของคุณคือการพัฒนาแบบจำลองที่คาดคะเนแท็กสำหรับคำถาม นี่คือตัวอย่างของการจำแนกหลายชั้นซึ่งเป็นปัญหาการเรียนรู้ของเครื่องที่สำคัญและใช้ได้อย่างกว้างขวาง

ดาวน์โหลดและสำรวจชุดข้อมูล

จากนั้นคุณจะดาวน์โหลดชุดข้อมูลและสำรวจโครงสร้างไดเรกทอรี

data_url = 'https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz'
dataset = utils.get_file(
    'stack_overflow_16k.tar.gz',
    data_url,
    untar=True,
    cache_dir='stack_overflow',
    cache_subdir='')
dataset_dir = pathlib.Path(dataset).parent
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/stack_overflow_16k.tar.gz
6053888/6053168 [==============================] - 0s 0us/step

list(dataset_dir.iterdir())
[PosixPath('/tmp/.keras/README.md'),
 PosixPath('/tmp/.keras/test'),
 PosixPath('/tmp/.keras/stack_overflow_16k.tar.gz.tar.gz'),
 PosixPath('/tmp/.keras/train')]
train_dir = dataset_dir/'train'
list(train_dir.iterdir())
[PosixPath('/tmp/.keras/train/csharp'),
 PosixPath('/tmp/.keras/train/python'),
 PosixPath('/tmp/.keras/train/javascript'),
 PosixPath('/tmp/.keras/train/java')]

ไดเร็กทอรี train/csharp , train/java , train/python และ train/javascript มีไฟล์ข้อความจำนวนมากซึ่งแต่ละคำถามเป็นคำถาม Stack Overflow พิมพ์ไฟล์และตรวจสอบข้อมูล

sample_file = train_dir/'python/1755.txt'
with open(sample_file) as f:
  print(f.read())
why does this blank program print true x=true.def stupid():.    x=false.stupid().print x


โหลดชุดข้อมูล

จากนั้นคุณจะโหลดข้อมูลออกจากดิสก์และเตรียมเป็นรูปแบบที่เหมาะสมสำหรับการฝึกอบรม ในการทำเช่นนั้นคุณจะใช้ยูทิลิตี้ text_dataset_from_directory เพื่อสร้าง tf.data.Dataset มีป้ายกำกับ หากคุณยังใหม่กับ tf.data นี่เป็นชุดเครื่องมือที่มีประสิทธิภาพสำหรับการสร้างท่อป้อนข้อมูล

preprocessing.text_dataset_from_directory โครงสร้างไดเร็กทอรีดังนี้

train/
...csharp/
......1.txt
......2.txt
...java/
......1.txt
......2.txt
...javascript/
......1.txt
......2.txt
...python/
......1.txt
......2.txt

เมื่อทำการทดสอบแมชชีนเลิร์นนิงแนวทางปฏิบัติที่ดีที่สุดในการแบ่งชุดข้อมูลของคุณออกเป็น 3 ส่วน ได้แก่ การ ฝึกอบรม การตรวจสอบความถูกต้อง และ การทดสอบ ชุดข้อมูล Stack Overflow ได้ถูกแบ่งออกเป็น train และ test แล้ว แต่ไม่มีชุดการตรวจสอบความถูกต้อง สร้างชุดการตรวจสอบความถูกต้องโดยใช้การแยกข้อมูลการฝึกอบรม 80:20 โดยใช้อาร์กิวเมนต์ validation_split ด้านล่าง

batch_size = 32
seed = 42

raw_train_ds = preprocessing.text_dataset_from_directory(
    train_dir,
    batch_size=batch_size,
    validation_split=0.2,
    subset='training',
    seed=seed)
Found 8000 files belonging to 4 classes.
Using 6400 files for training.

ดังที่คุณเห็นด้านบนมีตัวอย่าง 8,000 ตัวอย่างในโฟลเดอร์การฝึกอบรมซึ่งคุณจะใช้ 80% (หรือ 6,400) ในการฝึกอบรม ดังที่คุณจะเห็นในอีกสักครู่คุณสามารถฝึกโมเดลได้โดยส่ง tf.data.Dataset ไปยัง model.fit โดยตรง ขั้นแรกให้วนซ้ำชุดข้อมูลและพิมพ์ตัวอย่างบางส่วนเพื่อให้เข้าใจถึงข้อมูล

for text_batch, label_batch in raw_train_ds.take(1):
  for i in range(10):
    print("Question: ", text_batch.numpy()[i][:100], '...')
    print("Label:", label_batch.numpy()[i])
Question:  b'"convert binary to string not works i created a simple program...i create a string and compress it b' ...
Label: 0
Question:  b'"how to calculate sin using system.data.compute() in blank i\'m new here! i\'m a newbie in blank. one ' ...
Label: 0
Question:  b'"how can i execute a js function from the top of the stack? i\'d like to execute a function from the ' ...
Label: 2
Question:  b'"print a reportviewer automatically when you open a form is it possible, when i open a form with rep' ...
Label: 0
Question:  b'"can i use node.childnodes in the if clause? can i do..if (node.childnodes) {.  // do something.}...' ...
Label: 2
Question:  b'"compare strings in array after split in blank i have a string that i use split function on it in or' ...
Label: 1
Question:  b'"adding an array of div ids to a var so i have animate multiple divs across site i found some js on ' ...
Label: 2
Question:  b'"is it necessary for the namespace to be the name of the file in blank? for example, i name my file(' ...
Label: 0
Question:  b'"how can i convert contiguous letters to number separated by dash in blank? i\'d like to convert alph' ...
Label: 1
Question:  b'"ternary operator to minimize code how i can minimize the following code using ternary operator..if ' ...
Label: 0

ป้ายกำกับคือ 0 , 1 , 2 หรือ 3 หากต้องการดูว่าข้อใดสอดคล้องกับป้ายกำกับสตริงคุณสามารถตรวจสอบคุณสมบัติ class_names บนชุดข้อมูลได้

for i, label in enumerate(raw_train_ds.class_names):
  print("Label", i, "corresponds to", label)
Label 0 corresponds to csharp
Label 1 corresponds to java
Label 2 corresponds to javascript
Label 3 corresponds to python

จากนั้นคุณจะสร้างชุดข้อมูลการตรวจสอบความถูกต้องและการทดสอบ คุณจะใช้บทวิจารณ์ที่เหลือ 1,600 จากชุดการฝึกอบรมเพื่อการตรวจสอบความถูกต้อง

raw_val_ds = preprocessing.text_dataset_from_directory(
    train_dir,
    batch_size=batch_size,
    validation_split=0.2,
    subset='validation',
    seed=seed)
Found 8000 files belonging to 4 classes.
Using 1600 files for validation.

test_dir = dataset_dir/'test'
raw_test_ds = preprocessing.text_dataset_from_directory(
    test_dir, batch_size=batch_size)
Found 8000 files belonging to 4 classes.

เตรียมชุดข้อมูลสำหรับการฝึกอบรม

จากนั้นคุณจะกำหนดมาตรฐานสร้างโทเค็นและกำหนดเวกเตอร์ข้อมูลโดยใช้เลเยอร์การ preprocessing.TextVectorization

  • Standardization หมายถึงการประมวลผลข้อความล่วงหน้าโดยทั่วไปจะลบเครื่องหมายวรรคตอนหรือองค์ประกอบ HTML เพื่อทำให้ชุดข้อมูลง่ายขึ้น

  • Tokenization หมายถึงการแยกสตริงออกเป็นโทเค็น (ตัวอย่างเช่นการแยกประโยคออกเป็นคำแต่ละคำโดยการแบ่งช่องว่าง)

  • Vectorization หมายถึงการแปลงโทเค็นเป็นตัวเลขเพื่อให้สามารถป้อนเข้าในโครงข่ายประสาทเทียมได้

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

  • การกำหนดมาตรฐานเริ่มต้นจะแปลงข้อความเป็นตัวพิมพ์เล็กและลบเครื่องหมายวรรคตอน

  • โทเค็นไนเซอร์เริ่มต้นจะแบ่งช่องว่าง

  • โหมด vectorization เริ่มต้นคือ int สิ่งนี้จะแสดงดัชนีจำนวนเต็ม (หนึ่งรายการต่อโทเค็น) โหมดนี้สามารถใช้เพื่อสร้างโมเดลที่คำนึงถึงลำดับคำ คุณยังสามารถใช้โหมดอื่น ๆ เช่น binary เพื่อสร้างแบบจำลองแบบถุงคำ

คุณจะสร้างสองโหมดเพื่อเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งเหล่านี้ ขั้นแรกคุณจะใช้โมเดล binary เพื่อสร้างแบบจำลองถุงคำ จากนั้นคุณจะใช้โหมด int กับ ConvNet 1D

VOCAB_SIZE = 10000

binary_vectorize_layer = TextVectorization(
    max_tokens=VOCAB_SIZE,
    output_mode='binary')

สำหรับโหมด int นอกจากขนาดคำศัพท์สูงสุดแล้วคุณจะต้องตั้งค่าความยาวของลำดับสูงสุดที่ชัดเจนซึ่งจะทำให้เลเยอร์ซ้อนทับหรือตัดลำดับลำดับให้ตรงกับค่าลำดับ _ ความยาว

MAX_SEQUENCE_LENGTH = 250

int_vectorize_layer = TextVectorization(
    max_tokens=VOCAB_SIZE,
    output_mode='int',
    output_sequence_length=MAX_SEQUENCE_LENGTH)

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

# Make a text-only dataset (without labels), then call adapt
train_text = raw_train_ds.map(lambda text, labels: text)
binary_vectorize_layer.adapt(train_text)
int_vectorize_layer.adapt(train_text)

ดูผลลัพธ์ของการใช้เลเยอร์เหล่านี้เพื่อประมวลผลข้อมูลล่วงหน้า:

def binary_vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return binary_vectorize_layer(text), label
def int_vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return int_vectorize_layer(text), label
# Retrieve a batch (of 32 reviews and labels) from the dataset
text_batch, label_batch = next(iter(raw_train_ds))
first_question, first_label = text_batch[0], label_batch[0]
print("Question", first_question)
print("Label", first_label)
Question tf.Tensor(b'"function expected error in blank for dynamically created check box when it is clicked i want to grab the attribute value.it is working in ie 8,9,10 but not working in ie 11,chrome shows function expected error..&lt;input type=checkbox checked=\'checked\' id=\'symptomfailurecodeid\' tabindex=\'54\' style=\'cursor:pointer;\' onclick=chkclickevt(this);  failurecodeid=""1"" &gt;...function chkclickevt(obj) { .    alert(obj.attributes(""failurecodeid""));.}"\n', shape=(), dtype=string)
Label tf.Tensor(2, shape=(), dtype=int32)

print("'binary' vectorized question:", 
      binary_vectorize_text(first_question, first_label)[0])
'binary' vectorized question: tf.Tensor([[1. 1. 1. ... 0. 0. 0.]], shape=(1, 10000), dtype=float32)

print("'int' vectorized question:",
      int_vectorize_text(first_question, first_label)[0])
'int' vectorized question: tf.Tensor(
[[  38  450   65    7   16   12  892  265  186  451   44   11    6  685
     3   46    4 2062    2  485    1    6  158    7  479    1   26   20
   158    7  479    1  502   38  450    1 1767 1763    1    1    1    1
     1    1    1    1    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0    0    0
     0    0    0    0    0    0    0    0    0    0    0    0]], shape=(1, 250), dtype=int64)

ดังที่คุณเห็นด้านบนโหมด binary จะส่งคืนอาร์เรย์ที่แสดงว่าโทเค็นมีอยู่อย่างน้อยหนึ่งครั้งในอินพุตในขณะที่โหมด int จะแทนที่โทเค็นแต่ละรายการด้วยจำนวนเต็มดังนั้นจึงรักษาลำดับของโทเค็นไว้ คุณสามารถค้นหาโทเค็น (สตริง) ที่แต่ละจำนวนเต็มสอดคล้องกันโดยการเรียก. .get_vocabulary() บนเลเยอร์

print("1289 ---> ", int_vectorize_layer.get_vocabulary()[1289])
print("313 ---> ", int_vectorize_layer.get_vocabulary()[313])
print("Vocabulary size: {}".format(len(int_vectorize_layer.get_vocabulary())))
1289 --->  roman
313 --->  source
Vocabulary size: 10000

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

binary_train_ds = raw_train_ds.map(binary_vectorize_text)
binary_val_ds = raw_val_ds.map(binary_vectorize_text)
binary_test_ds = raw_test_ds.map(binary_vectorize_text)

int_train_ds = raw_train_ds.map(int_vectorize_text)
int_val_ds = raw_val_ds.map(int_vectorize_text)
int_test_ds = raw_test_ds.map(int_vectorize_text)

กำหนดค่าชุดข้อมูลเพื่อประสิทธิภาพ

นี่เป็นวิธีการสำคัญสองวิธีที่คุณควรใช้เมื่อโหลดข้อมูลเพื่อให้แน่ใจว่า I / O จะไม่ถูกบล็อก

.cache() เก็บข้อมูลไว้ในหน่วยความจำหลังจากโหลดออกจากดิสก์ วิธีนี้จะช่วยให้มั่นใจได้ว่าชุดข้อมูลจะไม่กลายเป็นคอขวดขณะฝึกโมเดลของคุณ หากชุดข้อมูลของคุณมีขนาดใหญ่เกินไปที่จะใส่ลงในหน่วยความจำคุณยังสามารถใช้วิธีนี้เพื่อสร้างแคชบนดิสก์ที่มีประสิทธิภาพซึ่งจะมีประสิทธิภาพในการอ่านมากกว่าไฟล์ขนาดเล็กจำนวนมาก

.prefetch() ซ้อนทับการประมวลผลข้อมูลล่วงหน้าและการเรียกใช้โมเดลขณะฝึกอบรม

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับทั้งสองวิธีตลอดจนวิธีแคชข้อมูลลงดิสก์ใน คู่มือประสิทธิภาพข้อมูล

AUTOTUNE = tf.data.experimental.AUTOTUNE

def configure_dataset(dataset):
  return dataset.cache().prefetch(buffer_size=AUTOTUNE)
binary_train_ds = configure_dataset(binary_train_ds)
binary_val_ds = configure_dataset(binary_val_ds)
binary_test_ds = configure_dataset(binary_test_ds)

int_train_ds = configure_dataset(int_train_ds)
int_val_ds = configure_dataset(int_val_ds)
int_test_ds = configure_dataset(int_test_ds)

ฝึกโมเดล

ถึงเวลาสร้างเครือข่ายประสาทของเรา สำหรับข้อมูลที่เป็นเวกเตอร์ binary ให้ฝึกโมเดลเชิงเส้นแบบถุงคำง่ายๆ:

binary_model = tf.keras.Sequential([layers.Dense(4)])
binary_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
history = binary_model.fit(
    binary_train_ds, validation_data=binary_val_ds, epochs=10)
Epoch 1/10
200/200 [==============================] - 2s 12ms/step - loss: 1.1198 - accuracy: 0.6419 - val_loss: 0.9171 - val_accuracy: 0.7669
Epoch 2/10
200/200 [==============================] - 0s 2ms/step - loss: 0.7788 - accuracy: 0.8195 - val_loss: 0.7518 - val_accuracy: 0.7881
Epoch 3/10
200/200 [==============================] - 0s 2ms/step - loss: 0.6274 - accuracy: 0.8634 - val_loss: 0.6655 - val_accuracy: 0.8037
Epoch 4/10
200/200 [==============================] - 1s 3ms/step - loss: 0.5340 - accuracy: 0.8855 - val_loss: 0.6117 - val_accuracy: 0.8169
Epoch 5/10
200/200 [==============================] - 1s 3ms/step - loss: 0.4681 - accuracy: 0.9050 - val_loss: 0.5747 - val_accuracy: 0.8294
Epoch 6/10
200/200 [==============================] - 0s 2ms/step - loss: 0.4178 - accuracy: 0.9189 - val_loss: 0.5479 - val_accuracy: 0.8300
Epoch 7/10
200/200 [==============================] - 1s 3ms/step - loss: 0.3776 - accuracy: 0.9289 - val_loss: 0.5277 - val_accuracy: 0.8338
Epoch 8/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3443 - accuracy: 0.9370 - val_loss: 0.5120 - val_accuracy: 0.8325
Epoch 9/10
200/200 [==============================] - 0s 2ms/step - loss: 0.3161 - accuracy: 0.9427 - val_loss: 0.4997 - val_accuracy: 0.8356
Epoch 10/10
200/200 [==============================] - 0s 2ms/step - loss: 0.2918 - accuracy: 0.9495 - val_loss: 0.4899 - val_accuracy: 0.8394

จากนั้นคุณจะใช้ int vectorized layer เพื่อสร้าง ConvNet 1D

def create_model(vocab_size, num_labels):
  model = tf.keras.Sequential([
      layers.Embedding(vocab_size, 64, mask_zero=True),
      layers.Conv1D(64, 5, padding="valid", activation="relu", strides=2),
      layers.GlobalMaxPooling1D(),
      layers.Dense(num_labels)
  ])
  return model
# vocab_size is VOCAB_SIZE + 1 since 0 is used additionally for padding.
int_model = create_model(vocab_size=VOCAB_SIZE + 1, num_labels=4)
int_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
history = int_model.fit(int_train_ds, validation_data=int_val_ds, epochs=5)
Epoch 1/5
200/200 [==============================] - 4s 18ms/step - loss: 1.1293 - accuracy: 0.5183 - val_loss: 0.7424 - val_accuracy: 0.7100
Epoch 2/5
200/200 [==============================] - 2s 9ms/step - loss: 0.6095 - accuracy: 0.7727 - val_loss: 0.5349 - val_accuracy: 0.8062
Epoch 3/5
200/200 [==============================] - 2s 9ms/step - loss: 0.3565 - accuracy: 0.8892 - val_loss: 0.4734 - val_accuracy: 0.8125
Epoch 4/5
200/200 [==============================] - 2s 9ms/step - loss: 0.1898 - accuracy: 0.9559 - val_loss: 0.4760 - val_accuracy: 0.8194
Epoch 5/5
200/200 [==============================] - 2s 9ms/step - loss: 0.0909 - accuracy: 0.9864 - val_loss: 0.5039 - val_accuracy: 0.8144

เปรียบเทียบทั้งสองรุ่น:

print("Linear model on binary vectorized data:")
print(binary_model.summary())
Linear model on binary vectorized data:
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 4)                 40004     
=================================================================
Total params: 40,004
Trainable params: 40,004
Non-trainable params: 0
_________________________________________________________________
None

print("ConvNet model on int vectorized data:")
print(int_model.summary())
ConvNet model on int vectorized data:
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 64)          640064    
_________________________________________________________________
conv1d (Conv1D)              (None, None, 64)          20544     
_________________________________________________________________
global_max_pooling1d (Global (None, 64)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 4)                 260       
=================================================================
Total params: 660,868
Trainable params: 660,868
Non-trainable params: 0
_________________________________________________________________
None

ประเมินทั้งสองแบบในข้อมูลการทดสอบ:

binary_loss, binary_accuracy = binary_model.evaluate(binary_test_ds)
int_loss, int_accuracy = int_model.evaluate(int_test_ds)

print("Binary model accuracy: {:2.2%}".format(binary_accuracy))
print("Int model accuracy: {:2.2%}".format(int_accuracy))
250/250 [==============================] - 2s 8ms/step - loss: 0.5178 - accuracy: 0.8141
250/250 [==============================] - 2s 10ms/step - loss: 0.5194 - accuracy: 0.8091
Binary model accuracy: 81.41%
Int model accuracy: 80.91%

ส่งออกโมเดล

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

export_model = tf.keras.Sequential(
    [binary_vectorize_layer, binary_model,
     layers.Activation('sigmoid')])

export_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer='adam',
    metrics=['accuracy'])

# Test it with `raw_test_ds`, which yields raw strings
loss, accuracy = export_model.evaluate(raw_test_ds)
print("Accuracy: {:2.2%}".format(binary_accuracy))
250/250 [==============================] - 3s 11ms/step - loss: 0.7002 - accuracy: 0.8141
Accuracy: 81.41%

ตอนนี้โมเดลของคุณสามารถใช้สตริงดิบเป็นอินพุตและทำนายคะแนนสำหรับแต่ละป้ายกำกับโดยใช้ model.predict กำหนดฟังก์ชันเพื่อค้นหาป้ายกำกับที่มีคะแนนสูงสุด:

def get_string_labels(predicted_scores_batch):
  predicted_int_labels = tf.argmax(predicted_scores_batch, axis=1)
  predicted_labels = tf.gather(raw_train_ds.class_names, predicted_int_labels)
  return predicted_labels

เรียกใช้การอนุมานข้อมูลใหม่

inputs = [
    "how do I extract keys from a dict into a list?",  # python
    "debug public static void main(string[] args) {...}",  # java
]
predicted_scores = export_model.predict(inputs)
predicted_labels = get_string_labels(predicted_scores)
for input, label in zip(inputs, predicted_labels):
  print("Question: ", input)
  print("Predicted label: ", label.numpy())
Question:  how do I extract keys from a dict into a list?
Predicted label:  b'python'
Question:  debug public static void main(string[] args) {...}
Predicted label:  b'java'

การรวมตรรกะก่อนการประมวลผลข้อความไว้ในโมเดลของคุณช่วยให้คุณสามารถส่งออกโมเดลสำหรับการผลิตที่ช่วยลดความยุ่งยากในการปรับใช้และลดโอกาสใน การเบ้รถไฟ / ทดสอบ

มีความแตกต่างด้านประสิทธิภาพที่ควรคำนึงถึงเมื่อเลือกตำแหน่งที่จะใช้เลเยอร์ TextVectorization ของคุณ การใช้งานภายนอกแบบจำลองของคุณทำให้คุณสามารถประมวลผล CPU แบบอะซิงโครนัสและการบัฟเฟอร์ข้อมูลของคุณเมื่อฝึกอบรมกับ GPU ดังนั้นหากคุณกำลังฝึกโมเดลของคุณบน GPU คุณอาจต้องการใช้ตัวเลือกนี้เพื่อให้ได้ประสิทธิภาพที่ดีที่สุดในขณะที่พัฒนาโมเดลของคุณจากนั้นเปลี่ยนไปใช้เลเยอร์ TextVectorization ภายในโมเดลของคุณเมื่อคุณพร้อมที่จะเตรียมการปรับใช้ .

ไปที่ บทช่วยสอน นี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับโมเดลการประหยัด

ตัวอย่างที่ 2: ทำนายผู้เขียนแปล Illiad

ต่อไปนี้เป็นตัวอย่างของการใช้ tf.data.TextLineDataset เพื่อโหลดตัวอย่างจากไฟล์ข้อความและ tf.text เพื่อประมวลผลข้อมูลล่วงหน้า ในตัวอย่างนี้คุณจะใช้คำแปลภาษาอังกฤษที่แตกต่างกันสามฉบับในงานเดียวกันคือ Homer's Illiad และฝึกโมเดลเพื่อระบุผู้แปลโดยใช้ข้อความบรรทัดเดียว

ดาวน์โหลดและสำรวจชุดข้อมูล

ข้อความของการแปลทั้งสามโดย:

ไฟล์ข้อความที่ใช้ในบทช่วยสอนนี้ผ่านงานการประมวลผลล่วงหน้าทั่วไปบางอย่างเช่นการลบส่วนหัวและส่วนท้ายของเอกสารหมายเลขบรรทัดและชื่อบท ดาวน์โหลดไฟล์ที่มีขนาดเล็กเหล่านี้ในเครื่อง

DIRECTORY_URL = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'
FILE_NAMES = ['cowper.txt', 'derby.txt', 'butler.txt']

for name in FILE_NAMES:
  text_dir = utils.get_file(name, origin=DIRECTORY_URL + name)

parent_dir = pathlib.Path(text_dir).parent
list(parent_dir.iterdir())
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/cowper.txt
819200/815980 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/derby.txt
811008/809730 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/butler.txt
811008/807992 [==============================] - 0s 0us/step

[PosixPath('/root/.keras/datasets/derby.txt'),
 PosixPath('/root/.keras/datasets/cowper.txt'),
 PosixPath('/root/.keras/datasets/butler.txt')]

โหลดชุดข้อมูล

คุณจะใช้ TextLineDataset ซึ่งออกแบบมาเพื่อสร้าง tf.data.Dataset จากไฟล์ข้อความซึ่งแต่ละตัวอย่างเป็นบรรทัดข้อความจากไฟล์ต้นฉบับในขณะที่ text_dataset_from_directory จะถือว่าเนื้อหาทั้งหมดของไฟล์เป็นตัวอย่างเดียว TextLineDataset มีประโยชน์สำหรับข้อมูลข้อความที่ใช้บรรทัดเป็นหลัก (ตัวอย่างเช่นบทกวีหรือบันทึกข้อผิดพลาด)

วนซ้ำไฟล์เหล่านี้โหลดแต่ละไฟล์ลงในชุดข้อมูลของตัวเอง แต่ละตัวอย่างต้องติดป้ายกำกับแยกกันดังนั้นใช้ tf.data.Dataset.map เพื่อใช้ฟังก์ชัน Labeler กับแต่ละรายการ ซึ่งจะวนซ้ำทุกตัวอย่างในชุดข้อมูลโดยส่งคืนคู่ ( example, label )

def labeler(example, index):
  return example, tf.cast(index, tf.int64)
labeled_data_sets = []

for i, file_name in enumerate(FILE_NAMES):
  lines_dataset = tf.data.TextLineDataset(str(parent_dir/file_name))
  labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  labeled_data_sets.append(labeled_dataset)

จากนั้นคุณจะรวมชุดข้อมูลที่มีป้ายกำกับเหล่านี้เป็นชุดข้อมูลชุดเดียวและสับเปลี่ยน

BUFFER_SIZE = 50000
BATCH_SIZE = 64
VALIDATION_SIZE = 5000
all_labeled_data = labeled_data_sets[0]
for labeled_dataset in labeled_data_sets[1:]:
  all_labeled_data = all_labeled_data.concatenate(labeled_dataset)

all_labeled_data = all_labeled_data.shuffle(
    BUFFER_SIZE, reshuffle_each_iteration=False)

พิมพ์ตัวอย่างออกมาเล็กน้อยเช่นเดิม ชุดข้อมูลยังไม่ได้รับการจัดกลุ่มดังนั้นแต่ละรายการใน all_labeled_data สอดคล้องกับจุดข้อมูลเดียว:

for text, label in all_labeled_data.take(10):
  print("Sentence: ", text.numpy())
  print("Label:", label.numpy())
Sentence:  b"By the brisk breeze impell'd, and winnower's force;"
Label: 1
Sentence:  b"On this a brazen canister she plac'd,"
Label: 1
Sentence:  b'Trod in his steps, ere settled yet the dust.'
Label: 1
Sentence:  b'And stately \xc3\x86py. Their confederate powers'
Label: 0
Sentence:  b'Ill-fated parents both! nor thou to him,'
Label: 1
Sentence:  b'Let him not seek to terrify with force'
Label: 0
Sentence:  b'the tomb of Aepytus, where the people fight hand to hand; the men of'
Label: 2
Sentence:  b"And Theseus, AEgeus' more than mortal son."
Label: 1
Sentence:  b'To whom in wrath Achilles swift of foot;'
Label: 1
Sentence:  b'The lance of Diomed, behind his neck,'
Label: 1

เตรียมชุดข้อมูลสำหรับการฝึกอบรม

แทนที่จะใช้เลเยอร์ TextVectorization เพื่อประมวลผลชุดข้อมูลข้อความของเราล่วงหน้าตอนนี้คุณจะใช้ tf.text API เพื่อสร้างมาตรฐานและสร้างโทเค็นข้อมูลสร้างคำศัพท์และใช้ StaticVocabularyTable เพื่อแมปโทเค็นกับจำนวนเต็มเพื่อป้อนเข้าโมเดล

แม้ว่า tf.text จะให้โทเค็นไนเซอร์ต่างๆ แต่คุณจะใช้ UnicodeScriptTokenizer เพื่อสร้างโทเค็นชุดข้อมูลของเรา กำหนดฟังก์ชันเพื่อแปลงข้อความเป็นตัวพิมพ์เล็กและโทเค็น คุณจะใช้ tf.data.Dataset.map เพื่อใช้ tf.data.Dataset.map กับชุดข้อมูล

tokenizer = tf_text.UnicodeScriptTokenizer()
def tokenize(text, unused_label):
  lower_case = tf_text.case_fold_utf8(text)
  return tokenizer.tokenize(lower_case)
tokenized_ds = all_labeled_data.map(tokenize)
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/util/dispatch.py:201: batch_gather (from tensorflow.python.ops.array_ops) is deprecated and will be removed after 2017-10-25.
Instructions for updating:
`tf.batch_gather` is deprecated, please use `tf.gather` with `batch_dims=-1` instead.

คุณสามารถวนซ้ำชุดข้อมูลและพิมพ์ตัวอย่างโทเค็นบางส่วนได้

for text_batch in tokenized_ds.take(5):
  print("Tokens: ", text_batch.numpy())
Tokens:  [b'by' b'the' b'brisk' b'breeze' b'impell' b"'" b'd' b',' b'and'
 b'winnower' b"'" b's' b'force' b';']
Tokens:  [b'on' b'this' b'a' b'brazen' b'canister' b'she' b'plac' b"'" b'd' b',']
Tokens:  [b'trod' b'in' b'his' b'steps' b',' b'ere' b'settled' b'yet' b'the'
 b'dust' b'.']
Tokens:  [b'and' b'stately' b'\xc3\xa6py' b'.' b'their' b'confederate' b'powers']
Tokens:  [b'ill' b'-' b'fated' b'parents' b'both' b'!' b'nor' b'thou' b'to' b'him'
 b',']

จากนั้นคุณจะสร้างคำศัพท์โดยการจัดเรียงโทเค็นตามความถี่และรักษาโทเค็น VOCAB_SIZE อันดับ VOCAB_SIZE ๆ ไว้

tokenized_ds = configure_dataset(tokenized_ds)

vocab_dict = collections.defaultdict(lambda: 0)
for toks in tokenized_ds.as_numpy_iterator():
  for tok in toks:
    vocab_dict[tok] += 1

vocab = sorted(vocab_dict.items(), key=lambda x: x[1], reverse=True)
vocab = [token for token, count in vocab]
vocab = vocab[:VOCAB_SIZE]
vocab_size = len(vocab)
print("Vocab size: ", vocab_size)
print("First five vocab entries:", vocab[:5])
Vocab size:  10000
First five vocab entries: [b',', b'the', b'and', b"'", b'of']

ในการแปลงโทเค็นเป็นจำนวนเต็มให้ใช้ชุด vocab เพื่อสร้าง StaticVocabularyTable คุณจะจับคู่โทเค็นกับจำนวนเต็มในช่วง [ 2 , vocab_size + 2 ] เช่นเดียวกับเลเยอร์ TextVectorization 0 สงวนไว้เพื่อแสดงถึงช่องว่างภายในและ 1 สงวนไว้เพื่อแสดงถึงโทเค็นที่ไม่ตรงตามคำศัพท์ (OOV)

keys = vocab
values = range(2, len(vocab) + 2)  # reserve 0 for padding, 1 for OOV

init = tf.lookup.KeyValueTensorInitializer(
    keys, values, key_dtype=tf.string, value_dtype=tf.int64)

num_oov_buckets = 1
vocab_table = tf.lookup.StaticVocabularyTable(init, num_oov_buckets)

สุดท้ายกำหนด fuction เพื่อสร้างมาตรฐานสร้างโทเค็นและกำหนดเวกเตอร์ชุดข้อมูลโดยใช้ tokenizer และตารางการค้นหา:

def preprocess_text(text, label):
  standardized = tf_text.case_fold_utf8(text)
  tokenized = tokenizer.tokenize(standardized)
  vectorized = vocab_table.lookup(tokenized)
  return vectorized, label

คุณสามารถลองใช้สิ่งนี้ในตัวอย่างเดียวเพื่อดูผลลัพธ์:

example_text, example_label = next(iter(all_labeled_data))
print("Sentence: ", example_text.numpy())
vectorized_text, example_label = preprocess_text(example_text, example_label)
print("Vectorized sentence: ", vectorized_text.numpy())
Sentence:  b"By the brisk breeze impell'd, and winnower's force;"
Vectorized sentence:  [  26    3 3286 2263 1959    5    9    2    4 7806    5   29  260   10]

ตอนนี้เรียกใช้ฟังก์ชัน preprocess บนชุดข้อมูลโดยใช้ tf.data.Dataset.map

all_encoded_data = all_labeled_data.map(preprocess_text)

แยกชุดข้อมูลออกเป็นรถไฟและทดสอบ

เลเยอร์ TextVectorization ยังแบทช์และวางข้อมูลที่เป็นเวกเตอร์ จำเป็นต้องมีช่องว่างภายในเนื่องจากตัวอย่างภายในชุดงานต้องมีขนาดและรูปร่างเดียวกัน แต่ตัวอย่างในชุดข้อมูลเหล่านี้มีขนาดไม่เท่ากันทั้งหมดแต่ละบรรทัดของข้อความมีจำนวนคำที่แตกต่างกัน tf.data.Dataset รองรับชุดข้อมูลแบบแยกและแบบเบาะ:

train_data = all_encoded_data.skip(VALIDATION_SIZE).shuffle(BUFFER_SIZE)
validation_data = all_encoded_data.take(VALIDATION_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE)
validation_data = validation_data.padded_batch(BATCH_SIZE)

ตอนนี้ validation_data และ train_data ไม่ใช่คอลเล็กชันของคู่ ( example, label ) แต่เป็นคอลเล็กชันของแบทช์ แต่ละชุดเป็นคู่ของ ( หลายตัวอย่าง ป้ายกำกับจำนวนมาก ) ที่แสดงเป็นอาร์เรย์ เพื่อเป็นตัวอย่าง:

sample_text, sample_labels = next(iter(validation_data))
print("Text batch shape: ", sample_text.shape)
print("Label batch shape: ", sample_labels.shape)
print("First text example: ", sample_text[0])
print("First label example: ", sample_labels[0])
Text batch shape:  (64, 18)
Label batch shape:  (64,)
First text example:  tf.Tensor(
[  26    3 3286 2263 1959    5    9    2    4 7806    5   29  260   10
    0    0    0    0], shape=(18,), dtype=int64)
First label example:  tf.Tensor(1, shape=(), dtype=int64)

เนื่องจากเราใช้ 0 สำหรับช่องว่างภายในและ 1 สำหรับโทเค็นที่ไม่ใช้คำศัพท์ (OOV) ขนาดคำศัพท์จึงเพิ่มขึ้นสอง

vocab_size += 2

กำหนดค่าชุดข้อมูลเพื่อประสิทธิภาพที่ดีขึ้นเหมือนเดิม

train_data = configure_dataset(train_data)
validation_data = configure_dataset(validation_data)

ฝึกโมเดล

คุณสามารถฝึกโมเดลในชุดข้อมูลนี้ได้เหมือนเดิม

model = create_model(vocab_size=vocab_size, num_labels=3)
model.compile(
    optimizer='adam',
    loss=losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy'])
history = model.fit(train_data, validation_data=validation_data, epochs=3)
Epoch 1/3
697/697 [==============================] - 9s 13ms/step - loss: 0.5224 - accuracy: 0.7665 - val_loss: 0.3657 - val_accuracy: 0.8460
Epoch 2/3
697/697 [==============================] - 6s 8ms/step - loss: 0.2834 - accuracy: 0.8836 - val_loss: 0.3596 - val_accuracy: 0.8488
Epoch 3/3
697/697 [==============================] - 6s 9ms/step - loss: 0.1914 - accuracy: 0.9262 - val_loss: 0.3951 - val_accuracy: 0.8476

loss, accuracy = model.evaluate(validation_data)

print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
79/79 [==============================] - 0s 2ms/step - loss: 0.3951 - accuracy: 0.8476
Loss:  0.39514628052711487
Accuracy: 84.76%

ส่งออกโมเดล

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

preprocess_layer = TextVectorization(
    max_tokens=vocab_size,
    standardize=tf_text.case_fold_utf8,
    split=tokenizer.tokenize,
    output_mode='int',
    output_sequence_length=MAX_SEQUENCE_LENGTH)
preprocess_layer.set_vocabulary(vocab)
export_model = tf.keras.Sequential(
    [preprocess_layer, model,
     layers.Activation('sigmoid')])

export_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer='adam',
    metrics=['accuracy'])
# Create a test dataset of raw strings
test_ds = all_labeled_data.take(VALIDATION_SIZE).batch(BATCH_SIZE)
test_ds = configure_dataset(test_ds)
loss, accuracy = export_model.evaluate(test_ds)
print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
79/79 [==============================] - 1s 10ms/step - loss: 0.5304 - accuracy: 0.7978
Loss:  0.5304141640663147
Accuracy: 79.78%

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

เรียกใช้การอนุมานข้อมูลใหม่

inputs = [
    "Join'd to th' Ionians with their flowing robes,",  # Label: 1
    "the allies, and his armour flashed about him so that he seemed to all",  # Label: 2
    "And with loud clangor of his arms he fell.",  # Label: 0
]
predicted_scores = export_model.predict(inputs)
predicted_labels = tf.argmax(predicted_scores, axis=1)
for input, label in zip(inputs, predicted_labels):
  print("Question: ", input)
  print("Predicted label: ", label.numpy())
Question:  Join'd to th' Ionians with their flowing robes,
Predicted label:  1
Question:  the allies, and his armour flashed about him so that he seemed to all
Predicted label:  2
Question:  And with loud clangor of his arms he fell.
Predicted label:  0

การดาวน์โหลดชุดข้อมูลเพิ่มเติมโดยใช้ TensorFlow Datasets (TFDS)

คุณสามารถดาวน์โหลดชุดข้อมูลเพิ่มเติมได้จาก TensorFlow Datasets ตัวอย่างเช่นคุณจะดาวน์โหลด ชุดข้อมูล IMDB Large Movie Review และใช้เพื่อฝึกโมเดลสำหรับการจำแนกประเภทความรู้สึก

train_ds = tfds.load(
    'imdb_reviews',
    split='train',
    batch_size=BATCH_SIZE,
    shuffle_files=True,
    as_supervised=True)
Downloading and preparing dataset imdb_reviews/plain_text/1.0.0 (download: 80.23 MiB, generated: Unknown size, total: 80.23 MiB) to /root/tensorflow_datasets/imdb_reviews/plain_text/1.0.0...

HBox(children=(FloatProgress(value=1.0, bar_style='info', description='Dl Completed...', max=1.0, style=Progre…
HBox(children=(FloatProgress(value=1.0, bar_style='info', description='Dl Size...', max=1.0, style=ProgressSty…





HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))
Shuffling and writing examples to /root/tensorflow_datasets/imdb_reviews/plain_text/1.0.0.incompleteBKTU7R/imdb_reviews-train.tfrecord

HBox(children=(FloatProgress(value=0.0, max=25000.0), HTML(value='')))

HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))
Shuffling and writing examples to /root/tensorflow_datasets/imdb_reviews/plain_text/1.0.0.incompleteBKTU7R/imdb_reviews-test.tfrecord

HBox(children=(FloatProgress(value=0.0, max=25000.0), HTML(value='')))

HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))
Shuffling and writing examples to /root/tensorflow_datasets/imdb_reviews/plain_text/1.0.0.incompleteBKTU7R/imdb_reviews-unsupervised.tfrecord

HBox(children=(FloatProgress(value=0.0, max=50000.0), HTML(value='')))
Dataset imdb_reviews downloaded and prepared to /root/tensorflow_datasets/imdb_reviews/plain_text/1.0.0. Subsequent calls will reuse this data.

val_ds = tfds.load(
    'imdb_reviews',
    split='train',
    batch_size=BATCH_SIZE,
    shuffle_files=True,
    as_supervised=True)

พิมพ์ตัวอย่างเล็กน้อย

for review_batch, label_batch in val_ds.take(1):
  for i in range(5):
    print("Review: ", review_batch[i].numpy())
    print("Label: ", label_batch[i].numpy())
Review:  b"This was an absolutely terrible movie. Don't be lured in by Christopher Walken or Michael Ironside. Both are great actors, but this must simply be their worst role in history. Even their great acting could not redeem this movie's ridiculous storyline. This movie is an early nineties US propaganda piece. The most pathetic scenes were those when the Columbian rebels were making their cases for revolutions. Maria Conchita Alonso appeared phony, and her pseudo-love affair with Walken was nothing but a pathetic emotional plug in a movie that was devoid of any real meaning. I am disappointed that there are movies like this, ruining actor's like Christopher Walken's good name. I could barely sit through it."
Label:  0
Review:  b'I have been known to fall asleep during films, but this is usually due to a combination of things including, really tired, being warm and comfortable on the sette and having just eaten a lot. However on this occasion I fell asleep because the film was rubbish. The plot development was constant. Constantly slow and boring. Things seemed to happen, but with no explanation of what was causing them or why. I admit, I may have missed part of the film, but i watched the majority of it and everything just seemed to happen of its own accord without any real concern for anything else. I cant recommend this film at all.'
Label:  0
Review:  b'Mann photographs the Alberta Rocky Mountains in a superb fashion, and Jimmy Stewart and Walter Brennan give enjoyable performances as they always seem to do. <br /><br />But come on Hollywood - a Mountie telling the people of Dawson City, Yukon to elect themselves a marshal (yes a marshal!) and to enforce the law themselves, then gunfighters battling it out on the streets for control of the town? <br /><br />Nothing even remotely resembling that happened on the Canadian side of the border during the Klondike gold rush. Mr. Mann and company appear to have mistaken Dawson City for Deadwood, the Canadian North for the American Wild West.<br /><br />Canadian viewers be prepared for a Reefer Madness type of enjoyable howl with this ludicrous plot, or, to shake your head in disgust.'
Label:  0
Review:  b'This is the kind of film for a snowy Sunday afternoon when the rest of the world can go ahead with its own business as you descend into a big arm-chair and mellow for a couple of hours. Wonderful performances from Cher and Nicolas Cage (as always) gently row the plot along. There are no rapids to cross, no dangerous waters, just a warm and witty paddle through New York life at its best. A family film in every sense and one that deserves the praise it received.'
Label:  1
Review:  b'As others have mentioned, all the women that go nude in this film are mostly absolutely gorgeous. The plot very ably shows the hypocrisy of the female libido. When men are around they want to be pursued, but when no "men" are around, they become the pursuers of a 14 year old boy. And the boy becomes a man really fast (we should all be so lucky at this age!). He then gets up the courage to pursue his true love.'
Label:  1

ตอนนี้คุณสามารถประมวลผลข้อมูลล่วงหน้าและฝึกโมเดลได้เหมือนเดิม

เตรียมชุดข้อมูลสำหรับการฝึกอบรม

vectorize_layer = TextVectorization(
    max_tokens=VOCAB_SIZE,
    output_mode='int',
    output_sequence_length=MAX_SEQUENCE_LENGTH)

# Make a text-only dataset (without labels), then call adapt
train_text = train_ds.map(lambda text, labels: text)
vectorize_layer.adapt(train_text)
def vectorize_text(text, label):
  text = tf.expand_dims(text, -1)
  return vectorize_layer(text), label
train_ds = train_ds.map(vectorize_text)
val_ds = val_ds.map(vectorize_text)
# Configure datasets for performance as before
train_ds = configure_dataset(train_ds)
val_ds = configure_dataset(val_ds)

ฝึกโมเดล

model = create_model(vocab_size=VOCAB_SIZE + 1, num_labels=1)
model.summary()
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, None, 64)          640064    
_________________________________________________________________
conv1d_2 (Conv1D)            (None, None, 64)          20544     
_________________________________________________________________
global_max_pooling1d_2 (Glob (None, 64)                0         
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 65        
=================================================================
Total params: 660,673
Trainable params: 660,673
Non-trainable params: 0
_________________________________________________________________

model.compile(
    loss=losses.BinaryCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
history = model.fit(train_ds, validation_data=val_ds, epochs=3)
Epoch 1/3
391/391 [==============================] - 9s 23ms/step - loss: 0.4976 - accuracy: 0.7044 - val_loss: 0.2976 - val_accuracy: 0.8832
Epoch 2/3
391/391 [==============================] - 5s 14ms/step - loss: 0.2748 - accuracy: 0.8801 - val_loss: 0.1696 - val_accuracy: 0.9458
Epoch 3/3
391/391 [==============================] - 6s 14ms/step - loss: 0.1697 - accuracy: 0.9351 - val_loss: 0.0956 - val_accuracy: 0.9770

loss, accuracy = model.evaluate(val_ds)

print("Loss: ", loss)
print("Accuracy: {:2.2%}".format(accuracy))
391/391 [==============================] - 1s 3ms/step - loss: 0.0956 - accuracy: 0.9770
Loss:  0.09558165073394775
Accuracy: 97.70%

ส่งออกโมเดล

export_model = tf.keras.Sequential(
    [vectorize_layer, model,
     layers.Activation('sigmoid')])

export_model.compile(
    loss=losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer='adam',
    metrics=['accuracy'])
# 0 --> negative review
# 1 --> positive review
inputs = [
    "This is a fantastic movie.",
    "This is a bad movie.",
    "This movie was so bad that it was good.",
    "I will never say yes to watching this movie.",
]
predicted_scores = export_model.predict(inputs)
predicted_labels = [int(round(x[0])) for x in predicted_scores]
for input, label in zip(inputs, predicted_labels):
  print("Question: ", input)
  print("Predicted label: ", label)
Question:  This is a fantastic movie.
Predicted label:  1
Question:  This is a bad movie.
Predicted label:  0
Question:  This movie was so bad that it was good.
Predicted label:  0
Question:  I will never say yes to watching this movie.
Predicted label:  1

สรุป

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