TensorFlowLiteモデルメーカーによるテキスト分類

TensorFlow.orgで表示 GoogleColabで実行 GitHubでソースを表示ノートブックをダウンロードする

TensorFlow Lite Model Makerライブラリは、デバイス上のMLアプリケーションにこのモデルをデプロイするときに、TensorFlowモデルを特定の入力データに適合および変換するプロセスを簡素化します。

このノートブックは、モデルメーカーライブラリを利用して、モバイルデバイスで映画レビューを分類するために一般的に使用されるテキスト分類モデルの適応と変換を説明するエンドツーエンドの例を示しています。テキスト分類モデルは、テキストを事前定義されたカテゴリに分類します。入力は前処理されたテキストである必要があり、出力はカテゴリの確率です。このチュートリアルで使用されるデータセットは、ポジティブおよびネガティブな映画レビューです。

前提条件

必要なパッケージをインストールします

この例を実行するには、 GitHubリポジトリのModelMakerパッケージを含む必要なパッケージをインストールします。

pip install -q tflite-model-maker

必要なパッケージをインポートします。

import numpy as np
import os

from tflite_model_maker import model_spec
from tflite_model_maker import text_classifier
from tflite_model_maker.config import ExportFormat
from tflite_model_maker.text_classifier import AverageWordVecSpec
from tflite_model_maker.text_classifier import DataLoader

import tensorflow as tf
assert tf.__version__.startswith('2')
tf.get_logger().setLevel('ERROR')
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/numba/core/errors.py:154: UserWarning: Insufficiently recent colorama version found. Numba requires colorama >= 0.3.9
  warnings.warn(msg)

サンプルトレーニングデータをダウンロードします。

このチュートリアルでは、 GLUEベンチマークのタスクの1つであるSST-2 (Stanford Sentiment Treebank)を使用します。トレーニング用の67,349本の映画レビューとテスト用の872本の映画レビューが含まれています。データセットには、ポジティブとネガティブの映画レビューの2つのクラスがあります。

data_dir = tf.keras.utils.get_file(
      fname='SST-2.zip',
      origin='https://dl.fbaipublicfiles.com/glue/data/SST-2.zip',
      extract=True)
data_dir = os.path.join(os.path.dirname(data_dir), 'SST-2')
Downloading data from https://dl.fbaipublicfiles.com/glue/data/SST-2.zip
7446528/7439277 [==============================] - 2s 0us/step

SST-2データセットはTSV形式で保存されます。 TSVとCSVの唯一の違いは、TSV、タブ使用していることです\tコンマの代わりにその区切り文字として文字を, CSV形式で。

これがトレーニングデータセットの最初の5行です。 label = 0は負を意味し、label = 1は正を意味します。

ラベル
親ユニットから新しい分泌物を隠す0
ウィットは含まれていません。 0
そのキャラクターを愛し、人間の本性についてかなり美しい何かを伝えます1
ずっと同じままでいるために完全に満足している0
最悪のオタクの復讐の決まり文句で、映画製作者は浚渫する可能性があります0

次に、データセットをPandasデータフレームにロードし、現在のラベル名( 01 )をより人間が読める形式( negativepositive )に変更して、モデルのトレーニングに使用します。

import pandas as pd

def replace_label(original_file, new_file):
  # Load the original file to pandas. We need to specify the separator as
  # '\t' as the training data is stored in TSV format
  df = pd.read_csv(original_file, sep='\t')

  # Define how we want to change the label name
  label_map = {0: 'negative', 1: 'positive'}

  # Excute the label change
  df.replace({'label': label_map}, inplace=True)

  # Write the updated dataset to a new file
  df.to_csv(new_file)

# Replace the label name for both the training and test dataset. Then write the
# updated CSV dataset to the current folder.
replace_label(os.path.join(os.path.join(data_dir, 'train.tsv')), 'train.csv')
replace_label(os.path.join(os.path.join(data_dir, 'dev.tsv')), 'dev.csv')

クイックスタート

テキスト分類モデルをトレーニングするには、次の5つの手順があります。

手順1.テキスト分類モデルアーキテクチャを選択します。

ここでは、平均的な単語埋め込みモデルアーキテクチャを使用します。これにより、小さくて高速なモデルが適切な精度で生成されます。

spec = model_spec.get('average_word_vec')

Model Makerは、 BERTなどの他のモデルアーキテクチャもサポートしています。他のアーキテクチャについて知りたい場合は、以下の「テキスト分類子のモデルアーキテクチャ選択」セクションを参照してください。

手順2.トレーニングデータとテストデータを読み込み、特定のmodel_specに従って前処理します。

モデルメーカーは、CSV形式で入力データを取得できます。以前に作成した人間が読めるラベル名を使用して、トレーニングとテストのデータセットを読み込みます。

各モデルアーキテクチャでは、入力データを特定の方法で処理する必要があります。 DataLoaderは、 model_specから要件を読み取り、必要な前処理を自動的に実行します。

train_data = DataLoader.from_csv(
      filename='train.csv',
      text_column='sentence',
      label_column='label',
      model_spec=spec,
      is_training=True)
test_data = DataLoader.from_csv(
      filename='dev.csv',
      text_column='sentence',
      label_column='label',
      model_spec=spec,
      is_training=False)

ステップ3.トレーニングデータを使用してTensorFlowモデルをトレーニングします。

平均的な単語埋め込みモデルは、デフォルトでbatch_size = 32使用します。したがって、トレーニングデータセットの67,349文を通過するには2104ステップかかることがわかります。モデルを10エポックトレーニングします。つまり、トレーニングデータセットを10回実行します。

model = text_classifier.create(train_data, model_spec=spec, epochs=10)
Epoch 1/10
2104/2104 [==============================] - 8s 3ms/step - loss: 0.6808 - accuracy: 0.5622
Epoch 2/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.5791 - accuracy: 0.7025
Epoch 3/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.4578 - accuracy: 0.7896
Epoch 4/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.4040 - accuracy: 0.8222
Epoch 5/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.3768 - accuracy: 0.8380
Epoch 6/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.3614 - accuracy: 0.8481
Epoch 7/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.3490 - accuracy: 0.8553
Epoch 8/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.3420 - accuracy: 0.8600
Epoch 9/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.3354 - accuracy: 0.8630
Epoch 10/10
2104/2104 [==============================] - 6s 3ms/step - loss: 0.3293 - accuracy: 0.8660

ステップ4.テストデータを使用してモデルを評価します。

トレーニングデータセットの文を使用してテキスト分類モデルをトレーニングした後、テストデータセットの残りの872文を使用して、これまでに見たことのない新しいデータに対してモデルがどのように機能するかを評価します。

デフォルトのバッチサイズは32であるため、テストデータセットの872文を処理するには28ステップかかります。

loss, acc = model.evaluate(test_data)
28/28 [==============================] - 0s 2ms/step - loss: 0.5155 - accuracy: 0.8337

ステップ5.TensorFlowLiteモデルとしてエクスポートします。

トレーニングしたテキスト分類をTensorFlowLite形式でエクスポートしてみましょう。モデルをエクスポートするフォルダーを指定します。デフォルトでは、float TFLiteモデルは、平均的な単語埋め込みモデルアーキテクチャ用にエクスポートされます。

model.export(export_dir='average_word_vec')

Colabの左側のサイドバーを使用して、TensorFlowLiteモデルファイルをダウンロードできます。上記のexport_dirパラメーターで指定したaverage_word_vecフォルダーに移動し、 model.tfliteファイルを右クリックして、[ Downloadを選択してローカルコンピューターにダウンロードします。

このモデルは、使用してAndroidやiOSアプリに統合することができNLClassifierのAPITensorFlow Liteのタスク・ライブラリーを

動作中のアプリでモデルがどのように使用されるかの詳細については、 TFLiteテキスト分類サンプルアプリを参照してください。

注1:Android Studio Model Bindingはまだテキスト分類をサポートしていないため、TensorFlowLiteタスクライブラリを使用してください。

注2:TFLiteモデルと同じフォルダーにmodel.jsonファイルがあります。これには、TensorFlowLiteモデル内にバンドルされているメタデータのJSON表現が含まれています。モデルメタデータは、TFLiteタスクライブラリがモデルの機能とモデルのデータを前処理/後処理する方法を知るのに役立ちます。 model.jsonファイルは情報提供のみを目的としており、その内容はすでにTFLiteファイル内にあるため、ダウンロードする必要はありません。

注3:MobileBERTまたはBERT-Baseアーキテクチャを使用してテキスト分類モデルをトレーニングする場合は、代わりにBertNLClassifier APIを使用して、トレーニングしたモデルをモバイルアプリに統合する必要があります。

次のセクションでは、例を段階的に説明して、詳細を示します。

テキスト分類子のモデルアーキテクチャを選択します

model_specオブジェクトは、テキスト分類子の特定のモデルを表します。 TensorFlow Lite Model Makerは現在、 MobileBERTをサポートしており、単語の埋め込みとBERT-Baseモデルを平均化しています。

サポートされているモデルmodel_specの名前モデルの説明モデルサイズ
単語埋め込みの平均化'average_word_vec' RELUアクティベーションによるテキスト単語埋め込みの平均化。 <1MB
MobileBERT 'mobilebert_classifier' BERT-Baseより4.3倍小さく、5.5倍高速でありながら、デバイス上のアプリケーションに適した競争力のある結果を達成します。量子化付き25MB
量子化なしで100MB
BERT-Base 'bert_classifier' NLPタスクで広く使用されている標準のBERTモデル。 300MB

クイックスタートでは、平均的な単語埋め込みモデルを使用しました。より高い精度でモデルをトレーニングするために、 MobileBERTに切り替えましょう。

mb_spec = model_spec.get('mobilebert_classifier')

トレーニングデータを読み込む

独自のデータセットをアップロードして、このチュートリアルを実行できます。 Colabの左側のサイドバーを使用してデータセットをアップロードします。

ファイルをアップロードする

データセットをクラウドにアップロードしたくない場合は、 ガイドに従ってライブラリをローカルで実行することもできます。

簡単にするために、以前にダウンロードしたSST-2データセットを再利用します。 DataLoader.from_csvメソッドを使用してデータをロードしましょう。

モデルアーキテクチャを変更したため、新しい前処理ロジックを適用するには、トレーニングデータセットとテストデータセットを再読み込みする必要があることに注意してください。

train_data = DataLoader.from_csv(
      filename='train.csv',
      text_column='sentence',
      label_column='label',
      model_spec=mb_spec,
      is_training=True)
test_data = DataLoader.from_csv(
      filename='dev.csv',
      text_column='sentence',
      label_column='label',
      model_spec=mb_spec,
      is_training=False)

モデルメーカーライブラリは、データをロードするためのfrom_folder()メソッドもサポートしています。同じクラスのテキストデータが同じサブディレクトリにあり、サブフォルダ名がクラス名であると想定しています。各テキストファイルには、1つの映画レビューサンプルが含まれています。 class_labelsパラメーターは、どのサブフォルダーを指定するために使用されます。

TensorFlowモデルをトレーニングする

トレーニングデータを使用してテキスト分類モデルをトレーニングします。

model = text_classifier.create(train_data, model_spec=mb_spec, epochs=3)
Epoch 1/3
1403/1403 [==============================] - 319s 191ms/step - loss: 0.3808 - test_accuracy: 0.8441
Epoch 2/3
1403/1403 [==============================] - 262s 187ms/step - loss: 0.1296 - test_accuracy: 0.9534
Epoch 3/3
1403/1403 [==============================] - 264s 188ms/step - loss: 0.0750 - test_accuracy: 0.9759

詳細なモデル構造を調べます。

model.summary()
Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_word_ids (InputLayer)     [(None, 128)]        0                                            
__________________________________________________________________________________________________
input_mask (InputLayer)         [(None, 128)]        0                                            
__________________________________________________________________________________________________
input_type_ids (InputLayer)     [(None, 128)]        0                                            
__________________________________________________________________________________________________
hub_keras_layer_v1v2 (HubKerasL (None, 512)          24581888    input_word_ids[0][0]             
                                                                 input_mask[0][0]                 
                                                                 input_type_ids[0][0]             
__________________________________________________________________________________________________
dropout_1 (Dropout)             (None, 512)          0           hub_keras_layer_v1v2[0][0]       
__________________________________________________________________________________________________
output (Dense)                  (None, 2)            1026        dropout_1[0][0]                  
==================================================================================================
Total params: 24,582,914
Trainable params: 24,582,914
Non-trainable params: 0
__________________________________________________________________________________________________

モデルを評価する

テストデータを使用してトレーニングしたばかりのモデルを評価し、損失と精度の値を測定します。

loss, acc = model.evaluate(test_data)
28/28 [==============================] - 7s 50ms/step - loss: 0.3626 - test_accuracy: 0.9037

TensorFlowLiteモデルとしてエクスポート

トレーニング済みモデルをメタデータを含むTensorFlowLiteモデル形式に変換して、後でデバイス上のMLアプリケーションで使用できるようにします。ラベルファイルと語彙ファイルはメタデータに埋め込まれています。デフォルトのTFLiteファイル名はmodel.tfliteです。

多くのオンデバイスMLアプリケーションでは、モデルサイズが重要な要素です。したがって、モデルを小さくし、実行速度を上げる可能性があるように、クオンタイズを適用することをお勧めします。デフォルトのトレーニング後の量子化手法は、BERTおよびMobileBERTモデルのダイナミックレンジ量子化です。

model.export(export_dir='mobilebert/')

TensorFlow Liteのモデルファイルを使用してモバイルアプリに統合することができBertNLClassifierのAPITensorFlow Liteのタスク・ライブラリーを。これは、平均的な単語ベクトルモデルアーキテクチャでトレーニングされたテキスト分類を統合するために使用されるNLClassifierとは異なることに注意してください。

エクスポート形式は、次の1つまたはリストにすることができます。

デフォルトでは、モデルメタデータを含むTensorFlowLiteモデルファイルのみをエクスポートします。モデルに関連する他のファイルをエクスポートして、より適切に調査することもできます。たとえば、次のようにラベルファイルと語彙ファイルのみをエクスポートします。

model.export(export_dir='mobilebert/', export_format=[ExportFormat.LABEL, ExportFormat.VOCAB])

TFLiteモデルをevaluate_tfliteメソッドでevaluate_tfliteして、その精度を測定できます。トレーニング済みのTensorFlowモデルをTFLite形式に変換し、量子化を適用すると、その精度に影響を与える可能性があるため、デプロイする前にTFLiteモデルの精度を評価することをお勧めします。

accuracy = model.evaluate_tflite('mobilebert/model.tflite', test_data)
print('TFLite model accuracy: ', accuracy)
TFLite model accuracy:  {'accuracy': 0.9071100917431193}

高度な使用法

create関数は、ModelMakerライブラリがモデルを作成するために使用するドライバー関数です。 model_specパラメーターは、モデル仕様を定義します。 AverageWordVecSpecBertClassifierSpecクラスが現在サポートされています。 create機能は、次の手順で構成されています。

  1. model_specに従って、テキスト分類子のモデルを作成します。
  2. 分類器モデルをトレーニングします。デフォルトのエポックとデフォルトのバッチサイズはで設定されているdefault_training_epochsdefault_batch_sizeの変数model_specオブジェクト。

このセクションでは、モデルの調整やトレーニングハイパーパラメータなどの高度な使用トピックについて説明します。

MobileBERTモデルのハイパーパラメータをカスタマイズする

調整できるモデルパラメータは次のとおりです。

  • seq_len :モデルにフィードするシーケンスの長さ。
  • initializer_range :すべての重み行列を初期化するためのtruncated_normal_initializerの標準偏差。
  • trainable :事前にトレーニングされたレイヤーがトレーニング可能かどうかを指定するブール値。

調整できるトレーニングパイプラインパラメータは次のとおりです。

  • model_dir :モデルチェックポイントファイルの場所。設定されていない場合、一時ディレクトリが使用されます。
  • dropout_rate :ドロップアウト率。
  • learning_rate :Adamオプティマイザーの初期学習率。
  • tpu :接続するTPUアドレス。

たとえば、 seq_len=256 (デフォルトは128)を設定できます。これにより、モデルはより長いテキストを分類できます。

new_model_spec = model_spec.get('mobilebert_classifier')
new_model_spec.seq_len = 256

平均的な単語埋め込みモデルのハイパーパラメータをカスタマイズする

あなたは次のようにモデルのインフラストラクチャを調整することができwordvec_dimseq_lenの変数AverageWordVecSpecクラス。

たとえば、 wordvec_dim値を大きくしてモデルをトレーニングできます。モデルを変更する場合は、新しいmodel_spec作成する必要があることに注意してください。

new_model_spec = AverageWordVecSpec(wordvec_dim=32)

前処理されたデータを取得します。

new_train_data = DataLoader.from_csv(
      filename='train.csv',
      text_column='sentence',
      label_column='label',
      model_spec=new_model_spec,
      is_training=True)

新しいモデルをトレーニングします。

model = text_classifier.create(new_train_data, model_spec=new_model_spec)
Epoch 1/3
2104/2104 [==============================] - 9s 4ms/step - loss: 0.6725 - accuracy: 0.5775
Epoch 2/3
2104/2104 [==============================] - 7s 3ms/step - loss: 0.5202 - accuracy: 0.7484
Epoch 3/3
2104/2104 [==============================] - 7s 3ms/step - loss: 0.4149 - accuracy: 0.8130

トレーニングハイパーパラメータを調整する

モデルの精度に影響を与えるepochsbatch_sizeなどのトレーニングハイパーパラメータを調整することもできます。例えば、

  • epochs :エポックが多いほど精度が向上する可能性がありますが、過剰適合につながる可能性があります。
  • batch_size :1つのトレーニングステップで使用するサンプルの数。

たとえば、より多くのエポックでトレーニングできます。

model = text_classifier.create(new_train_data, model_spec=new_model_spec, epochs=20)
Epoch 1/20
2104/2104 [==============================] - 8s 3ms/step - loss: 0.6646 - accuracy: 0.5916
Epoch 2/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.4966 - accuracy: 0.7625
Epoch 3/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.4063 - accuracy: 0.8183
Epoch 4/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3713 - accuracy: 0.8380
Epoch 5/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3530 - accuracy: 0.8508
Epoch 6/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3409 - accuracy: 0.8565
Epoch 7/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3305 - accuracy: 0.8611
Epoch 8/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3240 - accuracy: 0.8663
Epoch 9/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3186 - accuracy: 0.8677
Epoch 10/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3137 - accuracy: 0.8701
Epoch 11/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3100 - accuracy: 0.8725
Epoch 12/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3071 - accuracy: 0.8732
Epoch 13/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3041 - accuracy: 0.8740
Epoch 14/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.3013 - accuracy: 0.8767
Epoch 15/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.2999 - accuracy: 0.8772
Epoch 16/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.2976 - accuracy: 0.8772
Epoch 17/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.2963 - accuracy: 0.8797
Epoch 18/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.2942 - accuracy: 0.8806
Epoch 19/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.2927 - accuracy: 0.8807
Epoch 20/20
2104/2104 [==============================] - 7s 3ms/step - loss: 0.2900 - accuracy: 0.8818

20のトレーニングエポックで新しく再トレーニングされたモデルを評価します。

new_test_data = DataLoader.from_csv(
      filename='dev.csv',
      text_column='sentence',
      label_column='label',
      model_spec=new_model_spec,
      is_training=False)

loss, accuracy = model.evaluate(new_test_data)
28/28 [==============================] - 0s 2ms/step - loss: 0.4985 - accuracy: 0.8326

モデルアーキテクチャを変更する

model_spec変更することにより、モデルを変更model_specます。以下にBERT-Baseモデルへの変更方法を示します。

model_specをテキスト分類子のBERT-Baseモデルに変更します。

spec = model_spec.get('bert_classifier')

残りの手順は同じです。

TensorFlowLiteモデルでトレーニング後の量子化をカスタマイズする

トレーニング後の量子化は、モデルの精度を少し低下させながら、CPUとハードウェアアクセラレータの推論速度を向上させながら、モデルのサイズと推論の待ち時間を短縮できる変換手法です。したがって、モデルを最適化するために広く使用されています。

モデルメーカーライブラリは、モデルをエクスポートするときに、デフォルトのトレーニング後の量子化手法を適用します。トレーニング後の量子化をカスタマイズする場合、Model Makerは、 QuantizationConfigを使用した複数のトレーニング後の量子化オプションもサポートしています。たとえば、float16量子化を取り上げましょう。まず、量子化構成を定義します。

config = QuantizationConfig.for_float16()

次に、そのような構成でTensorFlowLiteモデルをエクスポートします。

model.export(export_dir='.', tflite_filename='model_fp16.tflite', quantization_config=config)

続きを読む

テキスト分類の例を読んで、技術的な詳細を学ぶことができます。詳細については、以下を参照してください。