HuggingFace Transformers 4.17 : ガイド : 下流タスク用の再調整 – テキスト分類 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/27/2022 (v4.17.0)
* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
HuggingFace Transformers : ガイド : 下流タスク用の再調整 – テキスト分類
テキスト分類はラベルやクラスをテキストに割り当てる一般的な NLP タスクです。今日の最大手の企業の幾つかにより製品で広く使用されるテキスト分類の多くの実践的なアプリケーションがあります。テキスト分類の最もポピュラーな形式の一つはセンチメント分析です、これはテキストのシークエンスにポジティブ、ネガティブやニュートラルのようなラベルを割当てます。
このガイドは、映画レビューがポジティブかネガティブかを決定するために IMDb データセット上で DistilBERT を再調整する方法を示します。
Note : テキスト分類の他の形式と関連するモデル, データセット, そしてメトリックスについての詳細はテキスト分類 タスクのページ を見てください。
IMDb データセットのロード
Datasets ライブラリから IMDb データセットをロードします :
from datasets import load_dataset
imdb = load_dataset("imdb")
そしてサンプルを見ます :
imdb["test"][0]
{ "label": 0, "text": "I love sci-fi and am willing to put up with a lot. Sci-fi movies/TV are usually underfunded, under-appreciated and misunderstood. I tried to like this, I really did, but it is to good TV sci-fi as Babylon 5 is to Star Trek (the original). Silly prosthetics, cheap cardboard sets, stilted dialogues, CG that doesn't match the background, and painfully one-dimensional characters cannot be overcome with a 'sci-fi' setting. (I'm sure there are those of you out there who think Babylon 5 is good sci-fi TV. It's not. It's clichéd and uninspiring.) While US viewers might like emotion and character development, sci-fi is a genre that does not take itself seriously (cf. Star Trek). It may treat important issues, yet not as a serious philosophy. It's really difficult to care about the characters here as they are not simply foolish, just missing a spark of life. Their actions and reactions are wooden and predictable, often painful to watch. The makers of Earth KNOW it's rubbish as they have to always say \"Gene Roddenberry's Earth...\" otherwise people would not continue watching. Roddenberry's ashes must be turning in their orbit as this dull, cheap, poorly edited (watching it without advert breaks really brings this home) trudging Trabant of a show lumbers into space. Spoiler. So, kill off a main character. And then bring him back as another actor. Jeeez! Dallas all over again.", }
このデータセットには 2 つのフィールドがあります :
- text : 映画レビューのテキストを含む文字列。
- label : ネガティブなレビューのための 0、あるいはポジティブなレビューのための 1 のいずれかであり得る値。
前処理
text フィールドを処理するために DistilBERT トークナイザーをロードします :
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
テキストをトークン化し、シークエンスが DistilBERT の最大入力長よりも長くならないように切り詰める前処理関数を作成します :
def preprocess_function(examples):
return tokenizer(examples["text"], truncation=True)
データセット全体に対して前処理関数を適用するために Datasets map 関数を使用します。データセットの複数の要素を一度に処理する batched=True を設定することにより map 関数を高速化できます :
tokenized_imdb = imdb.map(preprocess_function, batched=True)
サンプルのバッチを作成するために DataCollatorWithPadding を使用します。それはまたバッチ内の最長要素の長さにテキストを動的にパディングしますので、それらは均一な長さです。padding=True を設定することでトークナイザーの関数でテキストをパディングすることも可能ですが、動的パディングはより効率的です。
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf")
Trainer で再調整
想定されるラベル数と共に AutoModelForSequenceClassification で DistilBERT をロードします :
from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer
model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased", num_labels=2)
Note : Trainer によるモデルの再調整に馴染みがない場合は、ここ の基本的なチュートリアルを見てください!
この時点で、3 つのステップだけが残っています :
- TrainingArguments で訓練ハイパーパラメータを定義します。
- モデル, データセット, トークナイザー, そしてデータ collator と共に訓練引数を Trainer に渡します。
- モデルを再調整するために train() を呼び出します。
training_args = TrainingArguments(
output_dir="./results",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=5,
weight_decay=0.01,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_imdb["train"],
eval_dataset=tokenized_imdb["test"],
tokenizer=tokenizer,
data_collator=data_collator,
)
trainer.train()
Note : Trainer はトークナイザーをそれに渡すときデフォルトでは動的パディングを適用します。この場合、データ collator を明示的に指定する必要はありません。
TensorFlow による再調整
TensorFlow でモデルを再調整することは、幾つかの違いはありますが、同様に簡単です。
データセットを to_tf_dataset で tf.data.Dataset 形式に変換します。columns で入力とラベルを、データセット順序をシャッフルするか否か、バッチサイズ、そしてデータ collator を指定します :
tf_train_dataset = tokenized_imdb["train"].to_tf_dataset(
columns=["attention_mask", "input_ids", "label"],
shuffle=True,
batch_size=16,
collate_fn=data_collator,
)
tf_validation_dataset = tokenized_imdb["train"].to_tf_dataset(
columns=["attention_mask", "input_ids", "label"],
shuffle=False,
batch_size=16,
collate_fn=data_collator,
)
optimizer 関数, 学習率スケジュール, そして幾つかの訓練ハイパーパラメータをセットアップします :
from transformers import create_optimizer
import tensorflow as tf
batch_size = 16
num_epochs = 5
batches_per_epoch = len(tokenized_imdb["train"]) // batch_size
total_train_steps = int(batches_per_epoch * num_epochs)
optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps)
想定されるラベル数と共に TFAutoModelForSequenceClassification で DistilBERT をロードします :
from transformers import TFAutoModelForSequenceClassification
model = TFAutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased", num_labels=2)
compile で訓練のためにモデルを configure します :
import tensorflow as tf
model.compile(optimizer=optimizer)
モデルを再調整するために fit を呼び出します :
model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3)
Note : テキスト分類のためにモデルを再調整する方法の詳細なサンプルについては、対応する PyTorch ノートブック か TensorFlow ノートブック を見てください。
以上