使用 TensorFlow Hub 進行文字分類:電影評論

在 TensorFlow.org 上檢視 在 Google Colab 中執行 在 GitHub 上檢視 下載筆記本 查看 TF Hub 模型

這個筆記本使用評論文字將電影評論分類為正面負面。這是二元分類 (或雙類別分類) 的範例,二元分類是一種重要且廣泛適用的機器學習問題。

本教學課程示範搭配 TensorFlow Hub 和 Keras 進行遷移學習的基本應用。

本教學課程使用 IMDB 資料集,其中包含來自 網際網路電影資料庫的 50,000 筆電影評論文字。這些評論分為 25,000 筆訓練評論和 25,000 筆測試評論。訓練集和測試集是平衡的,表示它們包含相同數量的正面和負面評論。

這個筆記本使用 tf.keras (用於在 TensorFlow 中建構和訓練模型的高階 API) 和 tensorflow_hub (用於以單行程式碼從 TFHub 載入已訓練模型的程式庫)。如需使用 tf.keras 的更進階文字分類教學課程,請參閱 MLCC 文字分類指南

pip install tensorflow-hub
pip install tensorflow-datasets
import os
import numpy as np

import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_datasets as tfds

print("Version: ", tf.__version__)
print("Eager mode: ", tf.executing_eagerly())
print("Hub version: ", hub.__version__)
print("GPU is", "available" if tf.config.list_physical_devices("GPU") else "NOT AVAILABLE")

下載 IMDB 資料集

IMDB 資料集可在 imdb 評論TensorFlow 資料集上取得。以下程式碼會將 IMDB 資料集下載到您的機器 (或 Colab 執行階段)

# Split the training set into 60% and 40% to end up with 15,000 examples
# for training, 10,000 examples for validation and 25,000 examples for testing.
train_data, validation_data, test_data = tfds.load(
    name="imdb_reviews", 
    split=('train[:60%]', 'train[60%:]', 'test'),
    as_supervised=True)

探索資料

我們先花一點時間瞭解資料的格式。每個範例都是一個句子,代表電影評論和對應的標籤。句子未經任何預先處理。標籤是一個整數值,可以是 0 或 1,其中 0 代表負面評論,1 代表正面評論。

讓我們印出前 10 個範例。

train_examples_batch, train_labels_batch = next(iter(train_data.batch(10)))
train_examples_batch

我們也印出前 10 個標籤。

train_labels_batch

建構模型

神經網路是透過堆疊層來建立的,這需要三個主要的架構決策

  • 如何表示文字?
  • 模型中要使用多少層?
  • 每個層要使用多少隱藏單元

在這個範例中,輸入資料包含句子。要預測的標籤是 0 或 1。

表示文字的一種方法是將句子轉換為嵌入向量。使用預先訓練的文字嵌入作為第一層,這將有三個優點

  • 您不必擔心文字預先處理,
  • 受益於遷移學習,
  • 嵌入具有固定大小,因此更易於處理。

對於這個範例,您可以使用來自 TensorFlow Hub 且名為 google/nnlm-en-dim50/2預先訓練文字嵌入模型

TFHub 上還有許多其他預先訓練的文字嵌入,可用於本教學課程

還有更多!在 TFHub 上尋找更多文字嵌入模型

我們先建立一個 Keras 層,使用 TensorFlow Hub 模型嵌入句子,並在幾個輸入範例上試用它。請注意,無論輸入文字的長度為何,嵌入的輸出形狀都是:(num_examples, embedding_dimension)

embedding = "https://tfhub.dev/google/nnlm-en-dim50/2"
hub_layer = hub.KerasLayer(embedding, input_shape=[], 
                           dtype=tf.string, trainable=True)
hub_layer(train_examples_batch[:3])

現在讓我們建構完整模型

model = tf.keras.Sequential()
model.add(hub_layer)
model.add(tf.keras.layers.Dense(16, activation='relu'))
model.add(tf.keras.layers.Dense(1))

model.summary()

這些層依序堆疊以建構分類器

  1. 第一層是 TensorFlow Hub 層。此層使用預先訓練的 Saved Model 將句子對應到其嵌入向量。您正在使用的預先訓練文字嵌入模型 (google/nnlm-en-dim50/2) 將句子分割為權杖,嵌入每個權杖,然後組合嵌入。產生的維度為:(num_examples, embedding_dimension)。對於此 NNLM 模型,embedding_dimension 為 50。
  2. 這個固定長度的輸出向量會透過具有 16 個隱藏單元的全連接 (Dense) 層。
  3. 最後一層與單一輸出節點緊密連接。

讓我們編譯模型。

損失函數和最佳化工具

模型需要損失函數和最佳化工具才能進行訓練。由於這是二元分類問題,而且模型輸出 logits (具有線性啟動的單元層),您將使用 binary_crossentropy 損失函數。

這不是損失函數的唯一選擇,例如,您可以選擇 mean_squared_error。但是,一般而言,binary_crossentropy 更適合處理機率,它可以測量機率分佈之間的「距離」,或者在我們的案例中,測量真實分佈和預測之間的距離。

稍後,當您探索迴歸問題 (例如,預測房屋價格) 時,您將看到如何使用另一個稱為均方誤差的損失函數。

現在,設定模型以使用最佳化工具和損失函數

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])

訓練模型

以 512 個樣本的小批次訓練模型 10 個週期。這是對 x_trainy_train 張量中的所有樣本進行 10 次疊代。在訓練期間,監控模型在驗證集中 10,000 個樣本上的損失和準確度

history = model.fit(train_data.shuffle(10000).batch(512),
                    epochs=10,
                    validation_data=validation_data.batch(512),
                    verbose=1)

評估模型

讓我們看看模型的效能。將傳回兩個值。損失 (代表我們誤差的數字,值越低越好) 和準確度。

results = model.evaluate(test_data.batch(512), verbose=2)

for name, value in zip(model.metrics_names, results):
  print("%s: %.3f" % (name, value))

這種相當簡單的方法實現了約 87% 的準確度。使用更進階的方法,模型應該更接近 95%。

延伸閱讀

# MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.