1.BERT整體模型架構(gòu)
-
基礎(chǔ)架構(gòu) - TRM的Encoder部分
image.png
BERT的基礎(chǔ)架構(gòu)是transformer的encoder部分。為什么說是基礎(chǔ)架構(gòu)之剧,因為bert是由多個encoder堆疊而成郭卫,其中bert-base使用的是12層的encoder,bert-large使用的是24層的encoder背稼。
簡單看一下贰军,一共12層的encoder,這里想談一個比較容易混淆的點蟹肘;12個encoder堆疊在一起組成了bert伶跷,而不是12層的transformer堆疊在一起組成了bert(transformer在原論文中應(yīng)該是6個encoder堆疊在一起成了編碼端壳炎,6個decoder堆疊在一起變成了解碼端)。
對于bert 的encoder部分 我們重點是關(guān)注他的輸入部分。對于transformer來說他的輸入部分包括input embedding 和 position encodeing郭怪;注意胖烛,在transformer中我們使用三角函數(shù)(正余弦函數(shù))去代表他临扮。但是在bert中毡咏,我們分為3個部分, 第一部分是token_emb 第二部分是segment emb 第三部分是position emb球化。注意:這里是position embedding 區(qū)別于 transformer的position encoding秽晚。
首先看input這一行,對于這一行我們重點關(guān)注兩個部分:第一部分是正常詞匯筒愚。第二部分是特殊詞匯[cls] [sep] [sep] 是兩種特殊符號赴蝇,這兩種特殊符號的存在都是因為bert的預(yù)訓(xùn)練任務(wù)中有一個任務(wù)是NSP任務(wù),去判斷兩個句子之間的關(guān)系巢掺。因為處理的是兩個句子 所以需要一個符號去告訴模型符號前后是兩個不同的句子扯再。我們要做的NSP任務(wù)又是一個二分類任務(wù),如何去做二分類任務(wù)址遇,作者在句子前面加入CLS的特殊符號,在訓(xùn)練的時候?qū)LS的輸出向量接一個二分類器斋竞。
擴展:CLS的誤解:很多人認為CLS的輸出向量代表的是整個或者整兩個句子的語義信息倔约。個人理解:在預(yù)訓(xùn)練結(jié)束之后,CLS的輸出向量并不能說代表了整個句子的語義信息坝初。CLS這個向量用在NSP這個任務(wù)中是一個二分類任務(wù)浸剩,與編碼的整個句子的語義信息差的遠钾军,所以大家都會發(fā)現(xiàn)一個問題:如果用CLS整個輸出向量去做無監(jiān)督文本相似度任務(wù)的時候效果特別差。
經(jīng)驗:bert pretrain模型直接拿出來做sentence embedding效果甚至不如word embedding,cls的embedding效果最差(也就是你說的pooled output)绢要。把所有普通token embedding做pooling勉強能用(這個也是開源項目bert-as-service的默認做法)吏恭,但也不會比word embedding更好。
token_embedding:就是對所有的input的詞匯進行向量化表示重罪。
segment_embedding:因為我們處理的是兩個句子樱哼,所以我們需要對兩個句子進行區(qū)分。在第一個句子我們?nèi)坑?來表示剿配,后面的句子我們?nèi)坑?表示搅幅。代表兩個句子
position_embeddings:代表的是bert的輸入部分,與transformer的輸入部分有一個很大的不同點呼胚,在transformer中茄唐,用的是正余弦函數(shù),在bert使用的是隨機初始化蝇更,然后讓模型自己去學(xué)習(xí)沪编。比如說第一個位置定位0 第二個位置定位1 直到511。讓模型自己學(xué)習(xí)embedding的向量是什么樣子的年扩。
2.如何做預(yù)訓(xùn)練:MLM + NSP
預(yù)訓(xùn)練的bert主要涉及到兩個任務(wù) 一個是MLM 另一個是NSP蚁廓。
MLM:bert在預(yù)訓(xùn)練的時候使用的是大量的無標注預(yù)料,所以在預(yù)訓(xùn)練任務(wù)設(shè)計的時候一定是要考慮無監(jiān)督來做常遂。對于無監(jiān)督的目標函數(shù)纳令,有兩組目標函數(shù)比較收到重視 AR模型(自回歸模型:只能考慮到單側(cè)信息,典型的就是GPT)克胳、 AE模型(自編碼模型);從損壞的輸入數(shù)據(jù)中重建原始數(shù)據(jù)平绩,可以使用到上下文的信息。BERT使用的就是AE漠另。
AR模型有前后的依賴關(guān)系捏雌,順序過來的,只用到了單側(cè)的信息與之對應(yīng)的笆搓,AE模型是對句子做一個mask性湿,用面具掩蓋句子中的某幾個單詞。mask這個模型满败,他的本質(zhì)是在打破文本原有的信息肤频。讓模型預(yù)訓(xùn)練的時候做文本重建,在文本重建的時候算墨,模型絞盡腦汁的從周圍的文本中學(xué)習(xí)各種信息讓自己訓(xùn)練出來的mask詞匯無限的接近原本的詞匯宵荒。模型在學(xué)習(xí)訓(xùn)練的時候,要讓mask這個詞出來的時候無限的接近或者就是原來的那個詞。
mask模型的缺點:
我們看優(yōu)化目標發(fā)現(xiàn):優(yōu)化目標認為吃和飯是相互獨立的 也就是mask和mask相互獨立报咳。但是大多數(shù)的情況下mask與mask之間不是相互獨立的侠讯。這就是mask模型的缺點。bert在預(yù)訓(xùn)練的時候第一個就是MLM 用到的就是mask策略暑刃,需要注意的是mask的概率問題厢漩,隨機mask15%的單詞。 15%個單詞中10%替換成其他單詞 10%原封不動岩臣,80%替換成真正的mask溜嗜。
mask代碼實踐:
for index in mask_indices:
#80% of the time, replace with [MASK]
if random.random()<0.8:
masked_token = '[MASK]'
else:
#10% of the time , keep original
if random.random() < 0.5:
masked_token = tokens[index]
# 10% of the time,replace with random word
else:
masked_token = random.choice(vocab_list)
NSP任務(wù):最重要的點應(yīng)該是理解樣本構(gòu)造模式
NSP樣本如下:
1.從訓(xùn)練預(yù)料庫中取出兩個連續(xù)的段落作為正樣本(兩個連續(xù)的段落說明了來自同一個文檔,一個文檔一個主題婿脸,首先是同一個主題下粱胜,同一個主題下的兩個連續(xù)的段落,說明順序沒有顛倒)
2.從不同文檔中隨機創(chuàng)建一堆段落作為負樣本(不同的主題隨便抽一個鏈接做負樣本)
缺點:主題預(yù)測和連貫性預(yù)測合并為一個單項任務(wù)狐树。由于主題任務(wù)是非常簡單的焙压,導(dǎo)致整個任務(wù)在做的時候就變得簡單起來。這也是后續(xù)很多實驗去預(yù)測NSP沒有很好效果的主要原因抑钟,ALBERT直接拋棄掉了主題預(yù)測涯曲。ALBERT的正負樣本都來自于同一個文檔,正樣本順序在塔,負樣本顛倒幻件。
3.如何微調(diào)BERT,提升BERT在下游任務(wù)中的效果
主要是分為4種蛔溃,句子對的分類任務(wù)绰沥;單個句子的分類任務(wù);問答贺待;序列標注任務(wù)
對于序列標注:把所有的token輸出做softmax看他屬于實體中的哪一個徽曲。
對于單個樣本:使用CLS的輸出做微調(diào)(二分類或者多分類)
對于句子對:本質(zhì)是文本匹配,把兩個句子拼接起來看是否是同一個主題麸塞。
在下游任務(wù)重還是比較簡單的
如何提升bert在下游任務(wù)中的表現(xiàn)
我們在實際應(yīng)用的時候一般很少從頭訓(xùn)練一個bert秃臣。一般是用已經(jīng)訓(xùn)練好的,然后自己在自己的任務(wù)中做一個微調(diào)哪工。一般的做法都是先獲取谷歌中文bert 奥此,然后基于自己的任務(wù)數(shù)據(jù)做一個微調(diào)。如果想要更好的性能雁比,現(xiàn)在有很多trick可以做
四步驟
比如做微博文本情感分析
1.在大量通用語料上訓(xùn)練一個LM(Pretrain)稚虎;——中文谷歌bert
2.在相同領(lǐng)域上繼續(xù)訓(xùn)練LM(Domain transfer); ——在大量微博文本上繼續(xù)訓(xùn)練這個bert
3.在任務(wù)相關(guān)的小數(shù)據(jù)上繼續(xù)訓(xùn)練LM(task transfer) :—— 在微博情感文本上(有的文本不屬于情感分析范疇)
4.在任務(wù)相關(guān)數(shù)據(jù)上做具體任務(wù)(Fine-tune)
先Domain transfer 再進行Task transfer 最后Fine-tune性能最好的
如何在相同領(lǐng)域數(shù)據(jù)中進行further pre-training
1.動態(tài)mask:就是每次epoch去訓(xùn)練的時候mask,而不是一直使用同一個(bert并不是一直使用同一個文件mask偎捎,為了避免這一點bert有做改進祥绞,有復(fù)制一些文本)
2.n-gram mask:其實比如ERINE 和SpanBert都是類似于做了實體詞的mask(如果自己訓(xùn)練的時候沒有實體詞非洲,可以做n-gram mask)
3.參數(shù)一定要設(shè)置的比較好 :
Batch_size : 16 32一般影響不打
Learning rate(Adam):5e-5 3e-5 2e-5 盡可能小一點避免災(zāi)難性遺忘
Number of epochs : 3 4
weighted decay修改后的adam,使用warmup蜕径,搭配線性衰減
在預(yù)訓(xùn)練的時候做數(shù)據(jù)增強,自蒸餾败京,外部數(shù)據(jù)的融入(加入實體詞信息兜喻,使用知識圖譜的信息等)
4.如何在脫敏數(shù)據(jù)中使用beert等預(yù)訓(xùn)練模型
1.如何在脫敏數(shù)據(jù)中使用BERT
2.基于此預(yù)料如何使用NSP任務(wù)
對于脫敏數(shù)據(jù)中使用bert,一般可以分為兩種
第一種就是直接從零開始基于預(yù)料訓(xùn)練一個新的bert出來使用
第二種就是按照詞頻赡麦,把脫敏數(shù)字對照到中文或者其他語言[假設(shè)我們使用中文],使用中文bert做初始化朴皆,然后基于新的中文語料訓(xùn)練bert
很多人對預(yù)訓(xùn)練模型理解的不是很深刻,很疑惑為什么在脫敏數(shù)據(jù)中也可以訓(xùn)練bert等預(yù)訓(xùn)練模型
其實這一點也很容易理解
最開始bert用英文預(yù)料訓(xùn)練出來的泛粹,然后有人基于中文語料開源了中文的bert
那么我的脫敏數(shù)字就是類似與中文的一種另外的語言遂铡,你可以看成是【X】語言,我們當然可以基于【X】語言的預(yù)料去訓(xùn)練一個新的BERT或者其他的預(yù)訓(xùn)練模型
NSP任務(wù)如何去使用的問題:
很明顯晶姊,在當前這個任務(wù)中是一個文本匹配的形式扒接;
語料不是我們自己有主動的去獲取的能力,所以構(gòu)造一個NSP任務(wù)的格式比較困難
但是NSP任務(wù)僅僅是一種任務(wù)形式们衙,我們完全可以基于訓(xùn)練語料構(gòu)造一個是否匹配的任務(wù)钾怔,可以稱之為NSP任務(wù)
基于此,測試數(shù)據(jù)是使用不了的蒙挑,因為測試數(shù)據(jù)沒有l(wèi)abel
不過宗侦,對于測試數(shù)據(jù)可以使用MLM任務(wù),訓(xùn)練數(shù)據(jù)使用MLM+類NSP任務(wù)忆蚀。