
bert下游_原來你是這樣的BERT,i了i了!——超詳細(xì)BERT介
紹(三)BERT下游任務(wù)...
原來你是這樣的BERT,i了i了! —— 超詳細(xì)BERT介紹(三)BERT下游任務(wù)
BERT(Bidirectional Encoder Reprentations from Transformers)是?歌在2018年10?推出的深度語?表?模型。
?經(jīng)推出便席卷整個(gè)NLP領(lǐng)域,帶來了?命性的進(jìn)步。
從此,?數(shù)英雄好漢競相投?于這場追劇(芝?街)運(yùn)動(dòng)。
只聽得這邊G家110億,那邊M家?1750億,真是好不熱鬧!
然??家真的了解BERT的具體構(gòu)造,以及使?細(xì)節(jié)嗎?
本?就帶?家來細(xì)品?下。
前?
本系列?章分成三篇介紹BERT,上兩篇分別介紹了BERT主模型的結(jié)構(gòu)及其組件相關(guān)和BERT預(yù)訓(xùn)練相關(guān),這?篇是最終話,介紹如何將
BERT應(yīng)?到不同的下游任務(wù)。
?章中的?些縮寫:NLP(natural language processing)?然語?處理;CV(computer vision)計(jì)算機(jī)視覺;DL(deep learning)深度學(xué)
習(xí);NLP&DL ?然語?處理和深度學(xué)習(xí)的交叉領(lǐng)域;CV&DL 計(jì)算機(jī)視覺和深度學(xué)習(xí)的交叉領(lǐng)域。
?章公式中的向量均為?向量,矩陣或張量的形狀均按照PyTorch的?式描述。
向量、矩陣或張量后的括號表?其形狀。
本系列?章的代碼均是基于transformers庫(v2.11.0)的代碼(基于Python語?、PyTorch框架)。
為便于理解,簡化了原代碼中不必要的部分,并保持主要功能等價(jià)。
閱讀本系列?章需要?些背景知識,包括Word2Vec、LSTM、Transformer-Ba、ELMo、GPT等,由于本?不想過于冗長(其實(shí)是
懶),以及相信來看本?的讀者們也都是沖著BERT來的,所以這部分內(nèi)容還請讀者們??學(xué)習(xí)。
本?假設(shè)讀者們均已有相關(guān)背景知識。
?錄
序列分類任務(wù)就是輸??個(gè)序列,輸出整個(gè)序列的標(biāo)簽。
輸?的序列可以是單句也可以是雙句。
單句序列分類任務(wù)就是?本分類(text classification)任務(wù),包括主題(topic)、情感(ntiment)、垃圾郵件(spam)等的分類任務(wù);雙句序
列分類任務(wù)包括相似度(similarity)、釋義(paraphra)、蘊(yùn)含(entailment)等的分類任務(wù)。
根據(jù)標(biāo)簽數(shù)量分,可以分成單標(biāo)簽和多標(biāo)簽(multi-label)的分類任務(wù)。
根據(jù)標(biāo)簽的類別數(shù)量分,可以分成?分類或三分類、五分類等多分類任務(wù)。
BERT中的序列分類任務(wù)包括單句和雙句的單標(biāo)簽回歸或分類任務(wù),涉及到語?可接受性(linguistic acceptability)、情感、相似度、釋義、
蘊(yùn)含等特征的分類,即GLUE(General Language Understanding Evaluation)中的任務(wù)。
如下為?個(gè)相似度回歸任務(wù)的例?(來?transformers庫的?例):
5.000A plane is taking off. ||| An air plane is taking off.
3.800A man is playing a large flute. ||| A man is playing a flute.
3.800A man is spreading shreded chee on a pizza. ||| A man is spreading shredded chee on an uncooked pizza.
其中,最左邊的是標(biāo)簽,表?兩句話的相似度分?jǐn)?shù),分?jǐn)?shù)越?,相似度越?,分?jǐn)?shù)的取值范圍是([0, 5])。
再如下為?個(gè)雙句釋義?分類任務(wù)的例?(來?transformers庫的?例):
1He said the foodrvice pie business ... ||| The foodrvice pie business ...
0Magnarelli said Racicot hated ... ||| His wife said he was ...
0The dollar was at 116.92 yen against the yen ... ||| The dollar was at 116.78 yen JPY ...
其中,最左邊的是標(biāo)簽,如果后句是前句的釋義,即解釋說明,那么標(biāo)簽為1,否則為0。
序列分類代碼如下:
代碼
# BERT之序列分類
class BertForSeqCls(BertPreTrainedModel):
def __init__(lf, config):
super().__init__(config)
= config
# 標(biāo)簽的類別數(shù)量
_labels = _labels
# 主模型
= BertModel(config)
t = t(_dropout_prob)
# 線性回歸或分類器
= (_size, _labels)
# 回歸或分類損失函數(shù)
_fct = LossRgrsCls(_labels)
_weights()
def forward(lf,
tok_ids, # 標(biāo)記編碼(batch_size * q_length)
pos_ids=None, # 位置編碼(batch_size * q_length)
nt_pos_ids=None, # 句?位置編碼(batch_size * q_length)
att_masks=None, # 注意?掩碼(batch_size * q_length)
labels=None, # 標(biāo)簽(batch_size)
):
_, pooled_outputs = (
tok_ids,
pos_ids=pos_ids,
nt_pos_ids=nt_pos_ids,
att_masks=att_masks,
)
pooled_outputs = t(pooled_outputs)
logits = (pooled_outputs)
if labels is None:
return logits # 對數(shù)?率(batch_size * num_labels)
loss = _fct(logits, labels)
return loss
其中,
num_labels是標(biāo)簽的類別數(shù)量(注意:并不是標(biāo)簽數(shù)量,BERT的序列分類任務(wù)均為單標(biāo)簽分類任務(wù)),=1時(shí)為回歸任務(wù)。
標(biāo)記分類任務(wù)就是輸??個(gè)序列,輸出序列中每個(gè)標(biāo)記的標(biāo)簽。
輸?的序列?般是單句。
標(biāo)記分類任務(wù)就是序列標(biāo)注(quence tagging)任務(wù),包括中?分詞(Chine word gmentation)、詞性標(biāo)注(Part-of-Speech
tagging,POS tagging)、命名實(shí)體識別(named entity recognition,NER)等。
序列標(biāo)注任務(wù)常規(guī)的做法是BIO標(biāo)注,B表?需要標(biāo)注的?段的開頭標(biāo)記,I表??開頭標(biāo)記,O表?不需要標(biāo)注的標(biāo)記。
如下為?個(gè)NER任務(wù)的例?(來?transformers庫的?例):
例?
Schartau B-PER
sagte O
dem O
" O
Tagesspiegel B-ORG
" O
vom O
Freitag O
, O
Fischer B-PER
i O
" O
in O
einer O
Wei O
aufgetreten O
, O
die O
alles O
andere O
als O
überzeugend O
war O
" O
. O
Firmengründer O
Wolf B-PER
Peter I-PER
Bree I-PER
arbeitete O
Anfang O
der O
siebziger O
Jahre O
als O
M?belvertreter O
, O
als O
er O
einen O
fliegenden O
H?ndler O
aus O
dem O
Libanon B-LOC
traf O
. O
Ob O
sie O
dabei O
nach O
dem O
Runden O
Tisch O
am O
23. O
April O
in O
Berlin B-LOC
durch O
ein O
p?dagogisches O
Konzept O
unterstützt O
wird O
, O
ist O
allerdings O
zu O
bezweifeln O
. O
其中,每??為?個(gè)標(biāo)記和其標(biāo)簽,空?分隔不同的句?;PER是?名、ORG是組織名、LOC是地名。
標(biāo)記分類代碼如下:
代碼
# BERT之標(biāo)記分類
class BertForTokCls(BertPreTrainedModel):
def __init__(lf, config):
super().__init__(config)
= config
# 標(biāo)簽的類別數(shù)量
_labels = _labels
# 主模型
= BertModel(config)
t = t(_dropout_prob)
# 線性分類器
= (_size, _labels)
# 分類損失函數(shù)
_fct = LossCls(_labels)
_weights()
def forward(lf,
tok_ids, # 標(biāo)記編碼(batch_size * q_length)
pos_ids=None, # 位置編碼(batch_size * q_length)
nt_pos_ids=None, # 句?位置編碼(batch_size * q_length)
att_masks=None, # 注意?掩碼(batch_size * q_length)
labels=None, # 標(biāo)簽(batch_size * q_length)
):
outputs, _ = (
tok_ids,
pos_ids=pos_ids,
nt_pos_ids=nt_pos_ids,
att_masks=att_masks,
)
outputs = t(outputs)
logits = (outputs)
if labels is None:
return logits # 對數(shù)?率(batch_size * q_length * num_labels)
# 只計(jì)算?填充標(biāo)記的損失
if att_masks is not None:
active = att_(-1)>0
logits = (-1, _labels)[active]
labels = (-1)[active]
loss = _fct(logits, labels)
return loss
BERT中的選擇題是給出前句以及num_choices個(gè)后句,選擇最優(yōu)的后句。
如下(來?SWAG數(shù)據(jù)集):
2
Students lower their eyes nervously. She
pats her shoulder, then saunters toward someone.
turns with two students.
walks slowly towards someone.
wheels around as her dog thunders out.
其中,第??是標(biāo)簽,第??是前句,第三?到最后是四個(gè)后句;標(biāo)簽數(shù)字從0開始計(jì)數(shù),即標(biāo)簽為2表?第三個(gè)(walks slowly towards
someone.)為正確選項(xiàng)。
BERT將每個(gè)樣本轉(zhuǎn)換成num_choices個(gè)雙句:
Students lower their eyes nervously. ||| She pats her shoulder, then saunters toward someone.
Students lower their eyes nervously. ||| She turns with two students.
Students lower their eyes nervously. ||| She walks slowly towards someone.
Students lower their eyes nervously. ||| She wheels around as her dog thunders out.
然后每個(gè)雙句的序列表?產(chǎn)??個(gè)對數(shù)?率,num_choices個(gè)雙句就得到?個(gè)長度為num_choices的對數(shù)?率向量,最后將這個(gè)向量作為
這個(gè)樣本的輸出,計(jì)算損失即可。
選擇題代碼如下:
代碼
# BERT之選擇題
class BertForMultiChoice(BertPreTrainedModel):
def __init__(lf, config):
super().__init__(config)
= config
# 選項(xiàng)個(gè)數(shù)
_choices = _choices
# 主模型
= BertModel(config)
t = t(_dropout_prob)
# 線性分類器
= (_size, 1)
# 分類損失函數(shù)
_fct = LossCls(1)
_weights()
def forward(lf,
tok_ids, # 標(biāo)記編碼(batch_size * num_choices * q_length)
pos_ids=None, # 位置編碼(batch_size * num_choices * q_length)
nt_pos_ids=None, # 句?位置編碼(batch_size * num_choices * q_length)
att_masks=None, # 注意?掩碼(batch_size * num_choices * q_length)
labels=None, # 標(biāo)簽(batch_size)
):
q_length = tok_[-1]
# 調(diào)整形狀,每個(gè)前句-后句選項(xiàng)對看作?個(gè)雙句輸?
tok_ids = tok_(-1, q_length)
if pos_ids is not None: pos_ids = pos_(-1, q_length)
if nt_pos_ids is not None: nt_pos_ids = nt_pos_(-1, q_length)
if att_masks is not None: att_masks = att_(-1, q_length)
_, pooled_outputs = (
tok_ids,
pos_ids=pos_ids,
nt_pos_ids=nt_pos_ids,
att_masks=att_masks,
)
pooled_outputs = t(pooled_outputs)
logits = (pooled_outputs)
# 調(diào)整形狀,每num_choices個(gè)對數(shù)?率看作?個(gè)樣本的輸出
logits = (-1, _choices)
if labels is None:
return logits # 對數(shù)?率(batch_size * num_choices)
loss = _fct(logits, labels)
return loss
其中,
num_choices是選項(xiàng)個(gè)數(shù)。
BERT中的問答任務(wù)其實(shí)是抽取式的機(jī)器閱讀理解(machine reading comprehension)任務(wù),即給定?段話,給定?個(gè)問題,問題的答案
來?這段話的某個(gè)連續(xù)的?段。
如下(來?transformers庫的?例):
0Computational complexity theory
What branch of theoretical computer science deals with broadly classifying computational problems by difficulty and class
of relationship?
Computational complexity theory is a branch of the theory of computation in theoretical computer science that focus on
classifying computational problems according to their inherent difficulty ...
其中,第??是答案,答案左邊的數(shù)字表?這個(gè)答案在給定的這段話的起始位置(從0開始計(jì)數(shù)),第??是問題,第三?是給定的?段話。
BERT將這個(gè)抽取式任務(wù)轉(zhuǎn)化為?個(gè)預(yù)測答案起始和結(jié)束位置的分類任務(wù),標(biāo)簽的類別數(shù)量是q_length,起始位置和結(jié)束位置分別預(yù)測,
即相當(dāng)于兩個(gè)標(biāo)簽。
注意:這個(gè)起始和結(jié)束位置是標(biāo)記化等預(yù)處理后答案在輸?的編碼向量?的位置。
BERT將所有的標(biāo)記表?轉(zhuǎn)化成兩個(gè)對數(shù)?率,然后橫向切?,得到兩個(gè)長度為q_length的對數(shù)?率向量,分別作為起始和結(jié)束位置的預(yù)
測,最后計(jì)算損失即可。
問答代碼如下:
代碼
# BERT之問答
class BertForQustAns(BertPreTrainedModel):
def __init__(lf, config):
super().__init__(config)
= config
# 主模型
= BertModel(config)
# 線性分類器
= (_size, 2)
_weights()
def forward(lf,
tok_ids, # 標(biāo)記編碼(batch_size * q_length)
pos_ids=None, # 位置編碼(batch_size * q_length)
nt_pos_ids=None, # 句?位置編碼(batch_size * q_length)
att_masks=None, # 注意?掩碼(batch_size * q_length)
start_pos=None, # 起始位置標(biāo)簽(batch_size)
end_pos=None, # 結(jié)束位置標(biāo)簽(batch_size)
):
q_length = tok_[-1]
outputs, _ = (
tok_ids,
pos_ids=pos_ids,
nt_pos_ids=nt_pos_ids,
att_masks=att_masks,
)
logits = (outputs)
# 拆分起始和結(jié)束位置對數(shù)?率
start_logits, end_logits = (1, dim=-1)
start_logits = start_(-1, q_length)
end_logits = end_(-1, q_length)
if start_pos is None or end_pos is None:
return (
start_logits, # 起始位置對數(shù)?率(batch_size * q_length)
end_logits, # 結(jié)束位置對數(shù)?率(batch_size * q_length)
)
# 標(biāo)簽值裁剪,使值 (- [0, q_length],
# 其中合法值 (- [0, q_length-1],?法值 = q_length
start_pos = start_(0, q_length)
end_pos = end_(0, q_length)
# ignore_index=q_length:忽略標(biāo)簽值 = q_length對應(yīng)的損失
loss_fct = LossCls(q_length, ignore_index=q_length)
start_loss = loss_fct(start_logits, start_pos)
end_loss = loss_fct(end_logits, end_pos)
loss = (start_loss + end_loss) / 2
return loss
后記
本?作為系列的最后?篇?章,詳細(xì)地介紹了BERT下游任務(wù),BERT的通?性就體現(xiàn)在只需要添加少量模塊就能應(yīng)?到各種不同的下游任
務(wù)。
BERT充分地利?了主模型輸出的標(biāo)記表?和序列表?,并對其進(jìn)??定地修改,從?可以應(yīng)?到各種不同的下游任務(wù)中。
其中應(yīng)?到選擇題和問答任務(wù)的?式特別巧妙,分別活?了序列和標(biāo)記表?。
然?,如同預(yù)訓(xùn)練,標(biāo)記分類任務(wù)每個(gè)標(biāo)記的標(biāo)簽是獨(dú)?產(chǎn)?的,以及問答任務(wù)的起始和結(jié)束位置也是獨(dú)?產(chǎn)?的,這其實(shí)不是?常合理。

本文發(fā)布于:2023-05-22 19:17:02,感謝您對本站的認(rèn)可!
本文鏈接:http://m.newhan.cn/zhishi/a/1684754223174020.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:bert下游_原來你是這樣的BERT,i了i了!——超詳細(xì)BERT介紹(三)BERT下游任務(wù)....doc
本文 PDF 下載地址:bert下游_原來你是這樣的BERT,i了i了!——超詳細(xì)BERT介紹(三)BERT下游任務(wù)....pdf
| 留言與評論(共有 0 條評論) |