Transformer: Training and fine-tuning(六)
Transformer: Training and fine-tuning(六)
語譯分西?2020-12-09 19:43:43??73??收藏?1
分類專欄:?文本挖掘,情感分類
?
文章目錄
- 1.Fine-tuning in native本地 PyTorch
-
- 1.1 Freezing the encoder 凍結(jié)編碼器
- 2.在tensorflow上微調(diào)
- 3.Trainer
?
1.Fine-tuning in native本地 PyTorch
模型類model class不是以TF開頭的都是以Pytorch來運(yùn)行的。
接下來考慮微調(diào)fine-tune一個BERT模型來做句子分類任務(wù)。當(dāng)我們使用from_pretrained()實(shí)例化一個模型時,所指定模型的配置configuration 和預(yù)訓(xùn)練的權(quán)重會被用于初始化模型,這個庫library也會包含一些指定任務(wù)(task-specific)的最后一層final layer或者頭head。當(dāng)final layers 和head 沒有出現(xiàn)在指定的預(yù)訓(xùn)練模型中時,會隨機(jī)分配權(quán)重給它們。
舉例:實(shí)例化一個模型,用的是
BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
就會創(chuàng)建一個實(shí)例,這個實(shí)例會帶有來自bert-base-uncased?模型的encoder weights,編碼權(quán)重。并且隨機(jī)初始化句子分類頭(sequence classification head)在encoder上,output size是2。
模型是默認(rèn)在eval模式下進(jìn)行初始化的。我們可以用model.train()?來將其放進(jìn)訓(xùn)練模式中(to put it in train mode)
- 1
- 2
- 3
這是有用的,因?yàn)檫@允許我們利用預(yù)訓(xùn)練的BERT編碼器(encoder),簡單地在任何我們選擇的分類數(shù)據(jù)集上進(jìn)行訓(xùn)練。我們可以用任何Pytorch的優(yōu)化器optimizer。同時我們也提供了AdamW()優(yōu)化器,其實(shí)現(xiàn)梯度偏差校正以及權(quán)重衰減。
from transformers import AdamW optimizer = AdamW(model.parameters(), lr=1e-5)- 1
- 2
優(yōu)化器允許我們?yōu)樘囟ǖ膮?shù)組應(yīng)用不同的超參數(shù)。 例如,我們可以將權(quán)重衰減應(yīng)用于除bias和layer歸一化以外的所有參數(shù):
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)- 1
- 2
- 3
- 4
- 5
- 6
接下來我們可以設(shè)置一個極其簡單的training batch,使用__call__()?,也就是對其本身進(jìn)行調(diào)用。返回BatchEncoding()實(shí)例,這個實(shí)例準(zhǔn)備好了任何我們想傳進(jìn)模型的東西。
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']- 1
- 2
- 3
- 4
- 5
- 6
當(dāng)我們召喚一個帶有l(wèi)abels參數(shù)的分類模型,返回的第一個元素就是預(yù)測值和傳進(jìn)去的標(biāo)簽值之間的Cross Entropy loss交叉熵?fù)p失。設(shè)置好我們的優(yōu)化器optimizer后,我們可以就可以做后向傳播并更新權(quán)重了。
labels = torch.tensor([1,0]).unsqueeze(0) outputs = model(input_ids, attention_mask=attention_mask, labels=labels) loss = outputs.loss loss.backward() optimizer.step()- 1
- 2
- 3
- 4
- 5
或者,你可以只獲取logits并計(jì)算自己的損失值,下面的代碼跟上面等價
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()- 1
- 2
- 3
- 4
- 5
- 6
當(dāng)然,可以通過召喚to('cuda')來用GPU訓(xùn)練
我們還提供了一些學(xué)習(xí)率的調(diào)節(jié)工具。 通過以下內(nèi)容,我們可以設(shè)置一個調(diào)節(jié)程序,該調(diào)節(jié)程序?yàn)閚um_warmup_steps預(yù)熱,然后在訓(xùn)練結(jié)束前線性衰減為0。
from transformers import get_linear_schedule_with_warmup scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_train_steps)- 1
- 2
然后只要在optimizer.step()之后召喚scheduler.step()
loss.backward() optimizer.step() scheduler.step()- 1
- 2
- 3
我們強(qiáng)烈推薦使用**Trainer()**會在下面討論,很方便的訓(xùn)練Transformer模型,
1.1 Freezing the encoder 凍結(jié)編碼器
在有些情況下,你需要保持預(yù)訓(xùn)練編碼器的權(quán)重凍結(jié),只對head layers的權(quán)重進(jìn)行優(yōu)化,要這么做的話,只需要在encoder 參數(shù)上設(shè)置requires_grad?為 False,這樣就可以使庫中任何task-specific model上的base_model子模塊來訪問它:
for param in model.base_model.parameters():param.requires_grad = False- 1
- 2
2.在tensorflow上微調(diào)
略
3.Trainer
我們也提供了簡單,但功能完善的訓(xùn)練和評估接口:Trainer()?和?TFTrainer(),你可以用于訓(xùn)練,微調(diào),評估任何Transformer模型,有這非常多的訓(xùn)練options可供選擇,還有許多內(nèi)建的屬性比如?logging, gradient accumulation, and mixed precision.
from transformers import BertForSequenceClassification, Trainer, TrainingArgumentsmodel = BertForSequenceClassification.from_pretrained("bert-large-uncased")training_args = TrainingArguments(output_dir='./results', # output directorynum_train_epochs=3, # total # of training epochsper_device_train_batch_size=16, # batch size per device during trainingper_device_eval_batch_size=64, # batch size for evaluationwarmup_steps=500, # number of warmup steps for learning rate schedulerweight_decay=0.01, # strength of weight decaylogging_dir='./logs', # directory for storing logs )trainer = Trainer(model=model, # the instantiated 🤗 Transformers model to be trainedargs=training_args, # training arguments, defined abovetrain_dataset=train_dataset, # training dataseteval_dataset=test_dataset # evaluation dataset )- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
接下來,簡單的使用trainer.train()?來訓(xùn)練,使用?trainer.evaluate()?來評估,你也可以是用你自己的模塊,但是第一個從forward返回的參數(shù)必須是損失值,這個損失值是用來優(yōu)化的
Trainer()使用的是內(nèi)建的函數(shù)來收集batches并準(zhǔn)備好將它們傳進(jìn)模型中,如果需要,也可以使用data_collator參數(shù)來傳你自己的collator function(校對函數(shù)),這個校對函數(shù)傳進(jìn)以你提供的數(shù)據(jù)集的格式的數(shù)據(jù),返回可以傳進(jìn)模型的batch。
要計(jì)算除損失之外的其他指標(biāo),您還可以定義自己的compute_metrics函數(shù)并將其傳遞給Trainer。
from sklearn.metrics import accuracy_score, precision_recall_fscore_supportdef compute_metrics(pred):labels = pred.label_idspreds = 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}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
最后,您可以通過在指定的logging_dir目錄中啟動tensorboard來查看結(jié)果,包括所有計(jì)算的指標(biāo)。、
一個輕量化的colab demo,展示IMDb電影情感分析,使用的Trainer,鏈接
from transformers import BertForSequenceClassification, BertTokenizerFast, Trainer, TrainingArguments from nlp import load_dataset import torch import numpy as np from sklearn.metrics import accuracy_score, precision_recall_fscore_support- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 1
總結(jié)
以上是生活随笔為你收集整理的Transformer: Training and fine-tuning(六)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调用预训练好的XLnet词向量
- 下一篇: PyTorch环境下对BERT进行Fin