編者按:遷移學(xué)習(xí)在CV領(lǐng)域的應(yīng)用已經(jīng)取得不小的進(jìn)步了,而在自然語言處理(NLP)領(lǐng)域,很多任務(wù)還在使用詞嵌入。嵌入的確是種更豐富的表現(xiàn)單詞的形式,但是隨著任務(wù)種類的增多,嵌入也有了局限。本文將介紹用遷移學(xué)習(xí)處理NLP任務(wù)的大致思路,以下是論智的編譯。
通用語言建模
遷移學(xué)習(xí)在計算機(jī)視覺領(lǐng)域已經(jīng)有了很多應(yīng)用,最近幾年也做出了許多不錯的成果。在一些任務(wù)中,我們甚至能以超越人類精確度的水平完成某項任務(wù)。最近,很少能看到用無需預(yù)訓(xùn)練的權(quán)重輸出頂尖結(jié)果的模型。事實上,當(dāng)人們生產(chǎn)它們時,經(jīng)常會用遷移學(xué)習(xí)或某種微調(diào)的方法。遷移學(xué)習(xí)在計算機(jī)視覺領(lǐng)域有很大的影響,為該領(lǐng)域的發(fā)展做出了巨大貢獻(xiàn)。
但是直到現(xiàn)在,遷移學(xué)習(xí)對計算機(jī)視覺還有些許限制,最近的研究表明,這種限制可以擴(kuò)展到多個方面,包括自然語言處理和強(qiáng)化學(xué)習(xí)。最近的幾篇論文表明,NLP領(lǐng)域中的遷移學(xué)習(xí)和微調(diào)的結(jié)果也很不錯。
最近,OpenAI舉辦了一場Retro競賽,其中參賽者要創(chuàng)建多個智能體,在玩游戲時不能接觸環(huán)境,而是利用遷移學(xué)習(xí)進(jìn)行訓(xùn)練?,F(xiàn)在,我們可以探索這種方法的潛力了。
利用之前的經(jīng)驗學(xué)習(xí)新事物(強(qiáng)化學(xué)習(xí)中的新環(huán)境)。來源:OpenAI Retro Contest
此前在計算機(jī)視覺領(lǐng)域關(guān)于漸進(jìn)式學(xué)習(xí)的研究給模型進(jìn)行了概括,因為這是保證神經(jīng)網(wǎng)絡(luò)在學(xué)習(xí)時穩(wěn)定的最重要因素之一。想實現(xiàn)這一目的的論文就是Universal Language Model Fine-tuning for Text Classification。
文本分類是NLP領(lǐng)域重要的部分,它與現(xiàn)實生活中的場景密切相關(guān),例如機(jī)器人、語音助手、垃圾或詐騙信息監(jiān)測、文本分類等等。這項技術(shù)的用途十分廣泛,幾乎可以用在任意語言模型上。本論文的作者進(jìn)行的是文本分類,直到現(xiàn)在,很多學(xué)術(shù)研究人員仍然用詞嵌入訓(xùn)練模型,例如word2vec和GloVe。
詞嵌入的局限
詞嵌入是單詞的密集表示,通過用轉(zhuǎn)換成張量的真實數(shù)字轉(zhuǎn)化而來。在模型中,嵌入需要用特殊順序排列,這樣模型才能學(xué)會詞語和語境中的語法和語義關(guān)系。
進(jìn)行可視化時,有相近語義的單詞的嵌入也會更近,這樣每個單詞也會有不同的向量表示。
詞匯表中的不常見詞
處理數(shù)據(jù)集時,我們經(jīng)常會碰到生僻詞語。
標(biāo)記化(Tokenization)。這些詞語都是常見詞,但是有了類似這樣的嵌入就會很難處理
對于某些只出現(xiàn)很少幾次的詞語,模型就要花大量時間弄清楚它的語義,所以人們專門建立了一個詞匯集來處理這一問題。Word2vec無法處理未知詞語。當(dāng)模型不認(rèn)識某個詞時,它的向量就不能被確切地分解,所以它必須隨意地進(jìn)行初始化操作。關(guān)于嵌入,常見的問題有:
處理共享表示(shared representations)
詞語表示的另一個問題是,在子字詞中沒有一個共同的表示。英文中的前綴和后綴通常會改變詞語的意思。由于每個向量都是獨(dú)立的,詞語間的語義關(guān)系就不能完全被理解。
共現(xiàn)統(tǒng)計(co-occurrence statistics)
分布式詞向量模型能夠捕捉到詞語中共現(xiàn)統(tǒng)計的某些方面。在單詞共現(xiàn)上訓(xùn)練的嵌入可以捕捉單詞語義之間的相似性,所以可以在單詞相似性的任務(wù)上進(jìn)行評估。
如果某個特殊的語言模型用char-based輸入,并且無法從與訓(xùn)練中受益,那么就需要對詞嵌入進(jìn)行隨機(jī)處理。
支持新語言
嵌入的使用在面對其他語言時,會出現(xiàn)不穩(wěn)定的情況。新語言需要新的嵌入矩陣,無法使用共同的參數(shù),所以模型不能用于多語言任務(wù)。
詞嵌入可以被連接起來,但是用于訓(xùn)練的模型必須從新開始處理嵌入。預(yù)訓(xùn)練嵌入被看成是固定參數(shù)。這樣的模型在漸進(jìn)式學(xué)習(xí)中是沒有用的。
計算機(jī)視覺已經(jīng)表明,hypercolumns和其他常用的訓(xùn)練方法相比,并不實用。在CV中,一個像素的hypercolumn是該像素之上,所有卷積網(wǎng)絡(luò)單元中的活動向量。
平均隨機(jī)梯度方法,權(quán)重下降LSTM
這個研究中所用模型的靈感來自論文:Regularizing and Optimizing LSTM Language Models。它使用權(quán)重下降的LSTM,LSTM利用DropConnect作為循環(huán)正則化形式。DropConnect是在神經(jīng)網(wǎng)絡(luò)中對大型完全連接層進(jìn)行規(guī)范化的泛化。
用Dropout訓(xùn)練時,一個隨機(jī)選擇的子集在每層中被設(shè)置為0.DropConnect設(shè)置了一個隨機(jī)選擇的權(quán)重子集,每個單元從其中接收從上一層來的輸入。
Dropout網(wǎng)絡(luò)和DropConnect網(wǎng)絡(luò)的不同
通過在hidden-to-hidden權(quán)重矩陣上使用DropConnect,可以避免LSTM循環(huán)連接中的過度擬合。這一正則化技術(shù)還可以防止其他循環(huán)神經(jīng)網(wǎng)絡(luò)中的循環(huán)權(quán)重矩陣的過度擬合現(xiàn)象。
通常所用的值為:
dropouts = np.array([0.4,0.5,0.05,0.3,0.1]) x 0.5
這里的×0.5是一個超參數(shù),雖然數(shù)組中的比列已經(jīng)達(dá)到很好的平衡,但是用0.5進(jìn)行調(diào)整可能也是需要的。
由于同樣的權(quán)重可能在不同階段重復(fù)使用,同樣的權(quán)重會在全部過程中保持下降。結(jié)果和variational dropout非常像,它運(yùn)用了相同的dropout掩碼,只是應(yīng)用在了循環(huán)權(quán)重上。
通用語言模型
一個三層的LSTM結(jié)構(gòu)以及經(jīng)過調(diào)整的dropout參數(shù)能比其他文本分類任務(wù)表現(xiàn)得更好。主要用到的有三種技術(shù)。
三角變化學(xué)習(xí)速率(STLR)
最初我使用Adam優(yōu)化算法和權(quán)重衰減,但是優(yōu)化器又很有限制。如果模型在下鞍點(diǎn)卡住,同時生成的梯度很小,那么模型就很難生成足夠的梯度走出非凸區(qū)域。
Leslie Smith提出的循環(huán)學(xué)習(xí)速率(CLR)解決了這一問題。使用了CLR之后,精確度提高了10%。
學(xué)習(xí)速率決定了在目前的權(quán)重上應(yīng)用多少損失梯度,這一方法和熱啟動的隨機(jī)梯度很像。
簡單地說,選擇初始學(xué)習(xí)速率和學(xué)習(xí)速率調(diào)度表比較困難,因為有時并不能分辨那種情況更好。
但是可以給每個參數(shù)應(yīng)用靈活的學(xué)習(xí)速率,例如Adam、Adagrad和RMSprop等優(yōu)化器可以在訓(xùn)練時對每個參數(shù)的學(xué)習(xí)速率進(jìn)行調(diào)整。
論文Cyclical Learning Rates for Training Neural Networks用簡潔優(yōu)雅的方法解決了上述常見問題。
循環(huán)學(xué)習(xí)速率(CLR)為學(xué)習(xí)速率的值創(chuàng)建了高低兩個界限。它可以和適應(yīng)性學(xué)習(xí)速率結(jié)合,但是和SGDR很相似,同時所需計算力并不多。
如果在最低點(diǎn)停滯,可以使用更高的學(xué)習(xí)速率讓模型走出此區(qū)域,但如果位置過于低,那么傳統(tǒng)的改變學(xué)習(xí)速率的方法就無法生成足夠的梯度。
非凸函數(shù)
周期性的更高學(xué)習(xí)速率可以更流利、更快地穿過此區(qū)域。
最優(yōu)學(xué)習(xí)速率將處于最大和最低界限之間。
所以有了遷移學(xué)習(xí)在A上運(yùn)用的模型可以遷移到B上提到其表現(xiàn)力。語言模型有著用于CV分類的所有功能:它了解語言、理解層次關(guān)系,能夠進(jìn)行長時間應(yīng)用,可進(jìn)行情感分析。
ULMFiT和CV一樣有三個階段。
第一階段,語言模型的預(yù)訓(xùn)練。語言模型在通用數(shù)據(jù)集上訓(xùn)練,它從中學(xué)習(xí)到通用特征,了解語義關(guān)系,就像ImageNet。
第二階段,語言模型的微調(diào)。用不同的微調(diào)方法和三角形可變學(xué)習(xí)速率,從而使模型適應(yīng)不同的任務(wù)。
第三階段,分類器微調(diào)。對分類器進(jìn)行調(diào)整,逐步解鎖進(jìn)行微調(diào),用STLP保存低水平表示,同時對高層次進(jìn)行調(diào)整。
總之,ULMFiT可以看做是模型的主干,上面添加了一個分類器。它用的是在通用語料上訓(xùn)練過的模型。在之后的任務(wù)上可以進(jìn)行微調(diào)以達(dá)到文本分類的最佳水平。
ULMFiT可以解決的問題
這一方法之所以通用,是因為它對數(shù)據(jù)集沒有要求。任何長度的文件和數(shù)據(jù)集都能用它解決。它使用單一的結(jié)構(gòu)(在這個案例中是AWD-LSTM,和CV中的ResNet一樣)。無需特殊定制,也不需要額外的文本使其適應(yīng)不同的任務(wù)。
該模型還可以用注意力進(jìn)行進(jìn)一步改善提高,如有需要還可以加入跳躍式連接(skip connection)。
不同情況下的微調(diào)
神經(jīng)網(wǎng)絡(luò)的每個圖層都捕捉到不同的信息。在CV中,初始層捕捉到的是廣泛的、明顯的特征。越深的圖層捕捉到的特征就越復(fù)雜、具體。利用同樣的規(guī)則,這種方法會在語言模型的不同圖層提出不同的調(diào)整方法。為了達(dá)到這一目的,每一層的學(xué)習(xí)速率都不相同,這樣一來人們可以決定每一層的參數(shù)如何優(yōu)化。
參數(shù)θ將會分成一系列參數(shù),并作用在l個圖層上{θ1,…,θL},同時學(xué)習(xí)速率也可以做出同樣的操作,隨機(jī)梯度下降可以表示成:
不同任務(wù)權(quán)重下對分類器的微調(diào)
之后會添加兩個線性模塊,每個模塊利用批歸一化和較低值的dropout。在模塊之間,ReLU用來作為激活函數(shù)。這些分類器圖層并不會從預(yù)訓(xùn)練中延續(xù)某種特征,而是從零開始訓(xùn)練。在搭建模塊之前,會對上一個隱藏層進(jìn)行池化,然后輸入到第一個線性層中。
trn_ds = TextDataset(trn_clas, trn_labels)
val_ds = TextDataset(val_clas, val_labels)
trn_samp = SortishSampler(trn_clas, key=lambda x: len(trn_clas[x]), bs=bs//2)
val_samp = SortSampler(val_clas, key=lambda x: len(val_clas[x]))
trn_dl = DataLoader(trn_ds, bs//2, transpose=True, num_workers=1, pad_idx=1, sampler=trn_samp)
val_dl = DataLoader(val_ds, bs, transpose=True, num_workers=1, pad_idx=1, sampler=val_samp)
md = ModelData(PATH, trn_dl, val_dl)
dropouts = np.array([0.4,0.5,0.05,0.3,0.4])*0.5
m = get_rnn_classifer(bptt, 20*70, c, vs, emb_sz=em_sz, n_hid=nh, n_layers=nl, pad_token=1,
layers=[em_sz*3, 50, c], drop=[dropouts[4], 0.1],
dropouti=dropouts[0], wdrop=dropouts[1], dropoute=dropouts[2], dropouth=dropouts[3])
Concat池化
注意循環(huán)模型的狀態(tài)通常是很重要的,并且要保留有用的狀態(tài),釋放沒有用的并且限制內(nèi)存的狀態(tài)。但是隱藏包含了許多信息,而需要保留的權(quán)重都在隱藏層。為了做到這一點(diǎn),我們將最后一步的隱藏層和隱藏層最大和平均池化的表示連接起來,這樣可以適應(yīng)GPU的內(nèi)存。
trn_dl = DataLoader(trn_ds, bs//2, transpose=True, num_workers=1, pad_idx=1, sampler=trn_samp)
val_dl = DataLoader(val_ds, bs, transpose=True, num_workers=1, pad_idx=1, sampler=val_samp)
md = ModelData(PATH, trn_dl, val_dl)
訓(xùn)練分類器(逐步解鎖)
如果直接對分類器進(jìn)行微調(diào),則有可能導(dǎo)致嚴(yán)重的遺忘出現(xiàn),而緩慢地微調(diào)可能會導(dǎo)致過度擬合和收斂。所以我們認(rèn)為不能直接對所有圖層進(jìn)行微調(diào),而是要每次只調(diào)一個圖層,逐步進(jìn)行。
在文本分類上進(jìn)行逐步反向傳播(BPTT)
BPTT經(jīng)常用于RNN中處理序列數(shù)據(jù),每一步都有一個輸入、一個網(wǎng)絡(luò)的復(fù)制版本和一個輸出。同時每一步還會生成網(wǎng)絡(luò)的錯誤并集合在一起。
模型在上一批處理的最后階段進(jìn)行初始化。平均和最大池化的隱藏狀態(tài)同樣被追蹤下去。模型的核心使用了可變長度的序列,以下是用PyTorch進(jìn)行采樣的一小片段:
classSortishSampler(Sampler):
def __init__(self, data_source, key, bs):
self.data_source,self.key,self.bs = data_source,key,bs
def __len__(self): return len(self.data_source)
def __iter__(self):
idxs = np.random.permutation(len(self.data_source))
sz = self.bs*50
ck_idx = [idxs[i:i+sz] for i in range(0, len(idxs), sz)]
sort_idx = np.concatenate([sorted(s, key=self.key, reverse=True) for s in ck_idx])
sz = self.bs
ck_idx = [sort_idx[i:i+sz] for i in range(0, len(sort_idx), sz)]
max_ck = np.argmax([self.key(ck[0]) for ck in ck_idx]) # find the chunk with the largest key,
ck_idx[0],ck_idx[max_ck] = ck_idx[max_ck],ck_idx[0] # then make sure it goes first.
sort_idx = np.concatenate(np.random.permutation(ck_idx[1:]))
sort_idx = np.concatenate((ck_idx[0], sort_idx))
return iter(sort_idx)
結(jié)果
這一方法比其他依靠嵌入或其他遷移學(xué)習(xí)的NLP方法優(yōu)秀得多。通過逐漸解鎖并且用新的方法訓(xùn)練分類器,四次迭代后可以達(dá)到94.4的精確度,比其他方法都準(zhǔn)確。
用ULMFiT進(jìn)行文本分類時的損失和精確度
驗證錯誤率
-
計算機(jī)視覺
+關(guān)注
關(guān)注
8文章
1698瀏覽量
46031 -
強(qiáng)化學(xué)習(xí)
+關(guān)注
關(guān)注
4文章
268瀏覽量
11270 -
自然語言處理
+關(guān)注
關(guān)注
1文章
619瀏覽量
13581
原文標(biāo)題:概覽遷移學(xué)習(xí)在NLP領(lǐng)域中的應(yīng)用
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論