ホーム » Transformer » HuggingFace Transformers 3.4 : 訓練と再調整

HuggingFace Transformers 3.4 : 訓練と再調整

HuggingFace Transformers 3.4 : 訓練と再調整 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 11/22/2020 (3.4.0)

* 本ページは、HuggingFace Transformers の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

HuggingFace Transformers : 訓練と再調整

Transformers のモデルクラスは native PyTorch と TensorFlow 2 と互換であるように設計されそしていずれと共にシームレスに利用可能です。このクイックスタートでは、いずれのフレームワークでも利用可能な標準訓練ツールを使用してモデルをどのように再調整するか (or スクラッチから訓練するか) を示します。含まれる Trainer() クラスをどのように使用するかも示します、これは訓練の複雑さの大半を貴方のために処理します。

このガイドは推論のためにモデルをロードして使用することに既に馴染みがあることを仮定します : そうでないなら タスクの概要 を見てください。貴方が PyTorch か TF2 のいずれかの深層ニューラルネットワークの訓練に馴染みがあることも仮定し、 Transformers の訓練のためのニュアンスとツールに特にフォーカスします。

 

native PyTorch で再調整する

TF で始まらない Transformers のモデルクラスは PyTorch モジュールで、これは推論と最適化の両者のために丁度 PyTorch の任意のモデルのようにそれらを利用できることを意味します。

シークエンス分類データセット上で BERT のようなマスク付き言語モデルを再調整する一般的なタスクを考えましょう。モデルを from_pretrained() でインスタンス化するとき、モデルを初期化するために指定されたモデルのモデル configuration と事前訓練重みが使用されます。ライブラリはまた幾つかのタスク固有の最終層や「ヘッド」も含みます、それらの重みは指定された事前訓練モデルに存在しないときランダムにインスタンス化されます。例えば、BertForSequenceClassification.from_pretrained(‘bert-base-uncased’, num_labels=2) によるモデルのインスタンス化は bert-base-uncased モデルからコピーされたエンコーダ重みとエンコーダの上に 2 の出力サイズを持つランダムに初期化されたシークエンス分類ヘッドで BERT モデルインスタンスを作成します。モデルはデフォルトでは eval モードで初期化されます。それを train モードに置くために model.train() を呼び出すことができます。

from transformers import BertForSequenceClassification
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', return_dict=True)
model.train()

これは有用です、何故ならばそれは事前訓練された BERT エンコーダを利用してそれを選択するどのようなシークエンス分類データセットの上でも容易に訓練することを許容するからです。任意の PyTorch optimizer を利用できますが、ライブラリはまた AdamW() optimizer も提供します、これは重み減衰に加えて勾配バイアス補正 (= gradient bias correction) を実装しています。

from transformers import AdamW
optimizer = AdamW(model.parameters(), lr=1e-5)

optimizer は特定のパラメータグループのために異なるハイパーパラメータを適用することを許容します。例えば、重み減衰をバイアスと層正規化項以外の総てのパラメータに適用できます :

no_decay = ['bias', 'LayerNorm.weight']
optimizer_grouped_parameters = [
    {'params': [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01},
    {'params': [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}
]
optimizer = AdamW(optimizer_grouped_parameters, lr=1e-5)

今では __call__() を使用して単純なダミー訓練バッチをセットアップすることができます。これは BatchEncoding() インスタンスを返します、これはモデルに渡す必要があるかもしれない総てを準備します。

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
text_batch = ["I love Pixar.", "I don't care for Pixar."]
encoding = tokenizer(text_batch, return_tensors='pt', padding=True, truncation=True)
input_ids = encoding['input_ids']
attention_mask = encoding['attention_mask']

分類モデルを labels 引数で呼び出すとき、最初の返される要素は予測と渡されたラベルの間んほ交差エントロピーです。optimizer を既にセットアップしていますので、それから backwards を行ない重みを更新することができます :

labels = torch.tensor([1,0]).unsqueeze(0)
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
loss = outputs.loss
loss.backward()
optimizer.step()

代わりに、単にロジットを得て損失を貴方自身で計算することもできます。次は前のサンプルと同値です :

from torch.nn import functional as F
labels = torch.tensor([1,0])
outputs = model(input_ids, attention_mask=attention_mask)
loss = F.cross_entropy(outputs.logits, labels)
loss.backward()
optimizer.step()

もちろん、通常のようにモデルと入力上で to(‘cuda’) を呼び出して GPU 上で訓練することができます。

2, 3 の学習率スケジューリング・ツールも提供します。以下によって、スケジューラのセットアップができます、これは num_warmup_steps の間ウォームアップしてから訓練の終わりまでに 0 に線形に減衰します。

from transformers import get_linear_schedule_with_warmup
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_train_steps)

それから行なわなければならないことの総ては optimizer.step() の後で scheduler.step() を呼び出すことです。

loss.backward()
optimizer.step()
scheduler.step()

下で議論されるように、Trainer() を使用することを強く勧めます、これは混合精度と容易な tensorboard ロギングのような特徴とともに Transformers モデルを訓練する可動部を便利に処理します。

 

エンコーダを凍結する

ある場合には、事前訓練されたエンコーダの重みを凍結し続けてヘッド層の重みだけを最適化することに関心があるかもしれません。そのためには、エンコーダ・パラメータ上で単純に requires_grad 属性を False に設定します、これはライブラリの任意のタスク固有モデル上 base_model サブモジュールでアクセスできます :

for param in model.base_model.parameters():
    param.requires_grad = False

 

native TensorFlow 2 で再調整する

モデルはまた TensorFlow 2 でもネイティブに訓練できます。ちょうど PyTorch でのように、TensorFlow モデルはエンコーダの重みをロードするために from_pretrained() でインスタンス化できます。

from transformers import TFBertForSequenceClassification
model = TFBertForSequenceClassification.from_pretrained('bert-base-uncased')

GLUE からの MRPC データセット をロードするために tensorflow_datasets を使用しましょう。それから MRPC をトークン化してそれを TensorFlow Dataset オブジェクトに変換するために組込み glue_convert_examples_to_features() を利用できます。tokenizer はフレームワーク不可知ですので、事前訓練された tokenizer 名に TF を先頭に追加する必要はありません。

from transformers import BertTokenizer, glue_convert_examples_to_features
import tensorflow as tf
import tensorflow_datasets as tfds
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
data = tfds.load('glue/mrpc')
train_dataset = glue_convert_examples_to_features(data['train'], tokenizer, max_length=128, task='mrpc')
train_dataset = train_dataset.shuffle(100).batch(32).repeat(2)

そしてモデルは任意の Keras モデルとしてコンパイルされて訓練できます :

optimizer = tf.keras.optimizers.Adam(learning_rate=3e-5)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer=optimizer, loss=loss)
model.fit(train_dataset, epochs=2, steps_per_epoch=115)

TensorFlow と PyTorch モデル間の緊密な相互運用性により、モデルをセーブしてからそれを PyTorch モデルとして再ロードすることさえできます (or vice-versa) :

from transformers import BertForSequenceClassification
model.save_pretrained('./my_mrpc_model/')
pytorch_model = BertForSequenceClassification.from_pretrained('./my_mrpc_model/', from_tf=True)

 

Trainer

Trainer()TFTrainer() を通して単純ですが feature-complete な訓練と評価インターフェイスもまた提供します。広範囲の訓練オプションとロギング、勾配集積 (= accumulation) と混合精度のような組込み特徴で任意の Transformers モデルを訓練し、再調整し、そして評価することができます。

TensorFlow

from transformers import TFBertForSequenceClassification, TFTrainer, TFTrainingArguments

model = TFBertForSequenceClassification.from_pretrained("bert-large-uncased")

training_args = TFTrainingArguments(
    output_dir='./results',          # output directory
    num_train_epochs=3,              # total # of training epochs
    per_device_train_batch_size=16,  # batch size per device during training
    per_device_eval_batch_size=64,   # batch size for evaluation
    warmup_steps=500,                # number of warmup steps for learning rate scheduler
    weight_decay=0.01,               # strength of weight decay
    logging_dir='./logs',            # directory for storing logs
)

trainer = TFTrainer(
    model=model,                         # the instantiated 🤗 Transformers model to be trained
    args=training_args,                  # training arguments, defined above
    train_dataset=tfds_train_dataset,    # tensorflow_datasets training dataset
    eval_dataset=tfds_test_dataset       # tensorflow_datasets evaluation dataset
)

PyTorch

from transformers import BertForSequenceClassification, Trainer, TrainingArguments

model = BertForSequenceClassification.from_pretrained("bert-large-uncased")

training_args = TrainingArguments(
    output_dir='./results',          # output directory
    num_train_epochs=3,              # total # of training epochs
    per_device_train_batch_size=16,  # batch size per device during training
    per_device_eval_batch_size=64,   # batch size for evaluation
    warmup_steps=500,                # number of warmup steps for learning rate scheduler
    weight_decay=0.01,               # strength of weight decay
    logging_dir='./logs',            # directory for storing logs
)

trainer = Trainer(
    model=model,                         # the instantiated 🤗 Transformers model to be trained
    args=training_args,                  # training arguments, defined above
    train_dataset=train_dataset,         # training dataset
    eval_dataset=test_dataset            # evaluation dataset
)

今では単純に訓練するために trainer.train() をそして評価するために trainer.evaluate() を呼び出します。貴方自身のモジュールもまた使用できますが、forward から返される最初の引数は最適化することを望む損失でなければなりません。

Trainer() はバッチを順番に並べてそれらをモデルに供給されるように準備するために組込みのデフォルト関数を使用します。必要であれば、貴方自身の collator 関数を渡すために data_collator 引数も使用できます、これは貴方のデータセットにより提供される形式のデータを取りそしてモデルに供給される準備ができたバッチを返します。TFTrainer は渡されたデータセットが tensorflow_datasets からのデータセット・オブジェクトであることを想定していることに注意してください。

損失に加えて追加のメトリクスを計算するために、貴方自身の compute_metrics 関数も定義してそれを Trainer に渡すこともできます。

from sklearn.metrics import accuracy_score, precision_recall_fscore_support

def compute_metrics(pred):
    labels = pred.label_ids
    preds = pred.predictions.argmax(-1)
    precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average='binary')
    acc = accuracy_score(labels, preds)
    return {
        'accuracy': acc,
        'f1': f1,
        'precision': precision,
        'recall': recall
    }

最後に、指定された logging_dir ディレクトリで tensorboard を起動することにより任意の計算されたメトリクスを含む結果を見ることができます。

 

追加リソース

  • 軽量 colab デモ、これは IMDb センチメント分類のために Trainer を使用します。
  • Transformers サンプル、これは GLUE, SQuAD と幾つかの他のタスク上の訓練と再調整のためのスクリプトを含みます。
  • 言語モデルをどのように訓練するか、詳細な colab ノートブック、これは Esperanto 上でスクラッチからマスク付き言語モデルを訓練するために Trainer を使用します。
  • Transformers ノートブック、これは
    様々のタスク上 Transformers の訓練と利用のためのコミュニティからの数十のサンプル・ノートブックを含みます。
 

以上






AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com