11111111111111111111
111111111111111111111111111111111111111111111111111111
跳轉(zhuǎn)至
logo
Transformer
第二章:Transformer架構(gòu)解析
logo
Transformer
第一章:Transformer背景介紹
第二章:Transformer架構(gòu)解析
目錄
2.1 認識Transformer架構(gòu)
學習目標
Transformer模型的作用
Transformer總體架構(gòu)圖
小節(jié)總結(jié)
2.2 輸入部分實現(xiàn)
學習目標
文本嵌入層的作用
位置編碼器的作用
小節(jié)總結(jié)
2.3 編碼器部分實現(xiàn)
學習目標
2.3.1 掩碼張量
2.3.2 注意力機制
2.3.3 多頭注意力機制
2.3.4 前饋全連接層
2.3.5 規(guī)范化層
2.3.6 子層連接結(jié)構(gòu)
2.3.7 編碼器層
2.3.8 編碼器
2.4 解碼器部分實現(xiàn)
學習目標
2.4.1 解碼器層
2.4.2 解碼器
2.5 輸出部分實現(xiàn)
學習目標
線性層的作用
softmax層的作用
小節(jié)總結(jié)
2.6 模型構(gòu)建
學習目標
編碼器-解碼器結(jié)構(gòu)的代碼實現(xiàn)
Tansformer模型構(gòu)建過程的代碼分析
小節(jié)總結(jié)
第二章:Transformer架構(gòu)解析
2.1 認識Transformer架構(gòu)
學習目標
了解Transformer模型的作用.
了解Transformer總體架構(gòu)圖中各個組成部分的名稱.
Transformer模型的作用
基于seq2seq架構(gòu)的transformer模型可以完成NLP領(lǐng)域研究的典型任務, 如機器翻譯, 文本生成等. 同時又可以構(gòu)建預訓練語言模型,用于不同任務的遷移學習.
聲明:
在接下來的架構(gòu)分析中, 我們將假設(shè)使用Transformer模型架構(gòu)處理從一種語言文本到另一種語言文本的翻譯工作, 因此很多命名方式遵循NLP中的規(guī)則. 比如: Embeddding層將稱作文本嵌入層, Embedding層產(chǎn)生的張量稱為詞嵌入張量, 它的最后一維將稱作詞向量等.
Transformer總體架構(gòu)圖
avatar
Transformer總體架構(gòu)可分為四個部分:
輸入部分
輸出部分
編碼器部分
解碼器部分
輸入部分包含:
源文本嵌入層及其位置編碼器
目標文本嵌入層及其位置編碼器
avatar
輸出部分包含:
線性層
softmax層
avatar
編碼器部分:
由N個編碼器層堆疊而成
每個編碼器層由兩個子層連接結(jié)構(gòu)組成
第一個子層連接結(jié)構(gòu)包括一個多頭自注意力子層和規(guī)范化層以及一個殘差連接
第二個子層連接結(jié)構(gòu)包括一個前饋全連接子層和規(guī)范化層以及一個殘差連接
avatar
解碼器部分:
由N個解碼器層堆疊而成
每個解碼器層由三個子層連接結(jié)構(gòu)組成
第一個子層連接結(jié)構(gòu)包括一個多頭自注意力子層和規(guī)范化層以及一個殘差連接
第二個子層連接結(jié)構(gòu)包括一個多頭注意力子層和規(guī)范化層以及一個殘差連接
第三個子層連接結(jié)構(gòu)包括一個前饋全連接子層和規(guī)范化層以及一個殘差連接
avatar
小節(jié)總結(jié)
學習了Transformer模型的作用:
基于seq2seq架構(gòu)的transformer模型可以完成NLP領(lǐng)域研究的典型任務, 如機器翻譯, 文本生成等. 同時又可以構(gòu)建預訓練語言模型,用于不同任務的遷移學習.
Transformer總體架構(gòu)可分為四個部分:
輸入部分
輸出部分
編碼器部分
解碼器部分
輸入部分包含:
源文本嵌入層及其位置編碼器
目標文本嵌入層及其位置編碼器
輸出部分包含:
線性層
softmax處理器
編碼器部分:
由N個編碼器層堆疊而成
每個編碼器層由兩個子層連接結(jié)構(gòu)組成
第一個子層連接結(jié)構(gòu)包括一個多頭自注意力子層和規(guī)范化層以及一個殘差連接
第二個子層連接結(jié)構(gòu)包括一個前饋全連接子層和規(guī)范化層以及一個殘差連接
解碼器部分:
由N個解碼器層堆疊而成
每個解碼器層由三個子層連接結(jié)構(gòu)組成
第一個子層連接結(jié)構(gòu)包括一個多頭自注意力子層和規(guī)范化層以及一個殘差連接
第二個子層連接結(jié)構(gòu)包括一個多頭注意力子層和規(guī)范化層以及一個殘差連接
第三個子層連接結(jié)構(gòu)包括一個前饋全連接子層和規(guī)范化層以及一個殘差連接
2.2 輸入部分實現(xiàn)
學習目標
了解文本嵌入層和位置編碼的作用.
掌握文本嵌入層和位置編碼的實現(xiàn)過程.
輸入部分包含:
源文本嵌入層及其位置編碼器
目標文本嵌入層及其位置編碼器
avatar
文本嵌入層的作用
無論是源文本嵌入還是目標文本嵌入,都是為了將文本中詞匯的數(shù)字表示轉(zhuǎn)變?yōu)橄蛄勘硎? 希望在這樣的高維空間捕捉詞匯間的關(guān)系.
pytorch 0.3.0及其必備工具包的安裝:
使用pip安裝的工具包包括pytorch-0.3.0, numpy, matplotlib, seaborn
pip install http://download.pytorch.org/whl/cu80/torch-0.3.0.post4-cp36-cp36m-linux_x86_64.whl numpy matplotlib seaborn
MAC系統(tǒng)安裝, python版本<=3.6
pip install torch==0.3.0.post4 numpy matplotlib seaborn
文本嵌入層的代碼分析:
導入必備的工具包
import torch
預定義的網(wǎng)絡(luò)層torch.nn, 工具開發(fā)者已經(jīng)幫助我們開發(fā)好的一些常用層,
比如,卷積層, lstm層, embedding層等, 不需要我們再重新造輪子.
import torch.nn as nn
數(shù)學計算工具包
import math
torch中變量封裝函數(shù)Variable.
from torch.autograd import Variable
定義Embeddings類來實現(xiàn)文本嵌入層,這里s說明代表兩個一模一樣的嵌入層, 他們共享參數(shù).
該類繼承nn.Module, 這樣就有標準層的一些功能, 這里我們也可以理解為一種模式, 我們自己實現(xiàn)的所有層都會這樣去寫.
class Embeddings(nn.Module):
def init(self, d_model, vocab):
“”“類的初始化函數(shù), 有兩個參數(shù), d_model: 指詞嵌入的維度, vocab: 指詞表的大小.”""
# 接著就是使用super的方式指明繼承nn.Module的初始化函數(shù), 我們自己實現(xiàn)的所有層都會這樣去寫.
super(Embeddings, self).init()
# 之后就是調(diào)用nn中的預定義層Embedding, 獲得一個詞嵌入對象self.lut
self.lut = nn.Embedding(vocab, d_model)
# 最后就是將d_model傳入類中
self.d_model = d_model
nn.Embedding演示:
embedding = nn.Embedding(10, 3)
input = torch.LongTensor([[1,2,4,5],[4,3,2,9]])
embedding(input)
tensor([[[-0.0251, -1.6902, 0.7172],
[-0.6431, 0.0748, 0.6969],
[ 1.4970, 1.3448, -0.9685],
[-0.3677, -2.7265, -0.1685]],
embedding = nn.Embedding(10, 3, padding_idx=0)
input = torch.LongTensor([[0,2,0,5]])
embedding(input)
tensor([[[ 0.0000, 0.0000, 0.0000],
[ 0.1535, -2.0309, 0.9315],
[ 0.0000, 0.0000, 0.0000],
[-0.1655, 0.9897, 0.0635]]])
實例化參數(shù):
詞嵌入維度是512維
d_model = 512
詞表大小是1000
vocab = 1000
輸入?yún)?shù):
輸入x是一個使用Variable封裝的長整型張量, 形狀是2 x 4
x = Variable(torch.LongTensor([[100,2,421,508],[491,998,1,221]]))
調(diào)用:
emb = Embeddings(d_model, vocab)
embr = emb(x)
print(“embr:”, embr)
輸出效果:
embr: Variable containing:
( 0 ,.,.) =
35.9321 3.2582 -17.7301 … 3.4109 13.8832 39.0272
8.5410 -3.5790 -12.0460 … 40.1880 36.6009 34.7141
-17.0650 -1.8705 -20.1807 … -12.5556 -34.0739 35.6536
20.6105 4.4314 14.9912 … -0.1342 -9.9270 28.6771
( 1 ,.,.) =
27.7016 16.7183 46.6900 … 17.9840 17.2525 -3.9709
3.0645 -5.5105 10.8802 … -13.0069 30.8834 -38.3209
33.1378 -32.1435 -3.9369 … 15.6094 -29.7063 40.1361
-31.5056 3.3648 1.4726 … 2.8047 -9.6514 -23.4909
[torch.FloatTensor of size 2x4x512]
位置編碼器的作用
因為在Transformer的編碼器結(jié)構(gòu)中, 并沒有針對詞匯位置信息的處理,因此需要在Embedding層后加入位置編碼器,將詞匯位置不同可能會產(chǎn)生不同語義的信息加入到詞嵌入張量中, 以彌補位置信息的缺失.
位置編碼器的代碼分析:
定義位置編碼器類, 我們同樣把它看做一個層, 因此會繼承nn.Module
class PositionalEncoding(nn.Module):
def init(self, d_model, dropout, max_len=5000):
“”“位置編碼器類的初始化函數(shù), 共有三個參數(shù), 分別是d_model: 詞嵌入維度,
dropout: 置0比率, max_len: 每個句子的最大長度”""
super(PositionalEncoding, self).init()
nn.Dropout演示:
m = nn.Dropout(p=0.2)
input = torch.randn(4, 5)
output = m(input)
output
Variable containing:
0.0000 -0.5856 -1.4094 0.0000 -1.0290
2.0591 -1.3400 -1.7247 -0.9885 0.1286
0.5099 1.3715 0.0000 2.2079 -0.5497
-0.0000 -0.7839 -1.2434 -0.1222 1.2815
[torch.FloatTensor of size 4x5]
torch.unsqueeze演示:
x = torch.tensor([1, 2, 3, 4])
torch.unsqueeze(x, 0)
tensor([[ 1, 2, 3, 4]])
torch.unsqueeze(x, 1)
tensor([[ 1],
[ 2],
[ 3],
[ 4]])
實例化參數(shù):
詞嵌入維度是512維
d_model = 512
置0比率為0.1
dropout = 0.1
句子最大長度
max_len=60
輸入?yún)?shù):
輸入x是Embedding層的輸出的張量, 形狀是2 x 4 x 512
x = embr
Variable containing:
( 0 ,.,.) =
35.9321 3.2582 -17.7301 … 3.4109 13.8832 39.0272
8.5410 -3.5790 -12.0460 … 40.1880 36.6009 34.7141
-17.0650 -1.8705 -20.1807 … -12.5556 -34.0739 35.6536
20.6105 4.4314 14.9912 … -0.1342 -9.9270 28.6771
( 1 ,.,.) =
27.7016 16.7183 46.6900 … 17.9840 17.2525 -3.9709
3.0645 -5.5105 10.8802 … -13.0069 30.8834 -38.3209
33.1378 -32.1435 -3.9369 … 15.6094 -29.7063 40.1361
-31.5056 3.3648 1.4726 … 2.8047 -9.6514 -23.4909
[torch.FloatTensor of size 2x4x512]
調(diào)用:
pe = PositionalEncoding(d_model, dropout, max_len)
pe_result = pe(x)
print(“pe_result:”, pe_result)
輸出效果:
pe_result: Variable containing:
( 0 ,.,.) =
-19.7050 0.0000 0.0000 … -11.7557 -0.0000 23.4553
-1.4668 -62.2510 -2.4012 … 66.5860 -24.4578 -37.7469
9.8642 -41.6497 -11.4968 … -21.1293 -42.0945 50.7943
0.0000 34.1785 -33.0712 … 48.5520 3.2540 54.1348
( 1 ,.,.) =
7.7598 -21.0359 15.0595 … -35.6061 -0.0000 4.1772
-38.7230 8.6578 34.2935 … -43.3556 26.6052 4.3084
24.6962 37.3626 -26.9271 … 49.8989 0.0000 44.9158
-28.8435 -48.5963 -0.9892 … -52.5447 -4.1475 -3.0450
[torch.FloatTensor of size 2x4x512]
繪制詞匯向量中特征的分布曲線:
import matplotlib.pyplot as plt
創(chuàng)建一張15 x 5大小的畫布
plt.figure(figsize=(15, 5))
實例化PositionalEncoding類得到pe對象, 輸入?yún)?shù)是20和0
pe = PositionalEncoding(20, 0)
然后向pe傳入被Variable封裝的tensor, 這樣pe會直接執(zhí)行forward函數(shù),
且這個tensor里的數(shù)值都是0, 被處理后相當于位置編碼張量
y = pe(Variable(torch.zeros(1, 100, 20)))
然后定義畫布的橫縱坐標, 橫坐標到100的長度, 縱坐標是某一個詞匯中的某維特征在不同長度下對應的值
因為總共有20維之多, 我們這里只查看4,5,6,7維的值.
plt.plot(np.arange(100), y[0, :, 4:8].data.numpy())
在畫布上填寫維度提示信息
plt.legend([“dim %d”%p for p in [4,5,6,7]])
輸出效果:
avatar
效果分析:
每條顏色的曲線代表某一個詞匯中的特征在不同位置的含義.
保證同一詞匯隨著所在位置不同它對應位置嵌入向量會發(fā)生變化.
正弦波和余弦波的值域范圍都是1到-1這又很好的控制了嵌入數(shù)值的大小, 有助于梯度的快速計算.
小節(jié)總結(jié)
學習了文本嵌入層的作用:
無論是源文本嵌入還是目標文本嵌入,都是為了將文本中詞匯的數(shù)字表示轉(zhuǎn)變?yōu)橄蛄勘硎? 希望在這樣的高維空間捕捉詞匯間的關(guān)系.
學習并實現(xiàn)了文本嵌入層的類: Embeddings
初始化函數(shù)以d_model, 詞嵌入維度, 和vocab, 詞匯總數(shù)為參數(shù), 內(nèi)部主要使用了nn中的預定層Embedding進行詞嵌入.
在forward函數(shù)中, 將輸入x傳入到Embedding的實例化對象中, 然后乘以一個根號下d_model進行縮放, 控制數(shù)值大小.
它的輸出是文本嵌入后的結(jié)果.
學習了位置編碼器的作用:
因為在Transformer的編碼器結(jié)構(gòu)中, 并沒有針對詞匯位置信息的處理,因此需要在Embedding層后加入位置編碼器,將詞匯位置不同可能會產(chǎn)生不同語義的信息加入到詞嵌入張量中, 以彌補位置信息的缺失.
學習并實現(xiàn)了位置編碼器的類: PositionalEncoding
初始化函數(shù)以d_model, dropout, max_len為參數(shù), 分別代表d_model: 詞嵌入維度, dropout: 置0比率, max_len: 每個句子的最大長度.
forward函數(shù)中的輸入?yún)?shù)為x, 是Embedding層的輸出.
最終輸出一個加入了位置編碼信息的詞嵌入張量.
實現(xiàn)了繪制詞匯向量中特征的分布曲線:
保證同一詞匯隨著所在位置不同它對應位置嵌入向量會發(fā)生變化.
正弦波和余弦波的值域范圍都是1到-1, 這又很好的控制了嵌入數(shù)值的大小, 有助于梯度的快速計算.
2.3 編碼器部分實現(xiàn)
學習目標
了解編碼器中各個組成部分的作用.
掌握編碼器中各個組成部分的實現(xiàn)過程.
編碼器部分:
由N個編碼器層堆疊而成
每個編碼器層由兩個子層連接結(jié)構(gòu)組成
第一個子層連接結(jié)構(gòu)包括一個多頭自注意力子層和規(guī)范化層以及一個殘差連接
第二個子層連接結(jié)構(gòu)包括一個前饋全連接子層和規(guī)范化層以及一個殘差連接
avatar
2.3.1 掩碼張量
學習目標:
了解什么是掩碼張量以及它的作用.
掌握生成掩碼張量的實現(xiàn)過程.
什么是掩碼張量:
掩代表遮掩,碼就是我們張量中的數(shù)值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩還是1位置被遮掩可以自定義,因此它的作用就是讓另外一個張量中的一些數(shù)值被遮掩,也可以說被替換, 它的表現(xiàn)形式是一個張量.
掩碼張量的作用:
在transformer中, 掩碼張量的主要作用在應用attention(將在下一小節(jié)講解)時,有一些生成的attention張量中的值計算有可能已知了未來信息而得到的,未來信息被看到是因為訓練時會把整個輸出結(jié)果都一次性進行Embedding,但是理論上解碼器的的輸出卻不是一次就能產(chǎn)生最終結(jié)果的,而是一次次通過上一次結(jié)果綜合得出的,因此,未來的信息可能被提前利用. 所以,我們會進行遮掩. 關(guān)于解碼器的有關(guān)知識將在后面的章節(jié)中講解.
生成掩碼張量的代碼分析:
def subsequent_mask(size):
“”“生成向后遮掩的掩碼張量, 參數(shù)size是掩碼張量最后兩個維度的大小, 它的最后兩維形成一個方陣”""
# 在函數(shù)中, 首先定義掩碼張量的形狀
attn_shape = (1, size, size)
np.triu演示:
np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], k=-1)
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 0, 8, 9],
[ 0, 0, 12]])
np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], k=0)
array([[ 1, 2, 3],
[ 0, 5, 6],
[ 0, 0, 9],
[ 0, 0, 0]])
np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], k=1)
array([[ 0, 2, 3],
[ 0, 0, 6],
[ 0, 0, 0],
[ 0, 0, 0]])
輸入實例:
生成的掩碼張量的最后兩維的大小
size = 5
調(diào)用:
sm = subsequent_mask(size)
print(“sm:”, sm)
輸出效果:
最后兩維形成一個下三角陣
sm: (0 ,.,.) =
1 0 0 0 0
1 1 0 0 0
1 1 1 0 0
1 1 1 1 0
1 1 1 1 1
[torch.ByteTensor of size 1x5x5]
掩碼張量的可視化:
plt.figure(figsize=(5,5))
plt.imshow(subsequent_mask(20)[0])
輸出效果:
avatar
效果分析:
通過觀察可視化方陣, 黃色是1的部分, 這里代表被遮掩, 紫色代表沒有被遮掩的信息, 橫坐標代表目標詞匯的位置, 縱坐標代表可查看的位置;
我們看到, 在0的位置我們一看望過去都是黃色的, 都被遮住了,1的位置一眼望過去還是黃色, 說明第一次詞還沒有產(chǎn)生, 從第二個位置看過去, 就能看到位置1的詞, 其他位置看不到, 以此類推.
2.3.1 掩碼張量總結(jié):
學習了什么是掩碼張量:
掩代表遮掩,碼就是我們張量中的數(shù)值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩還是1位置被遮掩可以自定義,因此它的作用就是讓另外一個張量中的一些數(shù)值被遮掩, 也可以說被替換, 它的表現(xiàn)形式是一個張量.
學習了掩碼張量的作用:
在transformer中, 掩碼張量的主要作用在應用attention(將在下一小節(jié)講解)時,有一些生成的attetion張量中的值計算有可能已知量未來信息而得到的,未來信息被看到是因為訓練時會把整個輸出結(jié)果都一次性進行Embedding,但是理論上解碼器的的輸出卻不是一次就能產(chǎn)生最終結(jié)果的,而是一次次通過上一次結(jié)果綜合得出的,因此,未來的信息可能被提前利用. 所以,我們會進行遮掩. 關(guān)于解碼器的有關(guān)知識將在后面的章節(jié)中講解.
學習并實現(xiàn)了生成向后遮掩的掩碼張量函數(shù): subsequent_mask
它的輸入是size, 代表掩碼張量的大小.
它的輸出是一個最后兩維形成1方陣的下三角陣.
最后對生成的掩碼張量進行了可視化分析, 更深一步理解了它的用途.
2.3.2 注意力機制
學習目標:
了解什么是注意力計算規(guī)則和注意力機制.
掌握注意力計算規(guī)則的實現(xiàn)過程.
什么是注意力:
我們觀察事物時,之所以能夠快速判斷一種事物(當然允許判斷是錯誤的), 是因為我們大腦能夠很快把注意力放在事物最具有辨識度的部分從而作出判斷,而并非是從頭到尾的觀察一遍事物后,才能有判斷結(jié)果. 正是基于這樣的理論,就產(chǎn)生了注意力機制.
什么是注意力計算規(guī)則:
它需要三個指定的輸入Q(query), K(key), V(value), 然后通過公式得到注意力的計算結(jié)果, 這個結(jié)果代表query在key和value作用下的表示. 而這個具體的計算規(guī)則有很多種, 我這里只介紹我們用到的這一種.
我們這里使用的注意力的計算規(guī)則:
avatar
Q, K, V的比喻解釋:
假如我們有一個問題: 給出一段文本,使用一些關(guān)鍵詞對它進行描述!
為了方便統(tǒng)一正確答案,這道題可能預先已經(jīng)給大家寫出了一些關(guān)鍵詞作為提示.其中這些給出的提示就可以看作是key,
而整個的文本信息就相當于是query,value的含義則更抽象,可以比作是你看到這段文本信息后,腦子里浮現(xiàn)的答案信息,
這里我們又假設(shè)大家最開始都不是很聰明,第一次看到這段文本后腦子里基本上浮現(xiàn)的信息就只有提示這些信息,
因此key與value基本是相同的,但是隨著我們對這個問題的深入理解,通過我們的思考腦子里想起來的東西原來越多,
并且能夠開始對我們query也就是這段文本,提取關(guān)鍵信息進行表示. 這就是注意力作用的過程, 通過這個過程,
我們最終腦子里的value發(fā)生了變化,
根據(jù)提示key生成了query的關(guān)鍵詞表示方法,也就是另外一種特征表示方法.
剛剛我們說到key和value一般情況下默認是相同,與query是不同的,這種是我們一般的注意力輸入形式,
但有一種特殊情況,就是我們query與key和value相同,這種情況我們稱為自注意力機制,就如同我們的剛剛的例子,
使用一般注意力機制,是使用不同于給定文本的關(guān)鍵詞表示它. 而自注意力機制,
需要用給定文本自身來表達自己,也就是說你需要從給定文本中抽取關(guān)鍵詞來表述它, 相當于對文本自身的一次特征提取.
什么是注意力機制:
注意力機制是注意力計算規(guī)則能夠應用的深度學習網(wǎng)絡(luò)的載體, 除了注意力計算規(guī)則外, 還包括一些必要的全連接層以及相關(guān)張量處理, 使其與應用網(wǎng)絡(luò)融為一體. 使用自注意力計算規(guī)則的注意力機制稱為自注意力機制.
注意力機制在網(wǎng)絡(luò)中實現(xiàn)的圖形表示:
avatar
注意力計算規(guī)則的代碼分析:
def attention(query, key, value, mask=None, dropout=None):
“”“注意力機制的實現(xiàn), 輸入分別是query, key, value, mask: 掩碼張量,
dropout是nn.Dropout層的實例化對象, 默認為None”""
# 在函數(shù)中, 首先取query的最后一維的大小, 一般情況下就等同于我們的詞嵌入維度, 命名為d_k
d_k = query.size(-1)
# 按照注意力公式, 將query與key的轉(zhuǎn)置相乘, 這里面key是將最后兩個維度進行轉(zhuǎn)置, 再除以縮放系數(shù)根號下d_k, 這種計算方法也稱為縮放點積注意力計算.
# 得到注意力得分張量scores
scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
tensor.masked_fill演示:
input = Variable(torch.randn(5, 5))
input
Variable containing:
2.0344 -0.5450 0.3365 -0.1888 -2.1803
1.5221 -0.3823 0.8414 0.7836 -0.8481
-0.0345 -0.8643 0.6476 -0.2713 1.5645
0.8788 -2.2142 0.4022 0.1997 0.1474
2.9109 0.6006 -0.6745 -1.7262 0.6977
[torch.FloatTensor of size 5x5]
mask = Variable(torch.zeros(5, 5))
mask
Variable containing:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
[torch.FloatTensor of size 5x5]
input.masked_fill(mask == 0, -1e9)
Variable containing:
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
-1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09 -1.0000e+09
[torch.FloatTensor of size 5x5]
輸入?yún)?shù):
我們令輸入的query, key, value都相同, 位置編碼的輸出
query = key = value = pe_result
Variable containing:
( 0 ,.,.) =
46.5196 16.2057 -41.5581 … -16.0242 -17.8929 -43.0405
-32.6040 16.1096 -29.5228 … 4.2721 20.6034 -1.2747
-18.6235 14.5076 -2.0105 … 15.6462 -24.6081 -30.3391
0.0000 -66.1486 -11.5123 … 20.1519 -4.6823 0.4916
( 1 ,.,.) =
-24.8681 7.5495 -5.0765 … -7.5992 -26.6630 40.9517
13.1581 -3.1918 -30.9001 … 25.1187 -26.4621 2.9542
-49.7690 -42.5019 8.0198 … -5.4809 25.9403 -27.4931
-52.2775 10.4006 0.0000 … -1.9985 7.0106 -0.5189
[torch.FloatTensor of size 2x4x512]
調(diào)用:
attn, p_attn = attention(query, key, value)
print(“attn:”, attn)
print(“p_attn:”, p_attn)
輸出效果:
將得到兩個結(jié)果
query的注意力表示:
attn: Variable containing:
( 0 ,.,.) =
12.8269 7.7403 41.2225 … 1.4603 27.8559 -12.2600
12.4904 0.0000 24.1575 … 0.0000 2.5838 18.0647
-32.5959 -4.6252 -29.1050 … 0.0000 -22.6409 -11.8341
8.9921 -33.0114 -0.7393 … 4.7871 -5.7735 8.3374
( 1 ,.,.) =
-25.6705 -4.0860 -36.8226 … 37.2346 -27.3576 2.5497
-16.6674 73.9788 -33.3296 … 28.5028 -5.5488 -13.7564
0.0000 -29.9039 -3.0405 … 0.0000 14.4408 14.8579
30.7819 0.0000 21.3908 … -29.0746 0.0000 -5.8475
[torch.FloatTensor of size 2x4x512]
注意力張量:
p_attn: Variable containing:
(0 ,.,.) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
(1 ,.,.) =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
[torch.FloatTensor of size 2x4x4]
帶有mask的輸入?yún)?shù):
query = key = value = pe_result
令mask為一個2x4x4的零張量
mask = Variable(torch.zeros(2, 4, 4))
調(diào)用:
attn, p_attn = attention(query, key, value, mask=mask)
print(“attn:”, attn)
print(“p_attn:”, p_attn)
帶有mask的輸出效果:
query的注意力表示:
attn: Variable containing:
( 0 ,.,.) =
0.4284 -7.4741 8.8839 … 1.5618 0.5063 0.5770
0.4284 -7.4741 8.8839 … 1.5618 0.5063 0.5770
0.4284 -7.4741 8.8839 … 1.5618 0.5063 0.5770
0.4284 -7.4741 8.8839 … 1.5618 0.5063 0.5770
( 1 ,.,.) =
-2.8890 9.9972 -12.9505 … 9.1657 -4.6164 -0.5491
-2.8890 9.9972 -12.9505 … 9.1657 -4.6164 -0.5491
-2.8890 9.9972 -12.9505 … 9.1657 -4.6164 -0.5491
-2.8890 9.9972 -12.9505 … 9.1657 -4.6164 -0.5491
[torch.FloatTensor of size 2x4x512]
注意力張量:
p_attn: Variable containing:
(0 ,.,.) =
0.2500 0.2500 0.2500 0.2500
0.2500 0.2500 0.2500 0.2500
0.2500 0.2500 0.2500 0.2500
0.2500 0.2500 0.2500 0.2500
(1 ,.,.) =
0.2500 0.2500 0.2500 0.2500
0.2500 0.2500 0.2500 0.2500
0.2500 0.2500 0.2500 0.2500
0.2500 0.2500 0.2500 0.2500
[torch.FloatTensor of size 2x4x4]
2.3.2 注意力機制總結(jié):
學習了什么是注意力:
我們觀察事物時,之所以能夠快速判斷一種事物(當然允許判斷是錯誤的), 是因為我們大腦能夠很快把注意力放在事物最具有辨識度的部分從而作出判斷,而并非是從頭到尾的觀察一遍事物后,才能有判斷結(jié)果. 正是基于這樣的理論,就產(chǎn)生了注意力機制.
什么是注意力計算規(guī)則:
它需要三個指定的輸入Q(query), K(key), V(value), 然后通過公式得到注意力的計算結(jié)果, 這個結(jié)果代表query在key和value作用下的表示. 而這個具體的計算規(guī)則有很多種, 我這里只介紹我們用到的這一種.
學習了Q, K, V的比喻解釋:
Q是一段準備被概括的文本; K是給出的提示; V是大腦中的對提示K的延伸.
當Q=K=V時, 稱作自注意力機制.
什么是注意力機制:
注意力機制是注意力計算規(guī)則能夠應用的深度學習網(wǎng)絡(luò)的載體, 除了注意力計算規(guī)則外, 還包括一些必要的全連接層以及相關(guān)張量處理, 使其與應用網(wǎng)絡(luò)融為一體. 使用自注意力計算規(guī)則的注意力機制稱為自注意力機制.
學習并實現(xiàn)了注意力計算規(guī)則的函數(shù): attention
它的輸入就是Q,K,V以及mask和dropout, mask用于掩碼, dropout用于隨機置0.
它的輸出有兩個, query的注意力表示以及注意力張量.
2.3.3 多頭注意力機制
學習目標:
了解多頭注意力機制的作用.
掌握多頭注意力機制的實現(xiàn)過程.
什么是多頭注意力機制:
從多頭注意力的結(jié)構(gòu)圖中,貌似這個所謂的多個頭就是指多組線性變換層,其實并不是,我只有使用了一組線性變化層,即三個變換張量對Q,K,V分別進行線性變換,這些變換不會改變原有張量的尺寸,因此每個變換矩陣都是方陣,得到輸出結(jié)果后,多頭的作用才開始顯現(xiàn),每個頭開始從詞義層面分割輸出的張量,也就是每個頭都想獲得一組Q,K,V進行注意力機制的計算,但是句子中的每個詞的表示只獲得一部分,也就是只分割了最后一維的詞嵌入向量. 這就是所謂的多頭,將每個頭的獲得的輸入送到注意力機制中, 就形成多頭注意力機制.
多頭注意力機制結(jié)構(gòu)圖:
avatar
多頭注意力機制的作用:
這種結(jié)構(gòu)設(shè)計能讓每個注意力機制去優(yōu)化每個詞匯的不同特征部分,從而均衡同一種注意力機制可能產(chǎn)生的偏差,讓詞義擁有來自更多元的表達,實驗表明可以從而提升模型效果.
多頭注意力機制的代碼實現(xiàn):
用于深度拷貝的copy工具包
import copy
首先需要定義克隆函數(shù), 因為在多頭注意力機制的實現(xiàn)中, 用到多個結(jié)構(gòu)相同的線性層.
我們將使用clone函數(shù)將他們一同初始化在一個網(wǎng)絡(luò)層列表對象中. 之后的結(jié)構(gòu)中也會用到該函數(shù).
def clones(module, N):
“”“用于生成相同網(wǎng)絡(luò)層的克隆函數(shù), 它的參數(shù)module表示要克隆的目標網(wǎng)絡(luò)層, N代表需要克隆的數(shù)量”""
# 在函數(shù)中, 我們通過for循環(huán)對module進行N次深度拷貝, 使其每個module成為獨立的層,
# 然后將其放在nn.ModuleList類型的列表中存放.
return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])
我們使用一個類來實現(xiàn)多頭注意力機制的處理
class MultiHeadedAttention(nn.Module):
def init(self, head, embedding_dim, dropout=0.1):
“”“在類的初始化時, 會傳入三個參數(shù),head代表頭數(shù),embedding_dim代表詞嵌入的維度,
dropout代表進行dropout操作時置0比率,默認是0.1.”""
super(MultiHeadedAttention, self).init()
tensor.view演示:
x = torch.randn(4, 4)
x.size()
torch.Size([4, 4])
y = x.view(16)
y.size()
torch.Size([16])
z = x.view(-1, 8) # the size -1 is inferred from other dimensions
z.size()
torch.Size([2, 8])
a = torch.randn(1, 2, 3, 4)
a.size()
torch.Size([1, 2, 3, 4])
b = a.transpose(1, 2) # Swaps 2nd and 3rd dimension
b.size()
torch.Size([1, 3, 2, 4])
c = a.view(1, 3, 2, 4) # Does not change tensor layout in memory
c.size()
torch.Size([1, 3, 2, 4])
torch.equal(b, c)
False
torch.transpose演示:
x = torch.randn(2, 3)
x
tensor([[ 1.0028, -0.9893, 0.5809],
[-0.1669, 0.7299, 0.4942]])
torch.transpose(x, 0, 1)
tensor([[ 1.0028, -0.1669],
[-0.9893, 0.7299],
[ 0.5809, 0.4942]])
實例化參數(shù):
頭數(shù)head
head = 8
詞嵌入維度embedding_dim
embedding_dim = 512
置零比率dropout
dropout = 0.2
輸入?yún)?shù):
假設(shè)輸入的Q,K,V仍然相等
query = value = key = pe_result
輸入的掩碼張量mask
mask = Variable(torch.zeros(8, 4, 4))
調(diào)用:
mha = MultiHeadedAttention(head, embedding_dim, dropout)
mha_result = mha(query, key, value, mask)
print(mha_result)
輸出效果:
tensor([[[-0.3075, 1.5687, -2.5693, …, -1.1098, 0.0878, -3.3609],
[ 3.8065, -2.4538, -0.3708, …, -1.5205, -1.1488, -1.3984],
[ 2.4190, 0.5376, -2.8475, …, 1.4218, -0.4488, -0.2984],
[ 2.9356, 0.3620, -3.8722, …, -0.7996, 0.1468, 1.0345]],
torch.Size([2, 4, 512])
2.3.3 多頭注意力機制總結(jié):
學習了什么是多頭注意力機制:
每個頭開始從詞義層面分割輸出的張量,也就是每個頭都想獲得一組Q,K,V進行注意力機制的計算,但是句子中的每個詞的表示只獲得一部分,也就是只分割了最后一維的詞嵌入向量. 這就是所謂的多頭.將每個頭的獲得的輸入送到注意力機制中, 就形成了多頭注意力機制.
學習了多頭注意力機制的作用:
這種結(jié)構(gòu)設(shè)計能讓每個注意力機制去優(yōu)化每個詞匯的不同特征部分,從而均衡同一種注意力機制可能產(chǎn)生的偏差,讓詞義擁有來自更多元的表達,實驗表明可以從而提升模型效果.
學習并實現(xiàn)了多頭注意力機制的類: MultiHeadedAttention
因為多頭注意力機制中需要使用多個相同的線性層, 首先實現(xiàn)了克隆函數(shù)clones.
clones函數(shù)的輸入是module,N,分別代表克隆的目標層,和克隆個數(shù).
clones函數(shù)的輸出是裝有N個克隆層的Module列表.
接著實現(xiàn)MultiHeadedAttention類, 它的初始化函數(shù)輸入是h, d_model, dropout分別代表頭數(shù),詞嵌入維度和置零比率.
它的實例化對象輸入是Q, K, V以及掩碼張量mask.
它的實例化對象輸出是通過多頭注意力機制處理的Q的注意力表示.
2.3.4 前饋全連接層
學習目標:
了解什么是前饋全連接層及其它的作用.
掌握前饋全連接層的實現(xiàn)過程.
什么是前饋全連接層:
在Transformer中前饋全連接層就是具有兩層線性層的全連接網(wǎng)絡(luò).
前饋全連接層的作用:
考慮注意力機制可能對復雜過程的擬合程度不夠, 通過增加兩層網(wǎng)絡(luò)來增強模型的能力.
前饋全連接層的代碼分析:
通過類PositionwiseFeedForward來實現(xiàn)前饋全連接層
class PositionwiseFeedForward(nn.Module):
def init(self, d_model, d_ff, dropout=0.1):
“”“初始化函數(shù)有三個輸入?yún)?shù)分別是d_model, d_ff,和dropout=0.1,第一個是線性層的輸入維度也是第二個線性層的輸出維度,
因為我們希望輸入通過前饋全連接層后輸入和輸出的維度不變. 第二個參數(shù)d_ff就是第二個線性層的輸入維度和第一個線性層的輸出維度.
最后一個是dropout置0比率.”""
super(PositionwiseFeedForward, self).init()
ReLU函數(shù)公式: ReLU(x)=max(0, x)
ReLU函數(shù)圖像:
avatar
實例化參數(shù):
d_model = 512
線性變化的維度
d_ff = 64
dropout = 0.2
輸入?yún)?shù):
輸入?yún)?shù)x可以是多頭注意力機制的輸出
x = mha_result
tensor([[[-0.3075, 1.5687, -2.5693, …, -1.1098, 0.0878, -3.3609],
[ 3.8065, -2.4538, -0.3708, …, -1.5205, -1.1488, -1.3984],
[ 2.4190, 0.5376, -2.8475, …, 1.4218, -0.4488, -0.2984],
[ 2.9356, 0.3620, -3.8722, …, -0.7996, 0.1468, 1.0345]],
torch.Size([2, 4, 512])
調(diào)用:
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
ff_result = ff(x)
print(ff_result)
輸出效果:
tensor([[[-1.9488e+00, -3.4060e-01, -1.1216e+00, …, 1.8203e-01,
-2.6336e+00, 2.0917e-03],
[-2.5875e-02, 1.1523e-01, -9.5437e-01, …, -2.6257e-01,
-5.7620e-01, -1.9225e-01],
[-8.7508e-01, 1.0092e+00, -1.6515e+00, …, 3.4446e-02,
-1.5933e+00, -3.1760e-01],
[-2.7507e-01, 4.7225e-01, -2.0318e-01, …, 1.0530e+00,
-3.7910e-01, -9.7730e-01]],
torch.Size([2, 4, 512])
2.3.4 前饋全連接層總結(jié):
學習了什么是前饋全連接層:
在Transformer中前饋全連接層就是具有兩層線性層的全連接網(wǎng)絡(luò).
學習了前饋全連接層的作用:
考慮注意力機制可能對復雜過程的擬合程度不夠, 通過增加兩層網(wǎng)絡(luò)來增強模型的能力.
學習并實現(xiàn)了前饋全連接層的類: PositionwiseFeedForward
它的實例化參數(shù)為d_model, d_ff, dropout, 分別代表詞嵌入維度, 線性變換維度, 和置零比率.
它的輸入?yún)?shù)x, 表示上層的輸出.
它的輸出是經(jīng)過2層線性網(wǎng)絡(luò)變換的特征表示.
2.3.5 規(guī)范化層
學習目標:
了解規(guī)范化層的作用.
掌握規(guī)范化層的實現(xiàn)過程.
規(guī)范化層的作用:
它是所有深層網(wǎng)絡(luò)模型都需要的標準網(wǎng)絡(luò)層,因為隨著網(wǎng)絡(luò)層數(shù)的增加,通過多層的計算后參數(shù)可能開始出現(xiàn)過大或過小的情況,這樣可能會導致學習過程出現(xiàn)異常,模型可能收斂非常的慢. 因此都會在一定層數(shù)后接規(guī)范化層進行數(shù)值的規(guī)范化,使其特征數(shù)值在合理范圍內(nèi).
規(guī)范化層的代碼實現(xiàn):
通過LayerNorm實現(xiàn)規(guī)范化層的類
class LayerNorm(nn.Module):
def init(self, features, eps=1e-6):
“”“初始化函數(shù)有兩個參數(shù), 一個是features, 表示詞嵌入的維度,
另一個是eps它是一個足夠小的數(shù), 在規(guī)范化公式的分母中出現(xiàn),
防止分母為0.默認是1e-6.”""
super(LayerNorm, self).init()
實例化參數(shù):
features = d_model = 512
eps = 1e-6
輸入?yún)?shù):
輸入x來自前饋全連接層的輸出
x = ff_result
tensor([[[-1.9488e+00, -3.4060e-01, -1.1216e+00, …, 1.8203e-01,
-2.6336e+00, 2.0917e-03],
[-2.5875e-02, 1.1523e-01, -9.5437e-01, …, -2.6257e-01,
-5.7620e-01, -1.9225e-01],
[-8.7508e-01, 1.0092e+00, -1.6515e+00, …, 3.4446e-02,
-1.5933e+00, -3.1760e-01],
[-2.7507e-01, 4.7225e-01, -2.0318e-01, …, 1.0530e+00,
-3.7910e-01, -9.7730e-01]],
torch.Size([2, 4, 512])
調(diào)用:
ln = LayerNorm(feature, eps)
ln_result = ln(x)
print(ln_result)
輸出效果:
tensor([[[ 2.2697, 1.3911, -0.4417, …, 0.9937, 0.6589, -1.1902],
[ 1.5876, 0.5182, 0.6220, …, 0.9836, 0.0338, -1.3393],
[ 1.8261, 2.0161, 0.2272, …, 0.3004, 0.5660, -0.9044],
[ 1.5429, 1.3221, -0.2933, …, 0.0406, 1.0603, 1.4666]],
torch.Size([2, 4, 512])
2.3.5 規(guī)范化層總結(jié):
學習了規(guī)范化層的作用:
它是所有深層網(wǎng)絡(luò)模型都需要的標準網(wǎng)絡(luò)層,因為隨著網(wǎng)絡(luò)層數(shù)的增加,通過多層的計算后參數(shù)可能開始出現(xiàn)過大或過小的情況,這樣可能會導致學習過程出現(xiàn)異常,模型可能收斂非常的慢. 因此都會在一定層數(shù)后接規(guī)范化層進行數(shù)值的規(guī)范化,使其特征數(shù)值在合理范圍內(nèi).
學習并實現(xiàn)了規(guī)范化層的類: LayerNorm
它的實例化參數(shù)有兩個, features和eps,分別表示詞嵌入特征大小,和一個足夠小的數(shù).
它的輸入?yún)?shù)x代表來自上一層的輸出.
它的輸出就是經(jīng)過規(guī)范化的特征表示.
2.3.6 子層連接結(jié)構(gòu)
學習目標:
了解什么是子層連接結(jié)構(gòu).
掌握子層連接結(jié)構(gòu)的實現(xiàn)過程.
什么是子層連接結(jié)構(gòu):
如圖所示,輸入到每個子層以及規(guī)范化層的過程中,還使用了殘差鏈接(跳躍連接),因此我們把這一部分結(jié)構(gòu)整體叫做子層連接(代表子層及其鏈接結(jié)構(gòu)),在每個編碼器層中,都有兩個子層,這兩個子層加上周圍的鏈接結(jié)構(gòu)就形成了兩個子層連接結(jié)構(gòu).
子層連接結(jié)構(gòu)圖:
avatar
avatar
子層連接結(jié)構(gòu)的代碼分析:
使用SublayerConnection來實現(xiàn)子層連接結(jié)構(gòu)的類
class SublayerConnection(nn.Module):
def init(self, size, dropout=0.1):
“”“它輸入?yún)?shù)有兩個, size以及dropout, size一般是都是詞嵌入維度的大小,
dropout本身是對模型結(jié)構(gòu)中的節(jié)點數(shù)進行隨機抑制的比率,
又因為節(jié)點被抑制等效就是該節(jié)點的輸出都是0,因此也可以把dropout看作是對輸出矩陣的隨機置0的比率.
“””
super(SublayerConnection, self).init()
# 實例化了規(guī)范化對象self.norm
self.norm = LayerNorm(size)
# 又使用nn中預定義的droupout實例化一個self.dropout對象.
self.dropout = nn.Dropout(p=dropout)
實例化參數(shù)
size = 512
dropout = 0.2
head = 8
d_model = 512
輸入?yún)?shù):
令x為位置編碼器的輸出
x = pe_result
mask = Variable(torch.zeros(8, 4, 4))
假設(shè)子層中裝的是多頭注意力層, 實例化這個類
self_attn = MultiHeadedAttention(head, d_model)
使用lambda獲得一個函數(shù)類型的子層
sublayer = lambda x: self_attn(x, x, x, mask)
調(diào)用:
sc = SublayerConnection(size, dropout)
sc_result = sc(x, sublayer)
print(sc_result)
print(sc_result.shape)
輸出效果:
tensor([[[ 14.8830, 22.4106, -31.4739, …, 21.0882, -10.0338, -0.2588],
[-25.1435, 2.9246, -16.1235, …, 10.5069, -7.1007, -3.7396],
[ 0.1374, 32.6438, 12.3680, …, -12.0251, -40.5829, 2.2297],
[-13.3123, 55.4689, 9.5420, …, -12.6622, 23.4496, 21.1531]],
torch.Size([2, 4, 512])
2.3.6 子層連接結(jié)構(gòu)總結(jié):
什么是子層連接結(jié)構(gòu):
如圖所示,輸入到每個子層以及規(guī)范化層的過程中,還使用了殘差鏈接(跳躍連接),因此我們把這一部分結(jié)構(gòu)整體叫做子層連接(代表子層及其鏈接結(jié)構(gòu)), 在每個編碼器層中,都有兩個子層,這兩個子層加上周圍的鏈接結(jié)構(gòu)就形成了兩個子層連接結(jié)構(gòu).
學習并實現(xiàn)了子層連接結(jié)構(gòu)的類: SublayerConnection
類的初始化函數(shù)輸入?yún)?shù)是size, dropout, 分別代表詞嵌入大小和置零比率.
它的實例化對象輸入?yún)?shù)是x, sublayer, 分別代表上一層輸出以及子層的函數(shù)表示.
它的輸出就是通過子層連接結(jié)構(gòu)處理的輸出.
2.3.7 編碼器層
學習目標:
了解編碼器層的作用.
掌握編碼器層的實現(xiàn)過程.
編碼器層的作用:
作為編碼器的組成單元, 每個編碼器層完成一次對輸入的特征提取過程, 即編碼過程.
編碼器層的構(gòu)成圖:
avatar
編碼器層的代碼分析:
使用EncoderLayer類實現(xiàn)編碼器層
class EncoderLayer(nn.Module):
def init(self, size, self_attn, feed_forward, dropout):
“”“它的初始化函數(shù)參數(shù)有四個,分別是size,其實就是我們詞嵌入維度的大小,它也將作為我們編碼器層的大小,
第二個self_attn,之后我們將傳入多頭自注意力子層實例化對象, 并且是自注意力機制,
第三個是feed_froward, 之后我們將傳入前饋全連接層實例化對象, 最后一個是置0比率dropout.”""
super(EncoderLayer, self).init()
實例化參數(shù):
size = 512
head = 8
d_model = 512
d_ff = 64
x = pe_result
dropout = 0.2
self_attn = MultiHeadedAttention(head, d_model)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
mask = Variable(torch.zeros(8, 4, 4))
調(diào)用:
el = EncoderLayer(size, self_attn, ff, dropout)
el_result = el(x, mask)
print(el_result)
print(el_result.shape)
輸出效果:
tensor([[[ 33.6988, -30.7224, 20.9575, …, 5.2968, -48.5658, 20.0734],
[-18.1999, 34.2358, 40.3094, …, 10.1102, 58.3381, 58.4962],
[ 32.1243, 16.7921, -6.8024, …, 23.0022, -18.1463, -17.1263],
[ -9.3475, -3.3605, -55.3494, …, 43.6333, -0.1900, 0.1625]],
torch.Size([2, 4, 512])
2.3.7 編碼器層總結(jié):
學習了編碼器層的作用:
作為編碼器的組成單元, 每個編碼器層完成一次對輸入的特征提取過程, 即編碼過程.
學習并實現(xiàn)了編碼器層的類: EncoderLayer
類的初始化函數(shù)共有4個, 別是size,其實就是我們詞嵌入維度的大小. 第二個self_attn,之后我們將傳入多頭自注意力子層實例化對象, 并且是自注意力機制. 第三個是feed_froward, 之后我們將傳入前饋全連接層實例化對象. 最后一個是置0比率dropout.
實例化對象的輸入?yún)?shù)有2個,x代表來自上一層的輸出, mask代表掩碼張量.
它的輸出代表經(jīng)過整個編碼層的特征表示.
2.3.8 編碼器
學習目標:
了解編碼器的作用.
掌握編碼器的實現(xiàn)過程.
編碼器的作用:
編碼器用于對輸入進行指定的特征提取過程, 也稱為編碼, 由N個編碼器層堆疊而成.
編碼器的結(jié)構(gòu)圖:
avatar
編碼器的代碼分析:
使用Encoder類來實現(xiàn)編碼器
class Encoder(nn.Module):
def init(self, layer, N):
“”“初始化函數(shù)的兩個參數(shù)分別代表編碼器層和編碼器層的個數(shù)”""
super(Encoder, self).init()
# 首先使用clones函數(shù)克隆N個編碼器層放在self.layers中
self.layers = clones(layer, N)
# 再初始化一個規(guī)范化層, 它將用在編碼器的最后面.
self.norm = LayerNorm(layer.size)
實例化參數(shù):
第一個實例化參數(shù)layer, 它是一個編碼器層的實例化對象, 因此需要傳入編碼器層的參數(shù)
又因為編碼器層中的子層是不共享的, 因此需要使用深度拷貝各個對象.
size = 512
head = 8
d_model = 512
d_ff = 64
c = copy.deepcopy
attn = MultiHeadedAttention(head, d_model)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
dropout = 0.2
layer = EncoderLayer(size, c(attn), c(ff), dropout)
編碼器中編碼器層的個數(shù)N
N = 8
mask = Variable(torch.zeros(8, 4, 4))
調(diào)用:
en = Encoder(layer, N)
en_result = en(x, mask)
print(en_result)
print(en_result.shape)
輸出效果:
tensor([[[-0.2081, -0.3586, -0.2353, …, 2.5646, -0.2851, 0.0238],
[ 0.7957, -0.5481, 1.2443, …, 0.7927, 0.6404, -0.0484],
[-0.1212, 0.4320, -0.5644, …, 1.3287, -0.0935, -0.6861],
[-0.3937, -0.6150, 2.2394, …, -1.5354, 0.7981, 1.7907]],
torch.Size([2, 4, 512])
2.3.8 編碼器總結(jié):
學習了編碼器的作用:
編碼器用于對輸入進行指定的特征提取過程, 也稱為編碼, 由N個編碼器層堆疊而成.
學習并實現(xiàn)了編碼器的類: Encoder
類的初始化函數(shù)參數(shù)有兩個,分別是layer和N,代表編碼器層和編碼器層的個數(shù).
forward函數(shù)的輸入?yún)?shù)也有兩個, 和編碼器層的forward相同, x代表上一層的輸出, mask代碼掩碼張量.
編碼器類的輸出就是Transformer中編碼器的特征提取表示, 它將成為解碼器的輸入的一部分.
2.4 解碼器部分實現(xiàn)
學習目標
了解解碼器中各個組成部分的作用.
掌握解碼器中各個組成部分的實現(xiàn)過程.
解碼器部分:
由N個解碼器層堆疊而成
每個解碼器層由三個子層連接結(jié)構(gòu)組成
第一個子層連接結(jié)構(gòu)包括一個多頭自注意力子層和規(guī)范化層以及一個殘差連接
第二個子層連接結(jié)構(gòu)包括一個多頭注意力子層和規(guī)范化層以及一個殘差連接
第三個子層連接結(jié)構(gòu)包括一個前饋全連接子層和規(guī)范化層以及一個殘差連接
avatar
說明:
解碼器層中的各個部分,如,多頭注意力機制,規(guī)范化層,前饋全連接網(wǎng)絡(luò),子層連接結(jié)構(gòu)都與編碼器中的實現(xiàn)相同. 因此這里可以直接拿來構(gòu)建解碼器層.
2.4.1 解碼器層
學習目標:
了解解碼器層的作用.
掌握解碼器層的實現(xiàn)過程.
解碼器層的作用:
作為解碼器的組成單元, 每個解碼器層根據(jù)給定的輸入向目標方向進行特征提取操作,即解碼過程.
解碼器層的代碼實現(xiàn):
使用DecoderLayer的類實現(xiàn)解碼器層
class DecoderLayer(nn.Module):
def init(self, size, self_attn, src_attn, feed_forward, dropout):
“”“初始化函數(shù)的參數(shù)有5個, 分別是size,代表詞嵌入的維度大小, 同時也代表解碼器層的尺寸,
第二個是self_attn,多頭自注意力對象,也就是說這個注意力機制需要Q=K=V,
第三個是src_attn,多頭注意力對象,這里Q!=K=V, 第四個是前饋全連接層對象,最后就是droupout置0比率.
“””
super(DecoderLayer, self).init()
# 在初始化函數(shù)中, 主要就是將這些輸入傳到類中
self.size = size
self.self_attn = self_attn
self.src_attn = src_attn
self.feed_forward = feed_forward
# 按照結(jié)構(gòu)圖使用clones函數(shù)克隆三個子層連接對象.
self.sublayer = clones(SublayerConnection(size, dropout), 3)
實例化參數(shù):
類的實例化參數(shù)與解碼器層類似, 相比多出了src_attn, 但是和self_attn是同一個類.
head = 8
size = 512
d_model = 512
d_ff = 64
dropout = 0.2
self_attn = src_attn = MultiHeadedAttention(head, d_model, dropout)
前饋全連接層也和之前相同
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
輸入?yún)?shù):
x是來自目標數(shù)據(jù)的詞嵌入表示, 但形式和源數(shù)據(jù)的詞嵌入表示相同, 這里使用per充當.
x = pe_result
memory是來自編碼器的輸出
memory = en_result
實際中source_mask和target_mask并不相同, 這里為了方便計算使他們都為mask
mask = Variable(torch.zeros(8, 4, 4))
source_mask = target_mask = mask
調(diào)用:
dl = DecoderLayer(size, self_attn, src_attn, ff, dropout)
dl_result = dl(x, memory, source_mask, target_mask)
print(dl_result)
print(dl_result.shape)
輸出效果:
tensor([[[ 1.9604e+00, 3.9288e+01, -5.2422e+01, …, 2.1041e-01,
-5.5063e+01, 1.5233e-01],
[ 1.0135e-01, -3.7779e-01, 6.5491e+01, …, 2.8062e+01,
-3.7780e+01, -3.9577e+01],
[ 1.9526e+01, -2.5741e+01, 2.6926e-01, …, -1.5316e+01,
1.4543e+00, 2.7714e+00],
[-2.1528e+01, 2.0141e+01, 2.1999e+01, …, 2.2099e+00,
-1.7267e+01, -1.6687e+01]],
torch.Size([2, 4, 512])
2.4.1 解碼器層總結(jié):
學習了解碼器層的作用:
作為解碼器的組成單元, 每個解碼器層根據(jù)給定的輸入向目標方向進行特征提取操作,即解碼過程.
學習并實現(xiàn)了解碼器層的類: DecoderLayer
類的初始化函數(shù)的參數(shù)有5個, 分別是size,代表詞嵌入的維度大小, 同時也代表解碼器層的尺寸,第二個是self_attn,多頭自注意力對象,也就是說這個注意力機制需要Q=K=V,第三個是src_attn,多頭注意力對象,這里Q!=K=V, 第四個是前饋全連接層對象,最后就是droupout置0比率.
forward函數(shù)的參數(shù)有4個,分別是來自上一層的輸入x,來自編碼器層的語義存儲變量mermory, 以及源數(shù)據(jù)掩碼張量和目標數(shù)據(jù)掩碼張量.
最終輸出了由編碼器輸入和目標數(shù)據(jù)一同作用的特征提取結(jié)果.
2.4.2 解碼器
學習目標:
了解解碼器的作用.
掌握解碼器的實現(xiàn)過程.
解碼器的作用:
根據(jù)編碼器的結(jié)果以及上一次預測的結(jié)果, 對下一次可能出現(xiàn)的’值’進行特征表示.
解碼器的代碼分析:
使用類Decoder來實現(xiàn)解碼器
class Decoder(nn.Module):
def init(self, layer, N):
“”“初始化函數(shù)的參數(shù)有兩個,第一個就是解碼器層layer,第二個是解碼器層的個數(shù)N.”""
super(Decoder, self).init()
# 首先使用clones方法克隆了N個layer,然后實例化了一個規(guī)范化層.
# 因為數(shù)據(jù)走過了所有的解碼器層后最后要做規(guī)范化處理.
self.layers = clones(layer, N)
self.norm = LayerNorm(layer.size)
實例化參數(shù):
分別是解碼器層layer和解碼器層的個數(shù)N
size = 512
d_model = 512
head = 8
d_ff = 64
dropout = 0.2
c = copy.deepcopy
attn = MultiHeadedAttention(head, d_model)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
layer = DecoderLayer(d_model, c(attn), c(attn), c(ff), dropout)
N = 8
輸入?yún)?shù):
輸入?yún)?shù)與解碼器層的輸入?yún)?shù)相同
x = pe_result
memory = en_result
mask = Variable(torch.zeros(8, 4, 4))
source_mask = target_mask = mask
調(diào)用:
de = Decoder(layer, N)
de_result = de(x, memory, source_mask, target_mask)
print(de_result)
print(de_result.shape)
輸出效果:
tensor([[[ 0.9898, -0.3216, -1.2439, …, 0.7427, -0.0717, -0.0814],
[-0.7432, 0.6985, 1.5551, …, 0.5232, -0.5685, 1.3387],
[ 0.2149, 0.5274, -1.6414, …, 0.7476, 0.5082, -3.0132],
[ 0.4408, 0.9416, 0.4522, …, -0.1506, 1.5591, -0.6453]],
torch.Size([2, 4, 512])
2.4.2 解碼器總結(jié):
學習了解碼器的作用:
根據(jù)編碼器的結(jié)果以及上一次預測的結(jié)果, 對下一次可能出現(xiàn)的’值’進行特征表示.
學習并實現(xiàn)了解碼器的類: Decoder
類的初始化函數(shù)的參數(shù)有兩個,第一個就是解碼器層layer,第二個是解碼器層的個數(shù)N.
forward函數(shù)中的參數(shù)有4個,x代表目標數(shù)據(jù)的嵌入表示,memory是編碼器層的輸出,src_mask, tgt_mask代表源數(shù)據(jù)和目標數(shù)據(jù)的掩碼張量.
輸出解碼過程的最終特征表示.
2.5 輸出部分實現(xiàn)
學習目標
了解線性層和softmax的作用.
掌握線性層和softmax的實現(xiàn)過程.
輸出部分包含:
線性層
softmax層
avatar
線性層的作用
通過對上一步的線性變化得到指定維度的輸出, 也就是轉(zhuǎn)換維度的作用.
softmax層的作用
使最后一維的向量中的數(shù)字縮放到0-1的概率值域內(nèi), 并滿足他們的和為1.
線性層和softmax層的代碼分析:
nn.functional工具包裝載了網(wǎng)絡(luò)層中那些只進行計算, 而沒有參數(shù)的層
import torch.nn.functional as F
將線性層和softmax計算層一起實現(xiàn), 因為二者的共同目標是生成最后的結(jié)構(gòu)
因此把類的名字叫做Generator, 生成器類
class Generator(nn.Module):
def init(self, d_model, vocab_size):
“”“初始化函數(shù)的輸入?yún)?shù)有兩個, d_model代表詞嵌入維度, vocab_size代表詞表大小.”""
super(Generator, self).init()
# 首先就是使用nn中的預定義線性層進行實例化, 得到一個對象self.project等待使用,
# 這個線性層的參數(shù)有兩個, 就是初始化函數(shù)傳進來的兩個參數(shù): d_model, vocab_size
self.project = nn.Linear(d_model, vocab_size)
nn.Linear演示:
m = nn.Linear(20, 30)
input = torch.randn(128, 20)
output = m(input)
print(output.size())
torch.Size([128, 30])
實例化參數(shù):
詞嵌入維度是512維
d_model = 512
詞表大小是1000
vocab_size = 1000
輸入?yún)?shù):
輸入x是上一層網(wǎng)絡(luò)的輸出, 我們使用來自解碼器層的輸出
x = de_result
調(diào)用:
gen = Generator(d_model, vocab_size)
gen_result = gen(x)
print(gen_result)
print(gen_result.shape)
輸出效果:
tensor([[[-7.8098, -7.5260, -6.9244, …, -7.6340, -6.9026, -7.5232],
[-6.9093, -7.3295, -7.2972, …, -6.6221, -7.2268, -7.0772],
[-7.0263, -7.2229, -7.8533, …, -6.7307, -6.9294, -7.3042],
[-6.5045, -6.0504, -6.6241, …, -5.9063, -6.5361, -7.1484]],
torch.Size([2, 4, 1000])
小節(jié)總結(jié)
學習了輸出部分包含:
線性層
softmax層
線性層的作用:
通過對上一步的線性變化得到指定維度的輸出, 也就是轉(zhuǎn)換維度的作用.
softmax層的作用:
使最后一維的向量中的數(shù)字縮放到0-1的概率值域內(nèi), 并滿足他們的和為1.
學習并實現(xiàn)了線性層和softmax層的類: Generator
初始化函數(shù)的輸入?yún)?shù)有兩個, d_model代表詞嵌入維度, vocab_size代表詞表大小.
forward函數(shù)接受上一層的輸出.
最終獲得經(jīng)過線性層和softmax層處理的結(jié)果.
2.6 模型構(gòu)建
學習目標
掌握編碼器-解碼器結(jié)構(gòu)的實現(xiàn)過程.
掌握Transformer模型的構(gòu)建過程.
通過上面的小節(jié), 我們已經(jīng)完成了所有組成部分的實現(xiàn), 接下來就來實現(xiàn)完整的編碼器-解碼器結(jié)構(gòu).
Transformer總體架構(gòu)圖:
avatar
編碼器-解碼器結(jié)構(gòu)的代碼實現(xiàn)
使用EncoderDecoder類來實現(xiàn)編碼器-解碼器結(jié)構(gòu)
class EncoderDecoder(nn.Module):
def init(self, encoder, decoder, source_embed, target_embed, generator):
“”“初始化函數(shù)中有5個參數(shù), 分別是編碼器對象, 解碼器對象,
源數(shù)據(jù)嵌入函數(shù), 目標數(shù)據(jù)嵌入函數(shù), 以及輸出部分的類別生成器對象
“””
super(EncoderDecoder, self).init()
# 將參數(shù)傳入到類中
self.encoder = encoder
self.decoder = decoder
self.src_embed = source_embed
self.tgt_embed = target_embed
self.generator = generator
實例化參數(shù)
vocab_size = 1000
d_model = 512
encoder = en
decoder = de
source_embed = nn.Embedding(vocab_size, d_model)
target_embed = nn.Embedding(vocab_size, d_model)
generator = gen
輸入?yún)?shù):
假設(shè)源數(shù)據(jù)與目標數(shù)據(jù)相同, 實際中并不相同
source = target = Variable(torch.LongTensor([[100, 2, 421, 508], [491, 998, 1, 221]]))
假設(shè)src_mask與tgt_mask相同,實際中并不相同
source_mask = target_mask = Variable(torch.zeros(8, 4, 4))
調(diào)用:
ed = EncoderDecoder(encoder, decoder, source_embed, target_embed, generator)
ed_result = ed(source, target, source_mask, target_mask)
print(ed_result)
print(ed_result.shape)
輸出效果:
tensor([[[ 0.2102, -0.0826, -0.0550, …, 1.5555, 1.3025, -0.6296],
[ 0.8270, -0.5372, -0.9559, …, 0.3665, 0.4338, -0.7505],
[ 0.4956, -0.5133, -0.9323, …, 1.0773, 1.1913, -0.6240],
[ 0.5770, -0.6258, -0.4833, …, 0.1171, 1.0069, -1.9030]],
torch.Size([2, 4, 512])
接著將基于以上結(jié)構(gòu)構(gòu)建用于訓練的模型.
Tansformer模型構(gòu)建過程的代碼分析
def make_model(source_vocab, target_vocab, N=6,
d_model=512, d_ff=2048, head=8, dropout=0.1):
“”“該函數(shù)用來構(gòu)建模型, 有7個參數(shù),分別是源數(shù)據(jù)特征(詞匯)總數(shù),目標數(shù)據(jù)特征(詞匯)總數(shù),
編碼器和解碼器堆疊數(shù),詞向量映射維度,前饋全連接網(wǎng)絡(luò)中變換矩陣的維度,
多頭注意力結(jié)構(gòu)中的多頭數(shù),以及置零比率dropout.”""
nn.init.xavier_uniform演示:
結(jié)果服從均勻分布U(-a, a)
w = torch.empty(3, 5)
w = nn.init.xavier_uniform_(w, gain=nn.init.calculate_gain(‘relu’))
w
tensor([[-0.7742, 0.5413, 0.5478, -0.4806, -0.2555],
[-0.8358, 0.4673, 0.3012, 0.3882, -0.6375],
[ 0.4622, -0.0794, 0.1851, 0.8462, -0.3591]])
輸入?yún)?shù):
source_vocab = 11
target_vocab = 11
N = 6
其他參數(shù)都使用默認值
調(diào)用:
if name == ‘main’:
res = make_model(source_vocab, target_vocab, N)
print(res)
輸出效果:
根據(jù)Transformer結(jié)構(gòu)圖構(gòu)建的最終模型結(jié)構(gòu)
EncoderDecoder(
(encoder): Encoder(
(layers): ModuleList(
(0): EncoderLayer(
(self_attn): MultiHeadedAttention(
(linears): ModuleList(
(0): Linear(in_features=512, out_features=512)
(1): Linear(in_features=512, out_features=512)
(2): Linear(in_features=512, out_features=512)
(3): Linear(in_features=512, out_features=512)
)
(dropout): Dropout(p=0.1)
)
(feed_forward): PositionwiseFeedForward(
(w_1): Linear(in_features=512, out_features=2048)
(w_2): Linear(in_features=2048, out_features=512)
(dropout): Dropout(p=0.1)
)
(sublayer): ModuleList(
(0): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
(1): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
)
)
(1): EncoderLayer(
(self_attn): MultiHeadedAttention(
(linears): ModuleList(
(0): Linear(in_features=512, out_features=512)
(1): Linear(in_features=512, out_features=512)
(2): Linear(in_features=512, out_features=512)
(3): Linear(in_features=512, out_features=512)
)
(dropout): Dropout(p=0.1)
)
(feed_forward): PositionwiseFeedForward(
(w_1): Linear(in_features=512, out_features=2048)
(w_2): Linear(in_features=2048, out_features=512)
(dropout): Dropout(p=0.1)
)
(sublayer): ModuleList(
(0): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
(1): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
)
)
)
(norm): LayerNorm(
)
)
(decoder): Decoder(
(layers): ModuleList(
(0): DecoderLayer(
(self_attn): MultiHeadedAttention(
(linears): ModuleList(
(0): Linear(in_features=512, out_features=512)
(1): Linear(in_features=512, out_features=512)
(2): Linear(in_features=512, out_features=512)
(3): Linear(in_features=512, out_features=512)
)
(dropout): Dropout(p=0.1)
)
(src_attn): MultiHeadedAttention(
(linears): ModuleList(
(0): Linear(in_features=512, out_features=512)
(1): Linear(in_features=512, out_features=512)
(2): Linear(in_features=512, out_features=512)
(3): Linear(in_features=512, out_features=512)
)
(dropout): Dropout(p=0.1)
)
(feed_forward): PositionwiseFeedForward(
(w_1): Linear(in_features=512, out_features=2048)
(w_2): Linear(in_features=2048, out_features=512)
(dropout): Dropout(p=0.1)
)
(sublayer): ModuleList(
(0): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
(1): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
(2): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
)
)
(1): DecoderLayer(
(self_attn): MultiHeadedAttention(
(linears): ModuleList(
(0): Linear(in_features=512, out_features=512)
(1): Linear(in_features=512, out_features=512)
(2): Linear(in_features=512, out_features=512)
(3): Linear(in_features=512, out_features=512)
)
(dropout): Dropout(p=0.1)
)
(src_attn): MultiHeadedAttention(
(linears): ModuleList(
(0): Linear(in_features=512, out_features=512)
(1): Linear(in_features=512, out_features=512)
(2): Linear(in_features=512, out_features=512)
(3): Linear(in_features=512, out_features=512)
)
(dropout): Dropout(p=0.1)
)
(feed_forward): PositionwiseFeedForward(
(w_1): Linear(in_features=512, out_features=2048)
(w_2): Linear(in_features=2048, out_features=512)
(dropout): Dropout(p=0.1)
)
(sublayer): ModuleList(
(0): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
(1): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
(2): SublayerConnection(
(norm): LayerNorm(
)
(dropout): Dropout(p=0.1)
)
)
)
)
(norm): LayerNorm(
)
)
(src_embed): Sequential(
(0): Embeddings(
(lut): Embedding(11, 512)
)
(1): PositionalEncoding(
(dropout): Dropout(p=0.1)
)
)
(tgt_embed): Sequential(
(0): Embeddings(
(lut): Embedding(11, 512)
)
(1): PositionalEncoding(
(dropout): Dropout(p=0.1)
)
)
(generator): Generator(
(proj): Linear(in_features=512, out_features=11)
)
)
小節(jié)總結(jié)
學習并實現(xiàn)了編碼器-解碼器結(jié)構(gòu)的類: EncoderDecoder
類的初始化函數(shù)傳入5個參數(shù), 分別是編碼器對象, 解碼器對象, 源數(shù)據(jù)嵌入函數(shù), 目標數(shù)據(jù)嵌入函數(shù), 以及輸出部分的類別生成器對象.
類中共實現(xiàn)三個函數(shù), forward, encode, decode
forward是主要邏輯函數(shù), 有四個參數(shù), source代表源數(shù)據(jù), target代表目標數(shù)據(jù), source_mask和target_mask代表對應的掩碼張量.
encode是編碼函數(shù), 以source和source_mask為參數(shù).
decode是解碼函數(shù), 以memory即編碼器的輸出, source_mask, target, target_mask為參數(shù)
學習并實現(xiàn)了模型構(gòu)建函數(shù): make_model
有7個參數(shù),分別是源數(shù)據(jù)特征(詞匯)總數(shù),目標數(shù)據(jù)特征(詞匯)總數(shù),編碼器和解碼器堆疊數(shù),詞向量映射維度,前饋全連接網(wǎng)絡(luò)中變換矩陣的維度,多頭注意力結(jié)構(gòu)中的多頭數(shù),以及置零比率dropout.
該函數(shù)最后返回一個構(gòu)建好的模型對象.
上一頁第一章:Transformer背景介紹
?Copyright 2019, itcast.cn.
Made with Material for MkDocs
跳轉(zhuǎn)至
logo
遷移學習
第一章:fasttext工具的使用
logo
遷移學習
第一章:fasttext工具的使用
第二章:遷移學習
目錄
1.1 認識fasttext工具
學習目標
1.2 進行文本分類
學習目標
什么是文本分類
文本分類的種類
使用fasttext工具進行文本分類的過程
第一步: 獲取數(shù)據(jù)
第二步: 訓練集與驗證集的劃分
第三步: 訓練模型
第四步: 使用模型進行預測并評估
第五步: 模型調(diào)優(yōu)
第六步: 模型保存與重加載
小節(jié)總結(jié)
1.3 訓練詞向量
學習目標
使用fasttext工具訓練詞向量的過程
第一步: 獲取數(shù)據(jù)
第二步: 訓練詞向量
第三步: 模型超參數(shù)設(shè)定
第四步: 模型效果檢驗
第五步: 模型的保存與重加載
小節(jié)總結(jié)
1.4 詞向量遷移
學習目標
如何使用fasttext進行詞向量模型遷移
第一步: 下載詞向量模型壓縮的bin.gz文件
第二步: 解壓bin.gz文件到bin文件
第三步: 加載bin文件獲取詞向量
第四步: 利用鄰近詞進行效果檢驗
小節(jié)總結(jié)
第一章:fasttext工具的使用
1.1 認識fasttext工具
學習目標
了解fasttext工具的作用.
了解fasttext工具的優(yōu)勢及其原因.
掌握fasttext的安裝方法.
作為NLP工程領(lǐng)域常用的工具包, fasttext有兩大作用:
進行文本分類
訓練詞向量
fasttext工具包的優(yōu)勢:
正如它的名字, 在保持較高精度的情況下, 快速的進行訓練和預測是fasttext的最大優(yōu)勢.
fasttext優(yōu)勢的原因:
fasttext工具包中內(nèi)含的fasttext模型具有十分簡單的網(wǎng)絡(luò)結(jié)構(gòu).
使用fasttext模型訓練詞向量時使用層次softmax結(jié)構(gòu), 來提升超多類別下的模型性能.
由于fasttext模型過于簡單無法捕捉詞序特征, 因此會進行n-gram特征提取以彌補模型缺陷提升精度.
fasttext的安裝:
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
使用pip安裝python中的fasttext工具包
$ sudo pip install .
驗證安裝:
Python 3.7.3 (default, Mar 27 2019, 22:11:17)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type “help”, “copyright”, “credits” or “l(fā)icense” for more information.
import fasttext
1.2 進行文本分類
學習目標
了解什么是文本分類及其種類.
掌握fasttext工具進行文本分類的過程.
什么是文本分類
文本分類的是將文檔(例如電子郵件,帖子,文本消息,產(chǎn)品評論等)分配給一個或多個類別. 當今文本分類的實現(xiàn)多是使用機器學習方法從訓練數(shù)據(jù)中提取分類規(guī)則以進行分類, 因此構(gòu)建文本分類器需要帶標簽的數(shù)據(jù).
文本分類的種類
二分類:
文本被分類兩個類別中, 往往這兩個類別是對立面, 比如: 判斷一句評論是好評還是差評.
單標簽多分類:
文本被分入到多個類別中, 且每條文本只能屬于某一個類別(即被打上某一個標簽), 比如: 輸入一個人名, 判斷它是來自哪個國家的人名.
多標簽多分類:
文本被分人到多個類別中, 但每條文本可以屬于多個類別(即被打上多個標簽), 比如: 輸入一段描述, 判斷可能是和哪些興趣愛好有關(guān), 一段描述中可能即討論了美食, 又太討論了游戲愛好.
使用fasttext工具進行文本分類的過程
第一步: 獲取數(shù)據(jù)
第二步: 訓練集與驗證集的劃分
第三步: 訓練模型
第四步: 使用模型進行預測并評估
第五步: 模型調(diào)優(yōu)
第六步: 模型保存與重加載
第一步: 獲取數(shù)據(jù)
獲取烹飪相關(guān)的數(shù)據(jù)集, 它是由facebook AI實驗室提供的演示數(shù)據(jù)集
$ wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz && tar xvzf cooking.stackexchange.tar.gz
查看數(shù)據(jù)的前10條
$ head cooking.stackexchange.txt
__label__sauce __label__cheese How much does potato starch affect a cheese sauce recipe?
__label__food-safety __label__acidity Dangerous pathogens capable of growing in acidic environments
__label__cast-iron __label__stove How do I cover up the white spots on my cast iron stove?
__label__restaurant Michelin Three Star Restaurant; but if the chef is not there
__label__knife-skills __label__dicing Without knife skills, how can I quickly and accurately dice vegetables?
__label__storage-method __label__equipment __label__bread What’s the purpose of a bread box?
__label__baking __label__food-safety __label__substitutions __label__peanuts how to seperate peanut oil from roasted peanuts at home?
__label__chocolate American equivalent for British chocolate terms
__label__baking __label__oven __label__convection Fan bake vs bake
__label__sauce __label__storage-lifetime __label__acidity __label__mayonnaise Regulation and balancing of readymade packed mayonnaise and other sauces
數(shù)據(jù)說明:
cooking.stackexchange.txt中的每一行都包含一個標簽列表,后跟相應的文檔, 標簽列表以類似"__label__sauce __label__cheese"的形式展現(xiàn), 代表有兩個標簽sauce和cheese, 所有標簽__label__均以前綴開頭,這是fastText識別標簽或單詞的方式. 標簽之后的一段話就是文本信息.如: How much does potato starch affect a cheese sauce recipe?
第二步: 訓練集與驗證集的劃分
查看數(shù)據(jù)總數(shù)
$ wc cooking.stackexchange.txt
15404 169582 1401900 cooking.stackexchange.txt
12404條數(shù)據(jù)作為訓練數(shù)據(jù)
$ head -n 12404 cooking.stackexchange.txt > cooking.train
3000條數(shù)據(jù)作為驗證數(shù)據(jù)
$ tail -n 3000 cooking.stackexchange.txt > cooking.valid
第三步: 訓練模型
代碼運行在python解釋器中
導入fasttext
import fasttext
使用fasttext的train_supervised方法進行文本分類模型的訓練
model = fasttext.train_supervised(input=“cooking.train”)
獲得結(jié)果
Read 0M words
不重復的詞匯總數(shù)
Number of words: 14543
標簽總數(shù)
Number of labels: 735
Progress: 訓練進度, 因為我們這里顯示的是最后的訓練完成信息, 所以進度是100%
words/sec/thread: 每個線程每秒處理的平均詞匯數(shù)
lr: 當前的學習率, 因為訓練完成所以學習率是0
avg.loss: 訓練過程的平均損失
ETA: 預計剩余訓練時間, 因為已訓練完成所以是0
Progress: 100.0% words/sec/thread: 60162 lr: 0.000000 avg.loss: 10.056812 ETA: 0h 0m 0s
第四步: 使用模型進行預測并評估
使用模型預測一段輸入文本, 通過我們常識, 可知預測是正確的, 但是對應預測概率并不大
model.predict(“Which baking dish is best to bake a banana bread ?”)
元組中的第一項代表標簽, 第二項代表對應的概率
((’__label__baking’,), array([0.06550845]))
通過我們常識可知預測是錯誤的
model.predict(“Why not put knives in the dishwasher?”)
((’__label__food-safety’,), array([0.07541209]))
為了評估模型到底表現(xiàn)如何, 我們在3000條的驗證集上進行測試
model.test(“cooking.valid”)
元組中的每項分別代表, 驗證集樣本數(shù)量, 精度以及召回率
我們看到模型精度和召回率表現(xiàn)都很差, 接下來我們講學習如何進行優(yōu)化.
(3000, 0.124, 0.0541)
第五步: 模型調(diào)優(yōu)
原始數(shù)據(jù)處理:
通過查看數(shù)據(jù), 我們發(fā)現(xiàn)數(shù)據(jù)中存在許多標點符號與單詞相連以及大小寫不統(tǒng)一,
這些因素對我們最終的分類目標沒有益處, 反是增加了模型提取分類規(guī)律的難度,
因此我們選擇將它們?nèi)コ蜣D(zhuǎn)化
處理前的部分數(shù)據(jù)
__label__fish Arctic char available in North-America
__label__pasta __label__salt __label__boiling When cooking pasta in salted water how much of the salt is absorbed?
__label__coffee Emergency Coffee via Chocolate Covered Coffee Beans?
__label__cake Non-beet alternatives to standard red food dye
__label__cheese __label__lentils Could cheese “halt” the tenderness of cooking lentils?
__label__asian-cuisine __label__chili-peppers __label__kimchi __label__korean-cuisine What kind of peppers are used in Gochugaru ()?
__label__consistency Pavlova Roll failure
__label__eggs __label__bread What qualities should I be looking for when making the best French Toast?
__label__meat __label__flour __label__stews __label__braising Coating meat in flour before browning, bad idea?
__label__food-safety Raw roast beef on the edge of safe?
__label__pork __label__food-identification How do I determine the cut of a pork steak prior to purchasing it?
通過服務器終端進行簡單的數(shù)據(jù)預處理
使標點符號與單詞分離并統(tǒng)一使用小寫字母
cat cooking.stackexchange.txt | sed -e “s/([.!?,’/()])/ \1 /g” | tr “[:upper:]” “[:lower:]” > cooking.preprocessed.txt
head -n 12404 cooking.preprocessed.txt > cooking.train
tail -n 3000 cooking.preprocessed.txt > cooking.valid
處理后的部分數(shù)據(jù)
__label__fish arctic char available in north-america
__label__pasta __label__salt __label__boiling when cooking pasta in salted water how much of the salt is absorbed ?
__label__coffee emergency coffee via chocolate covered coffee beans ?
__label__cake non-beet alternatives to standard red food dye
__label__cheese __label__lentils could cheese “halt” the tenderness of cooking lentils ?
__label__asian-cuisine __label__chili-peppers __label__kimchi __label__korean-cuisine what kind of peppers are used in gochugaru ( ) ?
__label__consistency pavlova roll failure
__label__eggs __label__bread what qualities should i be looking for when making the best french toast ?
__label__meat __label__flour __label__stews __label__braising coating meat in flour before browning , bad idea ?
__label__food-safety raw roast beef on the edge of safe ?
__label__pork __label__food-identification how do i determine the cut of a pork steak prior to purchasing it ?
數(shù)據(jù)處理后進行訓練并測試:
重新訓練
model = fasttext.train_supervised(input=“cooking.train”)
Read 0M words
不重復的詞匯總數(shù)減少很多, 因為之前會把帶大寫字母或者與標點符號相連接的單詞都認為是新的單詞
Number of words: 8952
Number of labels: 735
我們看到平均損失有所下降
Progress: 100.0% words/sec/thread: 65737 lr: 0.000000 avg.loss: 9.966091 ETA: 0h 0m 0s
重新測試
model.test(“cooking.valid”)
我們看到精度和召回率都有所提升
(3000, 0.161, 0.06962663975782038)
增加訓練輪數(shù):
設(shè)置train_supervised方法中的參數(shù)epoch來增加訓練輪數(shù), 默認的輪數(shù)是5次
增加輪數(shù)意味著模型能夠有更多機會在有限數(shù)據(jù)中調(diào)整分類規(guī)律, 當然這也會增加訓練時間
model = fasttext.train_supervised(input=“cooking.train”, epoch=25)
Read 0M words
Number of words: 8952
Number of labels: 735
我們看到平均損失繼續(xù)下降
Progress: 100.0% words/sec/thread: 66283 lr: 0.000000 avg.loss: 7.203885 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度已經(jīng)提升到了42%, 召回率提升至18%.
(3000, 0.4206666666666667, 0.1819230214790255)
調(diào)整學習率:
設(shè)置train_supervised方法中的參數(shù)lr來調(diào)整學習率, 默認的學習率大小是0.1
增大學習率意味著增大了梯度下降的步長使其在有限的迭代步驟下更接近最優(yōu)點
model = fasttext.train_supervised(input=“cooking.train”, lr=1.0, epoch=25)
Read 0M words
Number of words: 8952
Number of labels: 735
平均損失繼續(xù)下降
Progress: 100.0% words/sec/thread: 66027 lr: 0.000000 avg.loss: 4.278283 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度已經(jīng)提升到了47%, 召回率提升至20%.
(3000, 0.47633333333333333, 0.20599682860025947)
增加n-gram特征:
設(shè)置train_supervised方法中的參數(shù)wordNgrams來添加n-gram特征, 默認是1, 也就是沒有n-gram特征
我們這里將其設(shè)置為2意味著添加2-gram特征, 這些特征幫助模型捕捉前后詞匯之間的關(guān)聯(lián), 更好的提取分類規(guī)則用于模型分類, 當然這也會增加模型訓時練占用的資源和時間.
model = fasttext.train_supervised(input=“cooking.train”, lr=1.0, epoch=25, wordNgrams=2)
Read 0M words
Number of words: 8952
Number of labels: 735
平均損失繼續(xù)下降
Progress: 100.0% words/sec/thread: 65084 lr: 0.000000 avg.loss: 3.189422 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度已經(jīng)提升到了49%, 召回率提升至21%.
(3000, 0.49233333333333335, 0.2129162462159435)
修改損失計算方式:
隨著我們不斷的添加優(yōu)化策略, 模型訓練速度也越來越慢
為了能夠提升fasttext模型的訓練效率, 減小訓練時間
設(shè)置train_supervised方法中的參數(shù)loss來修改損失計算方式(等效于輸出層的結(jié)構(gòu)), 默認是softmax層結(jié)構(gòu)
我們這里將其設(shè)置為’hs’, 代表層次softmax結(jié)構(gòu), 意味著輸出層的結(jié)構(gòu)(計算方式)發(fā)生了變化, 將以一種更低復雜度的方式來計算損失.
model = fasttext.train_supervised(input=“cooking.train”, lr=1.0, epoch=25, wordNgrams=2, loss=‘hs’)
Read 0M words
Number of words: 8952
Number of labels: 735
Progress: 100.0% words/sec/thread: 1341740 lr: 0.000000 avg.loss: 2.225962 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度和召回率稍有波動, 但訓練時間卻縮短到僅僅幾秒
(3000, 0.483, 0.20887991927346114)
自動超參數(shù)調(diào)優(yōu):
手動調(diào)節(jié)和尋找超參數(shù)是非常困難的, 因為參數(shù)之間可能相關(guān), 并且不同數(shù)據(jù)集需要的超參數(shù)也不同,
因此可以使用fasttext的autotuneValidationFile參數(shù)進行自動超參數(shù)調(diào)優(yōu).
autotuneValidationFile參數(shù)需要指定驗證數(shù)據(jù)集所在路徑, 它將在驗證集上使用隨機搜索方法尋找可能最優(yōu)的超參數(shù).
使用autotuneDuration參數(shù)可以控制隨機搜索的時間, 默認是300s, 根據(jù)不同的需求, 我們可以延長或縮短時間.
驗證集路徑’cooking.valid’, 隨機搜索600秒
model = fasttext.train_supervised(input=‘cooking.train’, autotuneValidationFile=‘cooking.valid’, autotuneDuration=600)
Progress: 100.0% Trials: 38 Best score: 0.376170 ETA: 0h 0m 0s
Training again with best arguments
Read 0M words
Number of words: 8952
Number of labels: 735
Progress: 100.0% words/sec/thread: 63791 lr: 0.000000 avg.loss: 1.888165 ETA: 0h 0m 0s
實際生產(chǎn)中多標簽多分類問題的損失計算方式:
針對多標簽多分類問題, 使用’softmax’或者’hs’有時并不是最佳選擇, 因為我們最終得到的應該是多個標簽, 而softmax卻只能最大化一個標簽.
所以我們往往會選擇為每個標簽使用獨立的二分類器作為輸出層結(jié)構(gòu),
對應的損失計算方式為’ova’表示one vs all.
這種輸出層的改變意味著我們在統(tǒng)一語料下同時訓練多個二分類模型,
對于二分類模型來講, lr不宜過大, 這里我們設(shè)置為0.2
model = fasttext.train_supervised(input=“cooking.train”, lr=0.2, epoch=25, wordNgrams=2, loss=‘ova’)
Read 0M words
Number of words: 8952
Number of labels: 735
Progress: 100.0% words/sec/thread: 65044 lr: 0.000000 avg.loss: 7.713312 ETA: 0h 0m 0s
我們使用模型進行單條樣本的預測, 來看一下它的輸出結(jié)果.
參數(shù)k代表指定模型輸出多少個標簽, 默認為1, 這里設(shè)置為-1, 意味著盡可能多的輸出.
參數(shù)threshold代表顯示的標簽概率閾值, 設(shè)置為0.5, 意味著顯示概率大于0.5的標簽
model.predict(“Which baking dish is best to bake a banana bread ?”, k=-1, threshold=0.5)
我看到根據(jù)輸入文本, 輸出了它的三個最有可能的標簽
((u’__label__baking’, u’__label__bananas’, u’__label__bread’), array([1.00000, 0.939923, 0.592677]))
第六步: 模型保存與重加載
使用model的save_model方法保存模型到指定目錄
你可以在指定目錄下找到model_cooking.bin文件
model.save_model("./model_cooking.bin")
使用fasttext的load_model進行模型的重加載
model = fasttext.load_model("./model_cooking.bin")
重加載后的模型使用方法和之前完全相同
model.predict(“Which baking dish is best to bake a banana bread ?”, k=-1, threshold=0.5)
((u’__label__baking’, u’__label__bananas’, u’__label__bread’), array([1.00000, 0.939923, 0.592677]))
小節(jié)總結(jié)
學習了什么是文本分類:
文本分類的是將文檔(例如電子郵件,帖子,文本消息,產(chǎn)品評論等)分配給一個或多個類別. 當今文本分類的實現(xiàn)多是使用機器學習方法從訓練數(shù)據(jù)中提取分類規(guī)則以進行分類, 因此構(gòu)建文本分類器需要帶標簽的數(shù)據(jù).
文本分類的種類:
二分類:
文本被分類兩個類別中, 往往這兩個類別是對立面, 比如: 判斷一句評論是好評還是差評.
單標簽多分類:
文本被分入到多個類別中, 且每條文本只能屬于某一個類別(即被打上某一個標簽), 比如: 輸入一個人名, 判斷它是來自哪個國家的人名.
多標簽多分類:
文本被分人到多個類別中, 但每條文本可以屬于多個類別(即被打上多個標簽), 比如: 輸入一段描述, 判斷可能是和哪些興趣愛好有關(guān), 一段描述中可能即討論了美食, 又太討論了游戲愛好.
使用fasttext工具進行文本分類的過程:
第一步: 獲取數(shù)據(jù)
第二步: 訓練集與驗證集的劃分
第三步: 訓練模型
第四步: 使用模型進行預測并評估
第五步: 模型調(diào)優(yōu)
第六步: 模型保存與重加載
1.3 訓練詞向量
學習目標
了解詞向量的相關(guān)知識.
掌握fasttext工具訓練詞向量的過程.
詞向量的相關(guān)知識:
用向量表示文本中的詞匯(或字符)是現(xiàn)代機器學習中最流行的做法, 這些向量能夠很好的捕捉語言之間的關(guān)系, 從而提升基于詞向量的各種NLP任務的效果.
使用fasttext工具訓練詞向量的過程
第一步: 獲取數(shù)據(jù)
第二步: 訓練詞向量
第三步: 模型超參數(shù)設(shè)定
第四步: 模型效果檢驗
第五步: 模型的保存與重加載
第一步: 獲取數(shù)據(jù)
在這里, 我們將研究英語維基百科的部分網(wǎng)頁信息, 它的大小在300M左右
這些語料已經(jīng)被準備好, 我們可以通過Matt Mahoney的網(wǎng)站下載.
首先創(chuàng)建一個存儲數(shù)據(jù)的文件夾data
$ mkdir data
使用wget下載數(shù)據(jù)的zip壓縮包, 它將存儲在data目錄中
$ wget -c http://mattmahoney.net/dc/enwik9.zip -P data
使用unzip解壓, 如果你的服務器中還沒有unzip命令, 請使用: yum install unzip -y
解壓后在data目錄下會出現(xiàn)enwik9的文件夾
$ unzip data/enwik9.zip -d data
查看原始數(shù)據(jù):
$ head -10 data/enwik9
原始數(shù)據(jù)將輸出很多包含XML/HTML格式的內(nèi)容, 這些內(nèi)容并不是我們需要的
Wikipedia http://en.wikipedia.org/wiki/Main_Page MediaWiki 1.6alpha first-letter Media Special 原始數(shù)據(jù)處理:使用wikifil.pl文件處理腳本來清除XML/HTML格式的內(nèi)容
注: wikifil.pl文件已為大家提供
$ perl wikifil.pl data/enwik9 > data/fil9
查看預處理后的數(shù)據(jù):
查看前80個字符
head -c 80 data/fil9
輸出結(jié)果為由空格分割的單詞
anarchism originated as a term of abuse first used against early working class
第二步: 訓練詞向量
代碼運行在python解釋器中
導入fasttext
import fasttext
使用fasttext的train_unsupervised(無監(jiān)督訓練方法)進行詞向量的訓練
它的參數(shù)是數(shù)據(jù)集的持久化文件路徑’data/fil9’
model = fasttext.train_unsupervised(‘data/fil9’)
有效訓練詞匯量為124M, 共218316個單詞
Read 124M words
Number of words: 218316
Number of labels: 0
Progress: 100.0% words/sec/thread: 53996 lr: 0.000000 loss: 0.734999 ETA: 0h 0m
查看單詞對應的詞向量:
通過get_word_vector方法來獲得指定詞匯的詞向量
model.get_word_vector(“the”)
array([-0.03087516, 0.09221972, 0.17660329, 0.17308897, 0.12863874,
0.13912526, -0.09851588, 0.00739991, 0.37038437, -0.00845221,
…
-0.21184735, -0.05048715, -0.34571868, 0.23765688, 0.23726143],
dtype=float32)
第三步: 模型超參數(shù)設(shè)定
在訓練詞向量過程中, 我們可以設(shè)定很多常用超參數(shù)來調(diào)節(jié)我們的模型效果, 如:
無監(jiān)督訓練模式: ‘skipgram’ 或者 ‘cbow’, 默認為’skipgram’, 在實踐中,skipgram模式在利用子詞方面比cbow更好.
詞嵌入維度dim: 默認為100, 但隨著語料庫的增大, 詞嵌入的維度往往也要更大.
數(shù)據(jù)循環(huán)次數(shù)epoch: 默認為5, 但當你的數(shù)據(jù)集足夠大, 可能不需要那么多次.
學習率lr: 默認為0.05, 根據(jù)經(jīng)驗, 建議選擇[0.01,1]范圍內(nèi).
使用的線程數(shù)thread: 默認為12個線程, 一般建議和你的cpu核數(shù)相同.
model = fasttext.train_unsupervised(‘data/fil9’, “cbow”, dim=300, epoch=1, lr=0.1, thread=8)
Read 124M words
Number of words: 218316
Number of labels: 0
Progress: 100.0% words/sec/thread: 49523 lr: 0.000000 avg.loss: 1.777205 ETA: 0h 0m 0s
第四步: 模型效果檢驗
檢查單詞向量質(zhì)量的一種簡單方法就是查看其鄰近單詞, 通過我們主觀來判斷這些鄰近單詞是否與目標單詞相關(guān)來粗略評定模型效果好壞.
查找"運動"的鄰近單詞, 我們可以發(fā)現(xiàn)"體育網(wǎng)", “運動汽車”, "運動服"等.
model.get_nearest_neighbors(‘sports’)
[(0.8414610624313354, ‘sportsnet’), (0.8134572505950928, ‘sport’), (0.8100415468215942, ‘sportscars’), (0.8021156787872314, ‘sportsground’), (0.7889881134033203, ‘sportswomen’), (0.7863013744354248, ‘sportsplex’), (0.7786710262298584, ‘sporty’), (0.7696356177330017, ‘sportscar’), (0.7619683146476746, ‘sportswear’), (0.7600985765457153, ‘sportin’)]
查找"音樂"的鄰近單詞, 我們可以發(fā)現(xiàn)與音樂有關(guān)的詞匯.
model.get_nearest_neighbors(‘music’)
[(0.8908010125160217, ‘emusic’), (0.8464668393135071, ‘musicmoz’), (0.8444250822067261, ‘musics’), (0.8113634586334229, ‘a(chǎn)llmusic’), (0.8106718063354492, ‘musices’), (0.8049437999725342, ‘musicam’), (0.8004694581031799, ‘musicom’), (0.7952923774719238, ‘muchmusic’), (0.7852965593338013, ‘musicweb’), (0.7767147421836853, ‘musico’)]
查找"小狗"的鄰近單詞, 我們可以發(fā)現(xiàn)與小狗有關(guān)的詞匯.
model.get_nearest_neighbors(‘dog’)
[(0.8456876873970032, ‘catdog’), (0.7480780482292175, ‘dogcow’), (0.7289096117019653, ‘sleddog’), (0.7269964218139648, ‘hotdog’), (0.7114801406860352, ‘sheepdog’), (0.6947550773620605, ‘dogo’), (0.6897546648979187, ‘bodog’), (0.6621081829071045, ‘maddog’), (0.6605004072189331, ‘dogs’), (0.6398137211799622, ‘dogpile’)]
第五步: 模型的保存與重加載
使用save_model保存模型
model.save_model(“fil9.bin”)
使用fasttext.load_model加載模型
model = fasttext.load_model(“fil9.bin”)
model.get_word_vector(“the”)
array([-0.03087516, 0.09221972, 0.17660329, 0.17308897, 0.12863874,
0.13912526, -0.09851588, 0.00739991, 0.37038437, -0.00845221,
…
-0.21184735, -0.05048715, -0.34571868, 0.23765688, 0.23726143],
dtype=float32)
小節(jié)總結(jié)
學習了詞向量的相關(guān)知識:
用向量表示文本中的詞匯(或字符)是現(xiàn)代機器學習中最流行的做法, 這些向量能夠很好的捕捉語言之間的關(guān)系, 從而提升基于詞向量的各種NLP任務的效果.
使用fasttext工具訓練詞向量的過程:
第一步: 獲取數(shù)據(jù)
第二步: 訓練詞向量
第三步: 模型超參數(shù)設(shè)定
第四步: 模型效果檢驗
第五步: 模型的保存與重加載
1.4 詞向量遷移
學習目標
了解什么是詞向量遷移.
了解fasttext工具中有哪些可遷移的詞向量模型.
掌握如何使用fasttext進行詞向量模型遷移.
什么是詞向量遷移:
使用在大型語料庫上已經(jīng)進行訓練完成的詞向量模型.
fasttext工具中可以提供的可遷移的詞向量:
fasttext提供了157種語言的在CommonCrawl和Wikipedia語料上進行訓練的可遷移詞向量模型, 它們采用CBOW模式進行訓練, 詞向量維度為300維. 可通過該地址查看具體語言詞向量模型: https://fasttext.cc/docs/en/crawl-vectors.html
fasttext提供了294種語言的在Wikipedia語料上進行訓練的可遷移詞向量模型, 它們采用skipgram模式進行訓練, 詞向量維度同樣是300維. 可通過該地址查看具體語言詞向量模型: https://fasttext.cc/docs/en/pretrained-vectors.html
如何使用fasttext進行詞向量模型遷移
第一步: 下載詞向量模型壓縮的bin.gz文件
第二步: 解壓bin.gz文件到bin文件
第三步: 加載bin文件獲取詞向量
第四步: 利用鄰近詞進行效果檢驗
第一步: 下載詞向量模型壓縮的bin.gz文件
這里我們以遷移在CommonCrawl和Wikipedia語料上進行訓練的中文詞向量模型為例:
下載中文詞向量模型(bin.gz文件)
wget https://dl.fbaipublicfiles.com/fasttext/vectors-crawl/cc.zh.300.bin.gz
第二步: 解壓bin.gz文件到bin文件
使用gunzip進行解壓, 獲取cc.zh.300.bin文件
gunzip cc.zh.300.bin.gz
第三步: 加載bin文件獲取詞向量
加載模型
model = fasttext.load_model(“cc.zh.300.bin”)
查看前100個詞匯(這里的詞匯是廣義的, 可以是中文符號或漢字))
model.words[:100]
[’,’, ‘的’, ‘。’, ‘’, ‘、’, ‘是’, ‘一’, ‘在’, ‘:’, ‘了’, ‘(’, ‘)’, “’”, ‘和’, ‘不’, ‘有’, ‘我’, ‘,’, ‘)’, ‘(’, ‘“’, ‘”’, ‘也’, ‘人’, ‘個’, ‘:’, ‘中’, ‘.’, ‘就’, ‘他’, ‘》’, ‘《’, ‘-’, ‘你’, ‘都’, ‘上’, ‘大’, ‘!’, ‘這’, ‘為’, ‘多’, ‘與’, ‘章’, ‘「’, ‘到’, ‘」’, ‘要’, ‘?’, ‘被’, ‘而’, ‘能’, ‘等’, ‘可以’, ‘年’, ‘;’, ‘|’, ‘以’, ‘及’, ‘之’, ‘公司’, ‘對’, ‘中國’, ‘很’, ‘會’, ‘小’, ‘但’, ‘我們’, ‘最’, ‘更’, ‘/’, ‘1’, ‘三’, ‘新’, ‘自己’, ‘可’, ‘2’, ‘或’, ‘次’, ‘好’, ‘將’, ‘第’, ‘種’, ‘她’, ‘…’, ‘3’, ‘地’, ‘對’, ‘用’, ‘工作’, ‘下’, ‘后’, ‘由’, ‘兩’, ‘使用’, ‘還’, ‘又’, ‘您’, ‘?’, ‘其’, ‘已’]
使用模型獲得’音樂’這個名詞的詞向量
model.get_word_vector(“音樂”)
array([-6.81843981e-02, 3.84048335e-02, 4.63239700e-01, 6.11658543e-02,
9.38086119e-03, -9.63955745e-02, 1.28141120e-01, -6.51574507e-02,
…
3.13430429e-02, -6.43611327e-02, 1.68979481e-01, -1.95011273e-01],
dtype=float32)
第四步: 利用鄰近詞進行效果檢驗
以’音樂’為例, 返回的鄰近詞基本上與音樂都有關(guān)系, 如樂曲, 音樂會, 聲樂等.
model.get_nearest_neighbors(“音樂”)
[(0.6703276634216309, ‘樂曲’), (0.6569967269897461, ‘音樂人’), (0.6565821170806885, ‘聲樂’), (0.6557438373565674, ‘輕音樂’), (0.6536258459091187, ‘音樂家’), (0.6502416133880615, ‘配樂’), (0.6501686573028564, ‘藝術(shù)’), (0.6437276005744934, ‘音樂會’), (0.639589250087738, ‘原聲’), (0.6368917226791382, ‘音響’)]
以’美術(shù)’為例, 返回的鄰近詞基本上與美術(shù)都有關(guān)系, 如藝術(shù), 繪畫, 霍廷霄(滿城盡帶黃金甲的美術(shù)師)等.
model.get_nearest_neighbors(“美術(shù)”)
[(0.724744975566864, ‘藝術(shù)’), (0.7165924310684204, ‘繪畫’), (0.6741853356361389, ‘霍廷霄’), (0.6470299363136292, ‘純藝’), (0.6335071921348572, ‘美術(shù)家’), (0.6304370164871216, ‘美院’), (0.624431312084198, ‘藝術(shù)類’), (0.6244068741798401, ‘陳浩忠’), (0.62302166223526, ‘美術(shù)史’), (0.621710479259491, ‘環(huán)藝系’)]
以’周杰倫’為例, 返回的鄰近詞基本上與明星有關(guān)系, 如杰倫, 周董, 陳奕迅等.
model.get_nearest_neighbors(“周杰倫”)
[(0.6995140910148621, ‘杰倫’), (0.6967097520828247, ‘周杰倫’), (0.6859776377677917, ‘周董’), (0.6381043195724487, ‘陳奕迅’), (0.6367626190185547, ‘張靚穎’), (0.6313326358795166, ‘張韶涵’), (0.6271176338195801, ‘謝霆鋒’), (0.6188404560089111, ‘周華健’), (0.6184280514717102, ‘林俊杰’), (0.6143589019775391, ‘王力宏’)]
小節(jié)總結(jié)
學習了什么是詞向量遷移:
使用在大型語料庫上已經(jīng)進行訓練完成的詞向量模型.
學習了fasttext工具中可以提供的可遷移的詞向量:
fasttext提供了157種語言的在CommonCrawl和Wikipedia語料上進行訓練的可遷移詞向量模型, 它們采用CBOW模式進行訓練, 詞向量維度為300維. 可通過該地址查看具體語言詞向量模型: https://fasttext.cc/docs/en/crawl-vectors.html
fasttext提供了294種語言的在Wikipedia語料上進行訓練的可遷移詞向量模型, 它們采用skipgram模式進行訓練, 詞向量維度同樣是300維. 可通過該地址查看具體語言詞向量模型: https://fasttext.cc/docs/en/pretrained-vectors.html
如何使用fasttext進行詞向量模型遷移:
第一步: 下載詞向量模型壓縮的bin.gz文件
第二步: 解壓bin.gz文件到bin文件
第三步: 加載bin文件獲取詞向量
第四步: 利用鄰近詞進行效果檢驗
下一頁第二章:遷移學習
?Copyright 2019, itcast.cn.
Made with Material for MkDocs
跳轉(zhuǎn)至
logo
遷移學習
第二章:遷移學習
logo
遷移學習
第一章:fasttext工具的使用
第二章:遷移學習
目錄
2.1 遷移學習理論
學習目標
2.2 NLP中的標準數(shù)據(jù)集
學習目標
GLUE數(shù)據(jù)集合包含以下數(shù)據(jù)集
GLUE數(shù)據(jù)集合中子數(shù)據(jù)集的樣式及其任務類型
CoLA數(shù)據(jù)集文件樣式
SST-2數(shù)據(jù)集文件樣式
MRPC數(shù)據(jù)集文件樣式
STS-B數(shù)據(jù)集文件樣式
QQP數(shù)據(jù)集文件樣式
(MNLI/SNLI)數(shù)據(jù)集文件樣式
(QNLI/RTE/WNLI)數(shù)據(jù)集文件樣式
小節(jié)總結(jié)
2.3 NLP中的常用預訓練模型
學習目標
當下NLP中流行的預訓練模型
小節(jié)總結(jié)
2.4 加載和使用預訓練模型
學習目標
加載和使用預訓練模型的工具
加載和使用預訓練模型的步驟
第一步: 確定需要加載的預訓練模型并安裝依賴包
第二步: 加載預訓練模型的映射器tokenizer
第三步: 加載帶/不帶頭的預訓練模型
第四步: 使用模型獲得輸出結(jié)果
小節(jié)總結(jié)
2.5 遷移學習實踐
學習目標
指定任務類型的微調(diào)腳本使用步驟
第一步: 下載微調(diào)腳本文件
第二步: 配置微調(diào)腳本參數(shù)
第三步: 運行并檢驗效果
通過微調(diào)腳本微調(diào)后模型的使用步驟
第一步: 在https://huggingface.co/join上創(chuàng)建一個帳戶
第二步: 在服務器終端使用transformers-cli登陸
第三步: 使用transformers-cli上傳模型并查看
第四步: 使用pytorch.hub加載模型進行使用, 更多信息請參考2.4 加載和使用預訓練模型
通過微調(diào)方式進行遷移學習的兩種類型
類型一實戰(zhàn)演示
類型二實戰(zhàn)演示
小節(jié)總結(jié)
第二章:遷移學習
2.1 遷移學習理論
學習目標
了解遷移學習中的有關(guān)概念.
掌握遷移學習的兩種遷移方式.
遷移學習中的有關(guān)概念:
預訓練模型
微調(diào)
微調(diào)腳本
預訓練模型(Pretrained model):
一般情況下預訓練模型都是大型模型,具備復雜的網(wǎng)絡(luò)結(jié)構(gòu),眾多的參數(shù)量,以及在足夠大的數(shù)據(jù)集下進行訓練而產(chǎn)生的模型. 在NLP領(lǐng)域,預訓練模型往往是語言模型,因為語言模型的訓練是無監(jiān)督的,可以獲得大規(guī)模語料,同時語言模型又是許多典型NLP任務的基礎(chǔ),如機器翻譯,文本生成,閱讀理解等,常見的預訓練模型有BERT, GPT, roBERTa, transformer-XL等.
微調(diào)(Fine-tuning):
根據(jù)給定的預訓練模型,改變它的部分參數(shù)或者為其新增部分輸出結(jié)構(gòu)后,通過在小部分數(shù)據(jù)集上訓練,來使整個模型更好的適應特定任務.
微調(diào)腳本(Fine-tuning script):
實現(xiàn)微調(diào)過程的代碼文件。這些腳本文件中,應包括對預訓練模型的調(diào)用,對微調(diào)參數(shù)的選定以及對微調(diào)結(jié)構(gòu)的更改等,同時,因為微調(diào)是一個訓練過程,它同樣需要一些超參數(shù)的設(shè)定,以及損失函數(shù)和優(yōu)化器的選取等, 因此微調(diào)腳本往往也包含了整個遷移學習的過程.
關(guān)于微調(diào)腳本的說明:
一般情況下,微調(diào)腳本應該由不同的任務類型開發(fā)者自己編寫,但是由于目前研究的NLP任務類型(分類,提取,生成)以及對應的微調(diào)輸出結(jié)構(gòu)都是有限的,有些微調(diào)方式已經(jīng)在很多數(shù)據(jù)集上被驗證是有效的,因此微調(diào)腳本也可以使用已經(jīng)完成的規(guī)范腳本.
兩種遷移方式:
直接使用預訓練模型,進行相同任務的處理,不需要調(diào)整參數(shù)或模型結(jié)構(gòu),這些模型開箱即用。但是這種情況一般只適用于普適任務, 如:fasttest工具包中預訓練的詞向量模型。另外,很多預訓練模型開發(fā)者為了達到開箱即用的效果,將模型結(jié)構(gòu)分各個部分保存為不同的預訓練模型,提供對應的加載方法來完成特定目標.
更加主流的遷移學習方式是發(fā)揮預訓練模型特征抽象的能力,然后再通過微調(diào)的方式,通過訓練更新小部分參數(shù)以此來適應不同的任務。這種遷移方式需要提供小部分的標注數(shù)據(jù)來進行監(jiān)督學習.
關(guān)于遷移方式的說明:
直接使用預訓練模型的方式, 已經(jīng)在fasttext的詞向量遷移中學習. 接下來的遷移學習實踐將主要講解通過微調(diào)的方式進行遷移學習.
2.2 NLP中的標準數(shù)據(jù)集
學習目標
了解NLP中GLUE標準數(shù)據(jù)集合的相關(guān)知識.
掌握GLUE標準數(shù)據(jù)集合的下載方式, 數(shù)據(jù)樣式及其對應的任務類型.
GLUE數(shù)據(jù)集合的介紹:
GLUE由紐約大學, 華盛頓大學, Google聯(lián)合推出, 涵蓋不同NLP任務類型, 截止至2020年1月其中包括11個子任務數(shù)據(jù)集, 成為衡量NLP研究發(fā)展的衡量標準.
GLUE數(shù)據(jù)集合包含以下數(shù)據(jù)集
CoLA 數(shù)據(jù)集
SST-2 數(shù)據(jù)集
MRPC 數(shù)據(jù)集
STS-B 數(shù)據(jù)集
QQP 數(shù)據(jù)集
MNLI 數(shù)據(jù)集
SNLI 數(shù)據(jù)集
QNLI 數(shù)據(jù)集
RTE 數(shù)據(jù)集
WNLI 數(shù)據(jù)集
diagnostics數(shù)據(jù)集(官方未完善)
GLUE數(shù)據(jù)集合的下載方式:
下載腳本代碼:
‘’’ Script for downloading all GLUE data.’’’
import os
import sys
import shutil
import argparse
import tempfile
import urllib.request
import zipfile
TASKS = [“CoLA”, “SST”, “MRPC”, “QQP”, “STS”, “MNLI”, “SNLI”, “QNLI”, “RTE”, “WNLI”, “diagnostic”]
TASK2PATH = {“CoLA”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FCoLA.zip?alt=media&token=46d5e637-3411-4188-bc44-5809b5bfb5f4’,
“SST”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FSST-2.zip?alt=media&token=aabc5f6b-e466-44a2-b9b4-cf6337f84ac8’,
“MRPC”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2Fmrpc_dev_ids.tsv?alt=media&token=ec5c0836-31d5-48f4-b431-7480817f1adc’,
“QQP”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FQQP.zip?alt=media&token=700c6acf-160d-4d89-81d1-de4191d02cb5’,
“STS”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FSTS-B.zip?alt=media&token=bddb94a7-8706-4e0d-a694-1109e12273b5’,
“MNLI”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FMNLI.zip?alt=media&token=50329ea1-e339-40e2-809c-10c40afff3ce’,
“SNLI”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FSNLI.zip?alt=media&token=4afcfbb2-ff0c-4b2d-a09a-dbf07926f4df’,
“QNLI”: ‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FQNLIv2.zip?alt=media&token=6fdcf570-0fc5-4631-8456-9505272d1601’,
“RTE”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FRTE.zip?alt=media&token=5efa7e85-a0bb-4f19-8ea2-9e1840f077fb’,
“WNLI”:‘https://firebasestorage.googleapis.com/v0/b/mtl-sentence-representations.appspot.com/o/data%2FWNLI.zip?alt=media&token=068ad0a0-ded7-4bd7-99a5-5e00222e0faf’,
“diagnostic”:‘https://storage.googleapis.com/mtl-sentence-representations.appspot.com/tsvsWithoutLabels%2FAX.tsv?GoogleAccessId=firebase-adminsdk-0khhl@mtl-sentence-representations.iam.gserviceaccount.com&Expires=2498860800&Signature=DuQ2CSPt2Yfre0C%2BiISrVYrIFaZH1Lc7hBVZDD4ZyR7fZYOMNOUGpi8QxBmTNOrNPjR3z1cggo7WXFfrgECP6FBJSsURv8Ybrue8Ypt%2FTPxbuJ0Xc2FhDi%2BarnecCBFO77RSbfuz%2Bs95hRrYhTnByqu3U%2FYZPaj3tZt5QdfpH2IUROY8LiBXoXS46LE%2FgOQc%2FKN%2BA9SoscRDYsnxHfG0IjXGwHN%2Bf88q6hOmAxeNPx6moDulUF6XMUAaXCSFU%2BnRO2RDL9CapWxj%2BDl7syNyHhB7987hZ80B%2FwFkQ3MEs8auvt5XW1%2Bd4aCU7ytgM69r8JDCwibfhZxpaa4gd50QXQ%3D%3D’}
MRPC_TRAIN = ‘https://dl.fbaipublicfiles.com/senteval/senteval_data/msr_paraphrase_train.txt’
MRPC_TEST = ‘https://dl.fbaipublicfiles.com/senteval/senteval_data/msr_paraphrase_test.txt’
def download_and_extract(task, data_dir):
print(“Downloading and extracting %s…” % task)
data_file = “%s.zip” % task
urllib.request.urlretrieve(TASK2PATH[task], data_file)
with zipfile.ZipFile(data_file) as zip_ref:
zip_ref.extractall(data_dir)
os.remove(data_file)
print("\tCompleted!")
def format_mrpc(data_dir, path_to_data):
print(“Processing MRPC…”)
mrpc_dir = os.path.join(data_dir, “MRPC”)
if not os.path.isdir(mrpc_dir):
os.mkdir(mrpc_dir)
if path_to_data:
mrpc_train_file = os.path.join(path_to_data, “msr_paraphrase_train.txt”)
mrpc_test_file = os.path.join(path_to_data, “msr_paraphrase_test.txt”)
else:
print(“Local MRPC data not specified, downloading data from %s” % MRPC_TRAIN)
mrpc_train_file = os.path.join(mrpc_dir, “msr_paraphrase_train.txt”)
mrpc_test_file = os.path.join(mrpc_dir, “msr_paraphrase_test.txt”)
urllib.request.urlretrieve(MRPC_TRAIN, mrpc_train_file)
urllib.request.urlretrieve(MRPC_TEST, mrpc_test_file)
assert os.path.isfile(mrpc_train_file), “Train data not found at %s” % mrpc_train_file
assert os.path.isfile(mrpc_test_file), “Test data not found at %s” % mrpc_test_file
urllib.request.urlretrieve(TASK2PATH[“MRPC”], os.path.join(mrpc_dir, “dev_ids.tsv”))
def download_diagnostic(data_dir):
print(“Downloading and extracting diagnostic…”)
if not os.path.isdir(os.path.join(data_dir, “diagnostic”)):
os.mkdir(os.path.join(data_dir, “diagnostic”))
data_file = os.path.join(data_dir, “diagnostic”, “diagnostic.tsv”)
urllib.request.urlretrieve(TASK2PATH[“diagnostic”], data_file)
print("\tCompleted!")
return
def get_tasks(task_names):
task_names = task_names.split(’,’)
if “all” in task_names:
tasks = TASKS
else:
tasks = []
for task_name in task_names:
assert task_name in TASKS, “Task %s not found!” % task_name
tasks.append(task_name)
return tasks
def main(arguments):
parser = argparse.ArgumentParser()
parser.add_argument(’–data_dir’, help=‘directory to save data to’, type=str, default=‘glue_data’)
parser.add_argument(’–tasks’, help=‘tasks to download data for as a comma separated string’,
type=str, default=‘a(chǎn)ll’)
parser.add_argument(’–path_to_mrpc’, help=‘path to directory containing extracted MRPC data, msr_paraphrase_train.txt and msr_paraphrase_text.txt’,
type=str, default=’’)
args = parser.parse_args(arguments)
if name == ‘main’:
sys.exit(main(sys.argv[1:]))
運行腳本下載所有數(shù)據(jù)集:
假設(shè)你已經(jīng)將以上代碼copy到download_glue_data.py文件中
運行這個python腳本, 你將同目錄下得到一個glue文件夾
python download_glue_data.py
輸出效果:
Downloading and extracting CoLA…
Completed!
Downloading and extracting SST…
Completed!
Processing MRPC…
Local MRPC data not specified, downloading data from https://dl.fbaipublicfiles.com/senteval/senteval_data/msr_paraphrase_train.txt
Completed!
Downloading and extracting QQP…
Completed!
Downloading and extracting STS…
Completed!
Downloading and extracting MNLI…
Completed!
Downloading and extracting SNLI…
Completed!
Downloading and extracting QNLI…
Completed!
Downloading and extracting RTE…
Completed!
Downloading and extracting WNLI…
Completed!
Downloading and extracting diagnostic…
Completed!
GLUE數(shù)據(jù)集合中子數(shù)據(jù)集的樣式及其任務類型
CoLA數(shù)據(jù)集文件樣式
- CoLA/
- dev.tsv
- original/
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test.tsv是不帶有標簽的數(shù)據(jù).
train.tsv數(shù)據(jù)樣式:
…
gj04 1 She coughed herself awake as the leaf landed on her nose.
gj04 1 The worm wriggled onto the carpet.
gj04 1 The chocolate melted onto the carpet.
gj04 0 * The ball wriggled itself loose.
gj04 1 Bill wriggled himself loose.
bc01 1 The sinking of the ship to collect the insurance was very devious.
bc01 1 The ship’s sinking was very devious.
bc01 0 * The ship’s sinking to collect the insurance was very devious.
bc01 1 The testing of such drugs on oneself is too risky.
bc01 0 * This drug’s testing on oneself is too risky.
…
train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為4列, 第一列數(shù)據(jù), 如gj04, bc01等代表每條文本數(shù)據(jù)的來源即出版物代號; 第二列數(shù)據(jù), 0或1, 代表每條文本數(shù)據(jù)的語法是否正確, 0代表不正確, 1代表正確; 第三列數(shù)據(jù), ‘’, 是作者最初的正負樣本標記, 與第二列意義相同, ''表示不正確; 第四列即是被標注的語法使用是否正確的文本句子.
test.tsv數(shù)據(jù)樣式:
index sentence
0 Bill whistled past the house.
1 The car honked its way down the road.
2 Bill pushed Harry off the sofa.
3 the kittens yawned awake and played.
4 I demand that the more John eats, the more he pay.
5 If John eats more, keep your mouth shut tighter, OK?
6 His expectations are always lower than mine are.
7 The sooner you call, the more carefully I will word the letter.
8 The more timid he feels, the more people he interviews without asking questions of.
9 Once Janet left, Fred became a lot crazier.
…
test.tsv數(shù)據(jù)樣式說明:
test.tsv中的數(shù)據(jù)內(nèi)容共分為2列, 第一列數(shù)據(jù)代表每條文本數(shù)據(jù)的索引; 第二列數(shù)據(jù)代表用于測試的句子.
CoLA數(shù)據(jù)集的任務類型:
二分類任務
評估指標為: MCC(馬修斯相關(guān)系數(shù), 在正負樣本分布十分不均衡的情況下使用的二分類評估指標)
SST-2數(shù)據(jù)集文件樣式
- SST-2/
- dev.tsv
- original/
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test.tsv是不帶有標簽的數(shù)據(jù).
train.tsv數(shù)據(jù)樣式:
sentence label
hide new secretions from the parental units 0
contains no wit , only labored gags 0
that loves its characters and communicates something rather beautiful about human nature 1
remains utterly satisfied to remain the same throughout 0
on the worst revenge-of-the-nerds clichés the filmmakers could dredge up 0
that 's far too tragic to merit such superficial treatment 0
demonstrates that the director of such hollywood blockbusters as patriot games can still turn out a small , personal film with an emotional wallop . 1
of saucy 1
a depressed fifteen-year-old 's suicidal poetry 0
…
train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為2列, 第一列數(shù)據(jù)代表具有感情色彩的評論文本; 第二列數(shù)據(jù), 0或1, 代表每條文本數(shù)據(jù)是積極或者消極的評論, 0代表消極, 1代表積極.
test.tsv數(shù)據(jù)樣式:
index sentence
0 uneasy mishmash of styles and genres .
1 this film 's relationship to actual tension is the same as what christmas-tree flocking in a spray can is to actual snow : a poor – if durable – imitation .
2 by the end of no such thing the audience , like beatrice , has a watchful affection for the monster .
3 director rob marshall went out gunning to make a great one .
4 lathan and diggs have considerable personal charm , and their screen rapport makes the old story seem new .
5 a well-made and often lovely depiction of the mysteries of friendship .
6 none of this violates the letter of behan 's book , but missing is its spirit , its ribald , full-throated humor .
7 although it bangs a very cliched drum at times , this crowd-pleaser 's fresh dialogue , energetic music , and good-natured spunk are often infectious .
8 it is not a mass-market entertainment but an uncompromising attempt by one artist to think about another .
9 this is junk food cinema at its greasiest .
…
test.tsv數(shù)據(jù)樣式說明: * test.tsv中的數(shù)據(jù)內(nèi)容共分為2列, 第一列數(shù)據(jù)代表每條文本數(shù)據(jù)的索引; 第二列數(shù)據(jù)代表用于測試的句子.
SST-2數(shù)據(jù)集的任務類型:
二分類任務
評估指標為: ACC
MRPC數(shù)據(jù)集文件樣式
- MRPC/
- dev.tsv
- test.tsv
- train.tsv- dev_ids.tsv
- msr_paraphrase_test.txt
- msr_paraphrase_train.txt
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test.tsv是不帶有標簽的數(shù)據(jù).
train.tsv數(shù)據(jù)樣式:
Quality #1 ID #2 ID #1 String #2 String
1 702876 702977 Amrozi accused his brother , whom he called " the witness " , of deliberately distorting his evidence . Referring to him as only " the witness " , Amrozi accused his brother of deliberately distorting his evidence .
0 2108705 2108831 Yucaipa owned Dominick 's before selling the chain to Safeway in 1998 for $ 2.5 billion . Yucaipa bought Dominick 's in 1995 for $ 693 million and sold it to Safeway for $ 1.8 billion in 1998 .
1 1330381 1330521 They had published an advertisement on the Internet on June 10 , offering the cargo for sale , he added . On June 10 , the ship 's owners had published an advertisement on the Internet , offering the explosives for sale .
0 3344667 3344648 Around 0335 GMT , Tab shares were up 19 cents , or 4.4 % , at A $ 4.56 , having earlier set a record high of A $ 4.57 . Tab shares jumped 20 cents , or 4.6 % , to set a record closing high at A $ 4.57 .
1 1236820 1236712 The stock rose $ 2.11 , or about 11 percent , to close Friday at $ 21.51 on the New York Stock Exchange . PG & E Corp. shares jumped $ 1.63 or 8 percent to $ 21.03 on the New York Stock Exchange on Friday .
1 738533 737951 Revenue in the first quarter of the year dropped 15 percent from the same period a year earlier . With the scandal hanging over Stewart 's company , revenue the first quarter of the year dropped 15 percent from the same period a year earlier .
0 264589 264502 The Nasdaq had a weekly gain of 17.27 , or 1.2 percent , closing at 1,520.15 on Friday . The tech-laced Nasdaq Composite .IXIC rallied 30.46 points , or 2.04 percent , to 1,520.15 .
1 579975 579810 The DVD-CCA then appealed to the state Supreme Court . The DVD CCA appealed that decision to the U.S. Supreme Court .
…
train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為5列, 第一列數(shù)據(jù), 0或1, 代表每對句子是否具有相同的含義, 0代表含義不相同, 1代表含義相同. 第二列和第三列分別代表每對句子的id, 第四列和第五列分別具有相同/不同含義的句子對.
test.tsv數(shù)據(jù)樣式:
index #1 ID #2 ID #1 String #2 String
0 1089874 1089925 PCCW 's chief operating officer , Mike Butcher , and Alex Arena , the chief financial officer , will report directly to Mr So . Current Chief Operating Officer Mike Butcher and Group Chief Financial Officer Alex Arena will report to So .
1 3019446 3019327 The world 's two largest automakers said their U.S. sales declined more than predicted last month as a late summer sales frenzy caused more of an industry backlash than expected . Domestic sales at both GM and No. 2 Ford Motor Co. declined more than predicted as a late summer sales frenzy prompted a larger-than-expected industry backlash .
2 1945605 1945824 According to the federal Centers for Disease Control and Prevention ( news - web sites ) , there were 19 reported cases of measles in the United States in 2002 . The Centers for Disease Control and Prevention said there were 19 reported cases of measles in the United States in 2002 .
3 1430402 1430329 A tropical storm rapidly developed in the Gulf of Mexico Sunday and was expected to hit somewhere along the Texas or Louisiana coasts by Monday night . A tropical storm rapidly developed in the Gulf of Mexico on Sunday and could have hurricane-force winds when it hits land somewhere along the Louisiana coast Monday night .
4 3354381 3354396 The company didn 't detail the costs of the replacement and repairs . But company officials expect the costs of the replacement work to run into the millions of dollars .
5 1390995 1391183 The settling companies would also assign their possible claims against the underwriters to the investor plaintiffs , he added . Under the agreement , the settling companies will also assign their potential claims against the underwriters to the investors , he added .
6 2201401 2201285 Air Commodore Quaife said the Hornets remained on three-minute alert throughout the operation . Air Commodore John Quaife said the security operation was unprecedented .
7 2453843 2453998 A Washington County man may have the countys first human case of West Nile virus , the health department said Friday . The countys first and only human case of West Nile this year was confirmed by health officials on Sept . 8 .
…
test.tsv數(shù)據(jù)樣式說明: * test.tsv中的數(shù)據(jù)內(nèi)容共分為5列, 第一列數(shù)據(jù)代表每條文本數(shù)據(jù)的索引; 其余列的含義與train.tsv中相同.
MRPC數(shù)據(jù)集的任務類型:
句子對二分類任務
評估指標為: ACC和F1
STS-B數(shù)據(jù)集文件樣式
- STS-B/
- dev.tsv
- test.tsv
- train.tsv- LICENSE.txt
- readme.txt
- original/
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test.tsv是不帶有標簽的數(shù)據(jù).
train.tsv數(shù)據(jù)樣式:
index genre filename year old_index source1 source2 sentence1 sentence2 score
0 main-captions MSRvid 2012test 0001 none none A plane is taking off. An air plane is taking off. 5.000
1 main-captions MSRvid 2012test 0004 none none A man is playing a large flute. A man is playing a flute. 3.800
2 main-captions MSRvid 2012test 0005 none none A man is spreading shreded cheese on a pizza. A man is spreading shredded cheese on an uncooked pizza. 3.800
3 main-captions MSRvid 2012test 0006 none none Three men are playing chess.Two men are playing chess. 2.600
4 main-captions MSRvid 2012test 0009 none none A man is playing the cello.A man seated is playing the cello. 4.250
5 main-captions MSRvid 2012test 0011 none none Some men are fighting. Two men are fighting. 4.250
6 main-captions MSRvid 2012test 0012 none none A man is smoking. A man is skating. 0.500
7 main-captions MSRvid 2012test 0013 none none The man is playing the piano. The man is playing the guitar. 1.600
8 main-captions MSRvid 2012test 0014 none none A man is playing on a guitar and singing. A woman is playing an acoustic guitar and singing. 2.200
9 main-captions MSRvid 2012test 0016 none none A person is throwing a cat on to the ceiling. A person throws a cat on the ceiling. 5.000
…
train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為10列, 第一列數(shù)據(jù)是數(shù)據(jù)索引; 第二列代表每對句子的來源, 如main-captions表示來自字幕; 第三列代表來源的具體保存文件名, 第四列代表出現(xiàn)時間(年); 第五列代表原始數(shù)據(jù)的索引; 第六列和第七列分別代表句子對原始來源; 第八列和第九列代表相似程度不同的句子對; 第十列代表句子對的相似程度由低到高, 值域范圍是[0, 5].
test.tsv數(shù)據(jù)樣式:
index genre filename year old_index source1 source2 sentence1 sentence2
0 main-captions MSRvid 2012test 0024 none none A girl is styling her hair. A girl is brushing her hair.
1 main-captions MSRvid 2012test 0033 none none A group of men play soccer on the beach. A group of boys are playing soccer on the beach.
2 main-captions MSRvid 2012test 0045 none none One woman is measuring another woman’s ankle. A woman measures another woman’s ankle.
3 main-captions MSRvid 2012test 0063 none none A man is cutting up a cucumber. A man is slicing a cucumber.
4 main-captions MSRvid 2012test 0066 none none A man is playing a harp. A man is playing a keyboard.
5 main-captions MSRvid 2012test 0074 none none A woman is cutting onions. A woman is cutting tofu.
6 main-captions MSRvid 2012test 0076 none none A man is riding an electric bicycle. A man is riding a bicycle.
7 main-captions MSRvid 2012test 0082 none none A man is playing the drums. A man is playing the guitar.
8 main-captions MSRvid 2012test 0092 none none A man is playing guitar. A lady is playing the guitar.
9 main-captions MSRvid 2012test 0095 none none A man is playing a guitar. A man is playing a trumpet.
10 main-captions MSRvid 2012test 0096 none none A man is playing a guitar. A man is playing a trumpet.
…
test.tsv數(shù)據(jù)樣式說明:
test.tsv中的數(shù)據(jù)內(nèi)容共分為9列, 含義與train.tsv前9列相同.
STS-B數(shù)據(jù)集的任務類型:
句子對多分類任務/句子對回歸任務
評估指標為: Pearson-Spearman Corr
QQP數(shù)據(jù)集文件樣式
- QQP/
- dev.tsv
- original/
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test.tsv是不帶有標簽的數(shù)據(jù).
train.tsv數(shù)據(jù)樣式:
id qid1 qid2 question1 question2 is_duplicate
133273 213221 213222 How is the life of a math student? Could you describe your own experiences?Which level of prepration is enough for the exam jlpt5? 0
402555 536040 536041 How do I control my horny emotions? How do you control your horniness? 1
360472 364011 490273 What causes stool color to change to yellow? What can cause stool to come out as little balls? 0
150662 155721 7256 What can one do after MBBS? What do i do after my MBBS ? 1
183004 279958 279959 Where can I find a power outlet for my laptop at Melbourne Airport? Would a second airport in Sydney, Australia be needed if a high-speed rail link was created between Melbourne and Sydney? 0
119056 193387 193388 How not to feel guilty since I am Muslim and I’m conscious we won’t have sex together? I don’t beleive I am bulimic, but I force throw up atleast once a day after I eat something and feel guilty. Should I tell somebody, and if so who? 0
356863 422862 96457 How is air traffic controlled? How do you become an air traffic controller?0
106969 147570 787 What is the best self help book you have read? Why? How did it change your life? What are the top self help books I should read? 1
…
train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為6列, 第一列代表文本數(shù)據(jù)索引; 第二列和第三列數(shù)據(jù)分別代表問題1和問題2的id; 第四列和第五列代表需要進行’是否重復’判定的句子對; 第六列代表上述問題是/不是重復性問題的標簽, 0代表不重復, 1代表重復.
test.tsv數(shù)據(jù)樣式:
id question1 question2
0 Would the idea of Trump and Putin in bed together scare you, given the geopolitical implications? Do you think that if Donald Trump were elected President, he would be able to restore relations with Putin and Russia as he said he could, based on the rocky relationship Putin had with Obama and Bush?
1 What are the top ten Consumer-to-Consumer E-commerce online? What are the top ten Consumer-to-Business E-commerce online?
2 Why don’t people simply ‘Google’ instead of asking questions on Quora? Why do people ask Quora questions instead of just searching google?
3 Is it safe to invest in social trade biz? Is social trade geniune?
4 If the universe is expanding then does matter also expand? If universe and space is expanding? Does that mean anything that occupies space is also expanding?
5 What is the plural of hypothesis? What is the plural of thesis?
6 What is the application form you need for launching a company? What is the application form you need for launching a company in Austria?
7 What is Big Theta? When should I use Big Theta as opposed to big O? Is O(Log n) close to O(n) or O(1)?
8 What are the health implications of accidentally eating a small quantity of aluminium foil?What are the implications of not eating vegetables?
…
test.tsv數(shù)據(jù)樣式說明:
test.tsv中的數(shù)據(jù)內(nèi)容共分為3列, 第一列數(shù)據(jù)代表每條文本數(shù)據(jù)的索引; 第二列和第三列數(shù)據(jù)代表用于測試的問題句子對.
QQP數(shù)據(jù)集的任務類型:
句子對二分類任務
評估指標為: ACC/F1
(MNLI/SNLI)數(shù)據(jù)集文件樣式
- (MNLI/SNLI)/
- dev_matched.tsv
- dev_mismatched.tsv
- original/
- test_matched.tsv
- test_mismatched.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev_matched.tsv, dev_mismatched.tsv, test_matched.tsv, test_mismatched.tsv分別代表訓練集, 與訓練集一同采集的驗證集, 與訓練集不是一同采集驗證集, 與訓練集一同采集的測試集, 與訓練集不是一同采集測試集. 其中train.tsv與dev_matched.tsv和dev_mismatched.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test_matched.tsv與test_mismatched.tsv數(shù)據(jù)樣式相同, 都是不帶有標簽的數(shù)據(jù).
train.tsv數(shù)據(jù)樣式:
index promptID pairID genre sentence1_binary_parse sentence2_binary_parse sentence1_parse sentence2_parse sentence1 sentence2 label1 gold_label
0 31193 31193n government ( ( Conceptually ( cream skimming ) ) ( ( has ( ( ( two ( basic dimensions ) ) - ) ( ( product and ) geography ) ) ) . ) ) ( ( ( Product and ) geography ) ( ( are ( what ( make ( cream ( skimming work ) ) ) ) ) . ) ) (ROOT (S (NP (JJ Conceptually) (NN cream) (NN skimming)) (VP (VBZ has) (NP (NP (CD two) (JJ basic) (NNS dimensions)) (: -) (NP (NN product) (CC and) (NN geography)))) (. .))) (ROOT (S (NP (NN Product) (CC and) (NN geography)) (VP (VBP are) (SBAR (WHNP (WP what)) (S (VP (VBP make) (NP (NP (NN cream)) (VP (VBG skimming) (NP (NN work)))))))) (. .))) Conceptually cream skimming has two basic dimensions - product and geography. Product and geography are what make cream skimming work. neutral neutral
1 101457 101457e telephone ( you ( ( know ( during ( ( ( the season ) and ) ( i guess ) ) ) ) ( at ( at ( ( your level ) ( uh ( you ( ( ( lose them ) ( to ( the ( next level ) ) ) ) ( if ( ( if ( they ( decide ( to ( recall ( the ( the ( parent team ) ) ) ) ) ) ) ) ( ( the Braves ) ( decide ( to ( call ( to ( ( recall ( a guy ) ) ( from ( ( triple A ) ( ( ( then ( ( a ( double ( A guy ) ) ) ( ( goes up ) ( to ( replace him ) ) ) ) ) and ) ( ( a ( single ( A guy ) ) ) ( ( goes up ) ( to ( replace him ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ( You ( ( ( ( lose ( the things ) ) ( to ( the ( following level ) ) ) ) ( if ( ( the people ) recall ) ) ) . ) ) (ROOT (S (NP (PRP you)) (VP (VBP know) (PP (IN during) (NP (NP (DT the) (NN season)) (CC and) (NP (FW i) (FW guess)))) (PP (IN at) (IN at) (NP (NP (PRP$ your) (NN level)) (SBAR (S (INTJ (UH uh)) (NP (PRP you)) (VP (VBP lose) (NP (PRP them)) (PP (TO to) (NP (DT the) (JJ next) (NN level))) (SBAR (IN if) (S (SBAR (IN if) (S (NP (PRP they)) (VP (VBP decide) (S (VP (TO to) (VP (VB recall) (NP (DT the) (DT the) (NN parent) (NN team)))))))) (NP (DT the) (NNPS Braves)) (VP (VBP decide) (S (VP (TO to) (VP (VB call) (S (VP (TO to) (VP (VB recall) (NP (DT a) (NN guy)) (PP (IN from) (NP (NP (RB triple) (DT A)) (SBAR (S (S (ADVP (RB then)) (NP (DT a) (JJ double) (NNP A) (NN guy)) (VP (VBZ goes) (PRT (RP up)) (S (VP (TO to) (VP (VB replace) (NP (PRP him))))))) (CC and) (S (NP (DT a) (JJ single) (NNP A) (NN guy)) (VP (VBZ goes) (PRT (RP up)) (S (VP (TO to) (VP (VB replace) (NP (PRP him)))))))))))))))))))))))))))) (ROOT (S (NP (PRP You)) (VP (VBP lose) (NP (DT the) (NNS things)) (PP (TO to) (NP (DT the) (JJ following) (NN level))) (SBAR (IN if) (S (NP (DT the) (NNS people)) (VP (VBP recall))))) (. .))) you know during the season and i guess at at your level uh you lose them to the next level if if they decide to recall the the parent team the Braves decide to call to recall a guy from triple A then a double A guy goes up to replace him and a single A guy goes up to replace him You lose the things to the following level if the people recall. entailment entailment
2 134793 134793e fiction ( ( One ( of ( our number ) ) ) ( ( will ( ( ( carry out ) ( your instructions ) ) minutely ) ) . ) ) ( ( ( A member ) ( of ( my team ) ) ) ( ( will ( ( execute ( your orders ) ) ( with ( immense precision ) ) ) ) . ) ) (ROOT (S (NP (NP (CD One)) (PP (IN of) (NP (PRP$ our) (NN number)))) (VP (MD will) (VP (VB carry) (PRT (RP out)) (NP (PRP$ your) (NNS instructions)) (ADVP (RB minutely)))) (. .))) (ROOT (S (NP (NP (DT A) (NN member)) (PP (IN of) (NP (PRP$ my) (NN team)))) (VP (MD will) (VP (VB execute) (NP (PRP$ your) (NNS orders)) (PP (IN with) (NP (JJ immense) (NN precision))))) (. .))) One of our number will carry out your instructions minutely. A member of my team will execute your orders with immense precision. entailment entailment
3 37397 37397e fiction ( ( How ( ( ( do you ) know ) ? ) ) ( ( All this ) ( ( ( is ( their information ) ) again ) . ) ) ) ( ( This information ) ( ( belongs ( to them ) ) . ) ) (ROOT (S (SBARQ (WHADVP (WRB How)) (SQ (VBP do) (NP (PRP you)) (VP (VB know))) (. ?)) (NP (PDT All) (DT this)) (VP (VBZ is) (NP (PRP$ their) (NN information)) (ADVP (RB again))) (. .))) (ROOT (S (NP (DT This) (NN information)) (VP (VBZ belongs) (PP (TO to) (NP (PRP them)))) (. .))) How do you know? All this is their information again. This information belongs to them. entailment entailment
…
train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為12列, 第一列代表文本數(shù)據(jù)索引; 第二列和第三列數(shù)據(jù)分別代表句子對的不同類型id; 第四列代表句子對的來源; 第五列和第六列代表具有句法結(jié)構(gòu)分析的句子對表示; 第七列和第八列代表具有句法結(jié)構(gòu)和詞性標注的句子對表示, 第九列和第十列代表原始的句子對, 第十一和第十二列代表不同標準的標注方法產(chǎn)生的標簽, 在這里,他們始終相同, 一共有三種類型的標簽, neutral代表兩個句子既不矛盾也不蘊含, entailment代表兩個句子具有蘊含關(guān)系, contradiction代表兩個句子觀點矛盾.
test_matched.tsv數(shù)據(jù)樣式:
index promptID pairID genre sentence1_binary_parse sentence2_binary_parse sentence1_parse sentence2_parse sentence1 sentence2
0 31493 31493 travel ( ( ( ( ( ( ( ( Hierbas , ) ( ans seco ) ) , ) ( ans dulce ) ) , ) and ) frigola ) ( ( ( are just ) ( ( a ( few names ) ) ( worth ( ( keeping ( a look-out ) ) for ) ) ) ) . ) ) ( Hierbas ( ( is ( ( a name ) ( worth ( ( looking out ) for ) ) ) ) . ) ) (ROOT (S (NP (NP (NNS Hierbas)) (, ,) (NP (NN ans) (NN seco)) (, ,) (NP (NN ans) (NN dulce)) (, ,) (CC and) (NP (NN frigola))) (VP (VBP are) (ADVP (RB just)) (NP (NP (DT a) (JJ few) (NNS names)) (PP (JJ worth) (S (VP (VBG keeping) (NP (DT a) (NN look-out)) (PP (IN for))))))) (. .))) (ROOT (S (NP (NNS Hierbas)) (VP (VBZ is) (NP (NP (DT a) (NN name)) (PP (JJ worth) (S (VP (VBG looking) (PRT (RP out)) (PP (IN for))))))) (. .))) Hierbas, ans seco, ans dulce, and frigola are just a few names worth keeping a look-out for. Hierbas is a name worth looking out for.
1 92164 92164 government ( ( ( The extent ) ( of ( the ( behavioral effects ) ) ) ) ( ( would ( ( depend ( in ( part ( on ( ( the structure ) ( of ( ( ( the ( individual ( account program ) ) ) and ) ( any limits ) ) ) ) ) ) ) ) ( on ( accessing ( the funds ) ) ) ) ) . ) ) ( ( Many people ) ( ( would ( be ( very ( unhappy ( to ( ( loose control ) ( over ( their ( own money ) ) ) ) ) ) ) ) ) . ) ) (ROOT (S (NP (NP (DT The) (NN extent)) (PP (IN of) (NP (DT the) (JJ behavioral) (NNS effects)))) (VP (MD would) (VP (VB depend) (PP (IN in) (NP (NP (NN part)) (PP (IN on) (NP (NP (DT the) (NN structure)) (PP (IN of) (NP (NP (DT the) (JJ individual) (NN account) (NN program)) (CC and) (NP (DT any) (NNS limits)))))))) (PP (IN on) (S (VP (VBG accessing) (NP (DT the) (NNS funds))))))) (. .))) (ROOT (S (NP (JJ Many) (NNS people)) (VP (MD would) (VP (VB be) (ADJP (RB very) (JJ unhappy) (PP (TO to) (NP (NP (JJ loose) (NN control)) (PP (IN over) (NP (PRP$ their) (JJ own) (NN money)))))))) (. .))) The extent of the behavioral effects would depend in part on the structure of the individual account program and any limits on accessing the funds. Many people would be very unhappy to loose control over their own money.
2 9662 9662 government ( ( ( Timely access ) ( to information ) ) ( ( is ( in ( ( the ( best interests ) ) ( of ( ( ( both GAO ) and ) ( the agencies ) ) ) ) ) ) . ) ) ( It ( ( ( is ( in ( ( everyone 's ) ( best interest ) ) ) ) ( to ( ( have access ) ( to ( information ( in ( a ( timely manner ) ) ) ) ) ) ) ) . ) ) (ROOT (S (NP (NP (JJ Timely) (NN access)) (PP (TO to) (NP (NN information)))) (VP (VBZ is) (PP (IN in) (NP (NP (DT the) (JJS best) (NNS interests)) (PP (IN of) (NP (NP (DT both) (NNP GAO)) (CC and) (NP (DT the) (NNS agencies))))))) (. .))) (ROOT (S (NP (PRP It)) (VP (VBZ is) (PP (IN in) (NP (NP (NN everyone) (POS 's)) (JJS best) (NN interest))) (S (VP (TO to) (VP (VB have) (NP (NN access)) (PP (TO to) (NP (NP (NN information)) (PP (IN in) (NP (DT a) (JJ timely) (NN manner))))))))) (. .))) Timely access to information is in the best interests of both GAO and the agencies. It is in everyone’s best interest to have access to information in a timely manner.
3 5991 5991 travel ( ( Based ( in ( ( the ( Auvergnat ( spa town ) ) ) ( of Vichy ) ) ) ) ( , ( ( the ( French government ) ) ( often ( ( ( ( proved ( more zealous ) ) ( than ( its masters ) ) ) ( in ( ( ( suppressing ( civil liberties ) ) and ) ( ( drawing up ) ( anti-Jewish legislation ) ) ) ) ) . ) ) ) ) ) ( ( The ( French government ) ) ( ( passed ( ( anti-Jewish laws ) ( aimed ( at ( helping ( the Nazi ) ) ) ) ) ) . ) ) (ROOT (S (PP (VBN Based) (PP (IN in) (NP (NP (DT the) (NNP Auvergnat) (NN spa) (NN town)) (PP (IN of) (NP (NNP Vichy)))))) (, ,) (NP (DT the) (JJ French) (NN government)) (ADVP (RB often)) (VP (VBD proved) (NP (JJR more) (NNS zealous)) (PP (IN than) (NP (PRP$ its) (NNS masters))) (PP (IN in) (S (VP (VP (VBG suppressing) (NP (JJ civil) (NNS liberties))) (CC and) (VP (VBG drawing) (PRT (RP up)) (NP (JJ anti-Jewish) (NN legislation))))))) (. .))) (ROOT (S (NP (DT The) (JJ French) (NN government)) (VP (VBD passed) (NP (NP (JJ anti-Jewish) (NNS laws)) (VP (VBN aimed) (PP (IN at) (S (VP (VBG helping) (NP (DT the) (JJ Nazi)))))))) (. .))) Based in the Auvergnat spa town of Vichy, the French government often proved more zealous than its masters in suppressing civil liberties and drawing up anti-Jewish legislation. The French government passed anti-Jewish laws aimed at helping the Nazi.
…
test_matched.tsv數(shù)據(jù)樣式說明:
test_matched.tsv中的數(shù)據(jù)內(nèi)容共分為10列, 與train.tsv的前10列含義相同.
(MNLI/SNLI)數(shù)據(jù)集的任務類型:
句子對多分類任務
評估指標為: ACC
(QNLI/RTE/WNLI)數(shù)據(jù)集文件樣式
- QNLI, RTE, WNLI三個數(shù)據(jù)集的樣式基本相同.
- (QNLI/RTE/WNLI)/
- dev.tsv
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數(shù)據(jù)樣式相同, 都是帶有標簽的數(shù)據(jù), 其中test.tsv是不帶有標簽的數(shù)據(jù).
QNLI中的train.tsv數(shù)據(jù)樣式:
index question sentence label
0 When did the third Digimon series begin? Unlike the two seasons before it and most of the seasons that followed, Digimon Tamers takes a darker and more realistic approach to its story featuring Digimon who do not reincarnate after their deaths and more complex character development in the original Japanese. not_entailment
1 Which missile batteries often have individual launchers several kilometres from one another? When MANPADS is operated by specialists, batteries may have several dozen teams deploying separately in small sections; self-propelled air defence guns may deploy in pairs. not_entailment
2 What two things does Popper argue Tarski’s theory involves in an evaluation of truth? He bases this interpretation on the fact that examples such as the one described above refer to two things: assertions and the facts to which they refer. entailment
3 What is the name of the village 9 miles north of Calafat where the Ottoman forces attacked the Russians? On 31 December 1853, the Ottoman forces at Calafat moved against the Russian force at Chetatea or Cetate, a small village nine miles north of Calafat, and engaged them on 6 January 1854. entailment
4 What famous palace is located in London? London contains four World Heritage Sites: the Tower of London; Kew Gardens; the site comprising the Palace of Westminster, Westminster Abbey, and St Margaret’s Church; and the historic settlement of Greenwich (in which the Royal Observatory, Greenwich marks the Prime Meridian, 0° longitude, and GMT). not_entailment
5 When is the term ‘German dialects’ used in regard to the German language? When talking about the German language, the term German dialects is only used for the traditional regional varieties. entailment
6 What was the name of the island the English traded to the Dutch in return for New Amsterdam? At the end of the Second Anglo-Dutch War, the English gained New Amsterdam (New York) in North America in exchange for Dutch control of Run, an Indonesian island. entailment
7 How were the Portuguese expelled from Myanmar? From the 1720s onward, the kingdom was beset with repeated Meithei raids into Upper Myanmar and a nagging rebellion in Lan Na. not_entailment
8 What does the word ‘customer’ properly apply to? The bill also required rotation of principal maintenance inspectors and stipulated that the word “customer” properly applies to the flying public, not those entities regulated by the FAA. entailment
…
RTE中的train.tsv數(shù)據(jù)樣式:
index sentence1 sentence2 label
0 No Weapons of Mass Destruction Found in Iraq Yet. Weapons of Mass Destruction Found in Iraq. not_entailment
1 A place of sorrow, after Pope John Paul II died, became a place of celebration, as Roman Catholic faithful gathered in downtown Chicago to mark the installation of new Pope Benedict XVI.Pope Benedict XVI is the new leader of the Roman Catholic Church. entailment
2 Herceptin was already approved to treat the sickest breast cancer patients, and the company said, Monday, it will discuss with federal regulators the possibility of prescribing the drug for more breast cancer patients. Herceptin can be used to treat breast cancer. entailment
3 Judie Vivian, chief executive at ProMedica, a medical service company that helps sustain the 2-year-old Vietnam Heart Institute in Ho Chi Minh City (formerly Saigon), said that so far about 1,500 children have received treatment. The previous name of Ho Chi Minh City was Saigon.entailment
4 A man is due in court later charged with the murder 26 years ago of a teenager whose case was the first to be featured on BBC One’s Crimewatch. Colette Aram, 16, was walking to her boyfriend’s house in Keyworth, Nottinghamshire, on 30 October 1983 when she disappeared. Her body was later found in a field close to her home. Paul Stewart Hutchinson, 50, has been charged with murder and is due before Nottingham magistrates later. Paul Stewart Hutchinson is accused of having stabbed a girl. not_entailment
5 Britain said, Friday, that it has barred cleric, Omar Bakri, from returning to the country from Lebanon, where he was released by police after being detained for 24 hours. Bakri was briefly detained, but was released. entailment
6 Nearly 4 million children who have at least one parent who entered the U.S. illegally were born in the United States and are U.S. citizens as a result, according to the study conducted by the Pew Hispanic Center. That’s about three quarters of the estimated 5.5 million children of illegal immigrants inside the United States, according to the study. About 1.8 million children of undocumented immigrants live in poverty, the study found. Three quarters of U.S. illegal immigrants have children. not_entailment
7 Like the United States, U.N. officials are also dismayed that Aristide killed a conference called by Prime Minister Robert Malval in Port-au-Prince in hopes of bringing all the feuding parties together. Aristide had Prime Minister Robert Malval murdered in Port-au-Prince. not_entailment
8 WASHINGTON – A newly declassified narrative of the Bush administration’s advice to the CIA on harsh interrogations shows that the small group of Justice Department lawyers who wrote memos authorizing controversial interrogation techniques were operating not on their own but with direction from top administration officials, including then-Vice President Dick Cheney and national security adviser Condoleezza Rice. At the same time, the narrative suggests that then-Defense Secretary Donald H. Rumsfeld and then-Secretary of State Colin Powell were largely left out of the decision-making process. Dick Cheney was the Vice President of Bush. entailment
WNLI中的train.tsv數(shù)據(jù)樣式:
index sentence1 sentence2 label
0 I stuck a pin through a carrot. When I pulled the pin out, it had a hole. The carrot had a hole. 1
1 John couldn’t see the stage with Billy in front of him because he is so short. John is so short. 1
2 The police arrested all of the gang members. They were trying to stop the drug trade in the neighborhood. The police were trying to stop the drug trade in the neighborhood. 1
3 Steve follows Fred’s example in everything. He influences him hugely. Steve influences him hugely. 0
4 When Tatyana reached the cabin, her mother was sleeping. She was careful not to disturb her, undressing and climbing back into her berth. mother was careful not to disturb her, undressing and climbing back into her berth. 0
5 George got free tickets to the play, but he gave them to Eric, because he was particularly eager to see it. George was particularly eager to see it. 0
6 John was jogging through the park when he saw a man juggling watermelons. He was very impressive. John was very impressive. 0
7 I couldn’t put the pot on the shelf because it was too tall. The pot was too tall. 1
8 We had hoped to place copies of our newsletter on all the chairs in the auditorium, but there were simply not enough of them. There were simply not enough copies of the newsletter. 1
(QNLI/RTE/WNLI)中的train.tsv數(shù)據(jù)樣式說明:
train.tsv中的數(shù)據(jù)內(nèi)容共分為4列, 第一列代表文本數(shù)據(jù)索引; 第二列和第三列數(shù)據(jù)代表需要進行’是否蘊含’判定的句子對; 第四列數(shù)據(jù)代表兩個句子是否具有蘊含關(guān)系, 0/not_entailment代表不是蘊含關(guān)系, 1/entailment代表蘊含關(guān)系.
QNLI中的test.tsv數(shù)據(jù)樣式:
index question sentence
0 What organization is devoted to Jihad against Israel? For some decades prior to the First Palestine Intifada in 1987, the Muslim Brotherhood in Palestine took a “quiescent” stance towards Israel, focusing on preaching, education and social services, and benefiting from Israel’s “indulgence” to build up a network of mosques and charitable organizations.
1 In what century was the Yarrow-Schlick-Tweedy balancing system used? In the late 19th century, the Yarrow-Schlick-Tweedy balancing ‘system’ was used on some marine triple expansion engines.
2 The largest brand of what store in the UK is located in Kingston Park? Close to Newcastle, the largest indoor shopping centre in Europe, the MetroCentre, is located in Gateshead.
3 What does the IPCC rely on for research? In principle, this means that any significant new evidence or events that change our understanding of climate science between this deadline and publication of an IPCC report cannot be included.
4 What is the principle about relating spin and space variables? Thus in the case of two fermions there is a strictly negative correlation between spatial and spin variables, whereas for two bosons (e.g. quanta of electromagnetic waves, photons) the correlation is strictly positive.
5 Which network broadcasted Super Bowl 50 in the U.S.? CBS broadcast Super Bowl 50 in the U.S., and charged an average of $5 million for a 30-second commercial during the game.
6 What did the museum acquire from the Royal College of Science? To link this to the rest of the museum, a new entrance building was constructed on the site of the former boiler house, the intended site of the Spiral, between 1978 and 1982.
7 What is the name of the old north branch of the Rhine? From Wijk bij Duurstede, the old north branch of the Rhine is called Kromme Rijn (“Bent Rhine”) past Utrecht, first Leidse Rijn (“Rhine of Leiden”) and then, Oude Rijn (“Old Rhine”).
8 What was one of Luther’s most personal writings? It remains in use today, along with Luther’s hymns and his translation of the Bible.
…
(RTE/WNLI)中的test.tsv數(shù)據(jù)樣式:
index sentence1 sentence2
0 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they came in sight. Horses ran away when Maude and Dora came in sight.
1 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they came in sight. Horses ran away when the trains came in sight.
2 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they came in sight. Horses ran away when the puffs came in sight.
3 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they came in sight. Horses ran away when the roars came in sight.
4 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they came in sight. Horses ran away when the whistles came in sight.
5 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they came in sight. Horses ran away when the horses came in sight.
6 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they saw a train coming. Maude and Dora saw a train coming.
7 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they saw a train coming. The trains saw a train coming.
8 Maude and Dora had seen the trains rushing across the prairie, with long, rolling puffs of black smoke streaming back from the engine. Their roars and their wild, clear whistles could be heard from far away. Horses ran away when they saw a train coming. The puffs saw a train coming.
…
(QNLI/RTE/WNLI)中的test.tsv數(shù)據(jù)樣式說明:
test.tsv中的數(shù)據(jù)內(nèi)容共分為3列, 第一列數(shù)據(jù)代表每條文本數(shù)據(jù)的索引; 第二列和第三列數(shù)據(jù)代表需要進行’是否蘊含’判定的句子對.
(QNLI/RTE/WNLI)數(shù)據(jù)集的任務類型:
句子對二分類任務
評估指標為: ACC
小節(jié)總結(jié)
學習了GLUE數(shù)據(jù)集合的介紹:
GLUE由紐約大學, 華盛頓大學, Google聯(lián)合推出, 涵蓋不同NLP任務類型, 截止至2020年1月其中包括11個子任務數(shù)據(jù)集, 成為衡量NLP研究發(fā)展的衡量標準.
GLUE數(shù)據(jù)集合包含以下數(shù)據(jù)集:
CoLA 數(shù)據(jù)集
SST-2 數(shù)據(jù)集
MRPC 數(shù)據(jù)集
STS-B 數(shù)據(jù)集
QQP 數(shù)據(jù)集
MNLI 數(shù)據(jù)集
SNLI 數(shù)據(jù)集
QNLI 數(shù)據(jù)集
RTE 數(shù)據(jù)集
WNLI 數(shù)據(jù)集
2.3 NLP中的常用預訓練模型
學習目標
了解當下NLP中流行的預訓練模型.
掌握如何加載和使用預訓練模型.
當下NLP中流行的預訓練模型
BERT
GPT
GPT-2
Transformer-XL
XLNet
XLM
RoBERTa
DistilBERT
ALBERT
T5
XLM-RoBERTa
BERT及其變體:
bert-base-uncased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數(shù)量, 在小寫的英文文本上進行訓練而得到.
bert-large-uncased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共340M參數(shù)量, 在小寫的英文文本上進行訓練而得到.
bert-base-cased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數(shù)量, 在不區(qū)分大小寫的英文文本上進行訓練而得到.
bert-large-cased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共340M參數(shù)量, 在不區(qū)分大小寫的英文文本上進行訓練而得到.
bert-base-multilingual-uncased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數(shù)量, 在小寫的102種語言文本上進行訓練而得到.
bert-large-multilingual-uncased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共340M參數(shù)量, 在小寫的102種語言文本上進行訓練而得到.
bert-base-chinese: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數(shù)量, 在簡體和繁體中文文本上進行訓練而得到.
GPT:
openai-gpt: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數(shù)量, 由OpenAI在英文語料上進行訓練而得到.
GPT-2及其變體:
gpt2: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共117M參數(shù)量, 在OpenAI GPT-2英文語料上進行訓練而得到.
gpt2-xl: 編碼器具有48個隱層, 輸出1600維張量, 25個自注意力頭, 共1558M參數(shù)量, 在大型的OpenAI GPT-2英文語料上進行訓練而得到.
Transformer-XL:
transfo-xl-wt103: 編碼器具有18個隱層, 輸出1024維張量, 16個自注意力頭, 共257M參數(shù)量, 在wikitext-103英文語料進行訓練而得到.
XLNet及其變體:
xlnet-base-cased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數(shù)量, 在英文語料上進行訓練而得到.
xlnet-large-cased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共240參數(shù)量, 在英文語料上進行訓練而得到.
XLM:
xlm-mlm-en-2048: 編碼器具有12個隱層, 輸出2048維張量, 16個自注意力頭, 在英文文本上進行訓練而得到.
RoBERTa及其變體:
roberta-base: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共125M參數(shù)量, 在英文文本上進行訓練而得到.
roberta-large: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共355M參數(shù)量, 在英文文本上進行訓練而得到.
DistilBERT及其變體:
distilbert-base-uncased: 基于bert-base-uncased的蒸餾(壓縮)模型, 編碼器具有6個隱層, 輸出768維張量, 12個自注意力頭, 共66M參數(shù)量.
distilbert-base-multilingual-cased: 基于bert-base-multilingual-uncased的蒸餾(壓縮)模型, 編碼器具有6個隱層, 輸出768維張量, 12個自注意力頭, 共66M參數(shù)量.
ALBERT:
albert-base-v1: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共125M參數(shù)量, 在英文文本上進行訓練而得到.
albert-base-v2: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共125M參數(shù)量, 在英文文本上進行訓練而得到, 相比v1使用了更多的數(shù)據(jù)量, 花費更長的訓練時間.
T5及其變體:
t5-small: 編碼器具有6個隱層, 輸出512維張量, 8個自注意力頭, 共60M參數(shù)量, 在C4語料上進行訓練而得到.
t5-base: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共220M參數(shù)量, 在C4語料上進行訓練而得到.
t5-large: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共770M參數(shù)量, 在C4語料上進行訓練而得到.
XLM-RoBERTa及其變體:
xlm-roberta-base: 編碼器具有12個隱層, 輸出768維張量, 8個自注意力頭, 共125M參數(shù)量, 在2.5TB的100種語言文本上進行訓練而得到.
xlm-roberta-large: 編碼器具有24個隱層, 輸出1027維張量, 16個自注意力頭, 共355M參數(shù)量, 在2.5TB的100種語言文本上進行訓練而得到.
預訓練模型說明:
所有上述預訓練模型及其變體都是以transformer為基礎(chǔ),只是在模型結(jié)構(gòu)如神經(jīng)元連接方式,編碼器隱層數(shù),多頭注意力的頭數(shù)等發(fā)生改變,這些改變方式的大部分依據(jù)都是由在標準數(shù)據(jù)集上的表現(xiàn)而定,因此,對于我們使用者而言,不需要從理論上深度探究這些預訓練模型的結(jié)構(gòu)設(shè)計的優(yōu)劣,只需要在自己處理的目標數(shù)據(jù)上,盡量遍歷所有可用的模型對比得到最優(yōu)效果即可.
小節(jié)總結(jié)
當下NLP中流行的預訓練模型:
BERT
GPT
GPT-2
Transformer-XL
XLNet
XLM
RoBERTa
DistilBERT
ALBERT
T5
XLM-RoBERTa
2.4 加載和使用預訓練模型
學習目標
了解加載和使用預訓練模型的工具.
掌握加載和使用預訓練模型的過程.
加載和使用預訓練模型的工具
在這里我們使用torch.hub工具進行模型的加載和使用.
這些預訓練模型由世界先進的NLP研發(fā)團隊huggingface提供.
注意: 下面使用的代碼需要國外服務器的資源, 在國內(nèi)使用的時候, 國內(nèi)的網(wǎng)站下載可能會出現(xiàn)在原地卡死不動, 或是網(wǎng)絡(luò)連接超時等一些網(wǎng)絡(luò)報錯, 均是網(wǎng)絡(luò)問題, 不是代碼問題, 這個可以先行跳過, 把主要邏輯梳理完成即可
加載和使用預訓練模型的步驟
第一步: 確定需要加載的預訓練模型并安裝依賴包.
第二步: 加載預訓練模型的映射器tokenizer.
第三步: 加載帶/不帶頭的預訓練模型.
第四步: 使用模型獲得輸出結(jié)果.
第一步: 確定需要加載的預訓練模型并安裝依賴包
能夠加載哪些模型可以參考2.3 NLP中的常用預訓練模型
這里假設(shè)我們處理的是中文文本任務, 需要加載的模型是BERT的中文模型: bert-base-chinese
在使用工具加載模型前需要安裝必備的依賴包:
pip install tqdm boto3 requests regex sentencepiece sacremoses
第二步: 加載預訓練模型的映射器tokenizer
import torch
預訓練模型來源
source = ‘huggingface/pytorch-transformers’
選定加載模型的哪一部分, 這里是模型的映射器
part = ‘tokenizer’
加載的預訓練模型的名字
model_name = ‘bert-base-chinese’
tokenizer = torch.hub.load(source, part, model_name)
第三步: 加載帶/不帶頭的預訓練模型
加載預訓練模型時我們可以選擇帶頭或者不帶頭的模型
這里的’頭’是指模型的任務輸出層, 選擇加載不帶頭的模型, 相當于使用模型對輸入文本進行特征表示.
選擇加載帶頭的模型時, 有三種類型的’頭’可供選擇, modelWithLMHead(語言模型頭), modelForSequenceClassification(分類模型頭), modelForQuestionAnswering(問答模型頭)
不同類型的’頭’, 可以使預訓練模型輸出指定的張量維度. 如使用’分類模型頭’, 則輸出尺寸為(1,2)的張量, 用于進行分類任務判定結(jié)果.
加載不帶頭的預訓練模型
part = ‘model’
model = torch.hub.load(source, part, model_name)
加載帶有語言模型頭的預訓練模型
part = ‘modelWithLMHead’
lm_model = torch.hub.load(source, part, model_name)
加載帶有類模型頭的預訓練模型
part = ‘modelForSequenceClassification’
classification_model = torch.hub.load(source, part, model_name)
加載帶有問答模型頭的預訓練模型
part = ‘modelForQuestionAnswering’
qa_model = torch.hub.load(source, part, model_name)
第四步: 使用模型獲得輸出結(jié)果
使用不帶頭的模型進行輸出:
輸入的中文文本
input_text = “人生該如何起頭”
使用tokenizer進行數(shù)值映射
indexed_tokens = tokenizer.encode(input_text)
打印映射后的結(jié)構(gòu)
print(“indexed_tokens:”, indexed_tokens)
將映射結(jié)構(gòu)轉(zhuǎn)化為張量輸送給不帶頭的預訓練模型
tokens_tensor = torch.tensor([indexed_tokens])
使用不帶頭的預訓練模型獲得結(jié)果
with torch.no_grad():
encoded_layers, _ = model(tokens_tensor)
print(“不帶頭的模型輸出結(jié)果:”, encoded_layers)
print(“不帶頭的模型輸出結(jié)果的尺寸:”, encoded_layers.shape)
輸出效果:
tokenizer映射后的結(jié)果, 101和102是起止符,
中間的每個數(shù)字對應"人生該如何起頭"的每個字.
indexed_tokens: [101, 782, 4495, 6421, 1963, 862, 6629, 1928, 102]
不帶頭的模型輸出結(jié)果: tensor([[[ 0.5421, 0.4526, -0.0179, …, 1.0447, -0.1140, 0.0068],
[-0.1343, 0.2785, 0.1602, …, -0.0345, -0.1646, -0.2186],
[ 0.9960, -0.5121, -0.6229, …, 1.4173, 0.5533, -0.2681],
…,
[ 0.0115, 0.2150, -0.0163, …, 0.6445, 0.2452, -0.3749],
[ 0.8649, 0.4337, -0.1867, …, 0.7397, -0.2636, 0.2144],
[-0.6207, 0.1668, 0.1561, …, 1.1218, -0.0985, -0.0937]]])
輸出尺寸為1x9x768, 即每個字已經(jīng)使用768維的向量進行了表示,
我們可以基于此編碼結(jié)果進行接下來的自定義操作, 如: 編寫自己的微調(diào)網(wǎng)絡(luò)進行最終輸出.
不帶頭的模型輸出結(jié)果的尺寸: torch.Size([1, 9, 768])
使用帶有語言模型頭的模型進行輸出:
使用帶有語言模型頭的預訓練模型獲得結(jié)果
with torch.no_grad():
lm_output = lm_model(tokens_tensor)
print(“帶語言模型頭的模型輸出結(jié)果:”, lm_output)
print(“帶語言模型頭的模型輸出結(jié)果的尺寸:”, lm_output[0].shape)
輸出效果:
帶語言模型頭的模型輸出結(jié)果: (tensor([[[ -7.9706, -7.9119, -7.9317, …, -7.2174, -7.0263, -7.3746],
[ -8.2097, -8.1810, -8.0645, …, -7.2349, -6.9283, -6.9856],
[-13.7458, -13.5978, -12.6076, …, -7.6817, -9.5642, -11.9928],
…,
[ -9.0928, -8.6857, -8.4648, …, -8.2368, -7.5684, -10.2419],
[ -8.9458, -8.5784, -8.6325, …, -7.0547, -5.3288, -7.8077],
[ -8.4154, -8.5217, -8.5379, …, -6.7102, -5.9782, -7.6909]]]),)
輸出尺寸為1x9x21128, 即每個字已經(jīng)使用21128維的向量進行了表示,
同不帶頭的模型一樣, 我們可以基于此編碼結(jié)果進行接下來的自定義操作, 如: 編寫自己的微調(diào)網(wǎng)絡(luò)進行最終輸出.
帶語言模型頭的模型輸出結(jié)果的尺寸: torch.Size([1, 9, 21128])
使用帶有分類模型頭的模型進行輸出:
使用帶有分類模型頭的預訓練模型獲得結(jié)果
with torch.no_grad():
classification_output = classification_model(tokens_tensor)
print(“帶分類模型頭的模型輸出結(jié)果:”, classification_output)
print(“帶分類模型頭的模型輸出結(jié)果的尺寸:”, classification_output[0].shape)
輸出效果:
帶分類模型頭的模型輸出結(jié)果: (tensor([[-0.0649, -0.1593]]),)
輸出尺寸為1x2, 可直接用于文本二分問題的輸出
帶分類模型頭的模型輸出結(jié)果的尺寸: torch.Size([1, 2])
使用帶有問答模型頭的模型進行輸出:
使用帶有問答模型頭的模型進行輸出時, 需要使輸入的形式為句子對
第一條句子是對客觀事物的陳述
第二條句子是針對第一條句子提出的問題
問答模型最終將得到兩個張量,
每個張量中最大值對應索引的分別代表答案的在文本中的起始位置和終止位置.
input_text1 = “我家的小狗是黑色的”
input_text2 = “我家的小狗是什么顏色的呢?”
映射兩個句子
indexed_tokens = tokenizer.encode(input_text1, input_text2)
print(“句子對的indexed_tokens:”, indexed_tokens)
輸出結(jié)果: [101, 2769, 2157, 4638, 2207, 4318, 3221, 7946, 5682, 4638, 102, 2769, 2157, 4638, 2207, 4318, 3221, 784, 720, 7582, 5682, 4638, 1450, 136, 102]
用0,1來區(qū)分第一條和第二條句子
segments_ids = [0]*11 + [1]*14
轉(zhuǎn)化張量形式
segments_tensors = torch.tensor([segments_ids])
tokens_tensor = torch.tensor([indexed_tokens])
使用帶有問答模型頭的預訓練模型獲得結(jié)果
with torch.no_grad():
start_logits, end_logits = qa_model(tokens_tensor, token_type_ids=segments_tensors)
print(“帶問答模型頭的模型輸出結(jié)果:”, (start_logits, end_logits))
print(“帶問答模型頭的模型輸出結(jié)果的尺寸:”, (start_logits.shape, end_logits.shape))
輸出效果:
句子對的indexed_tokens: [101, 2769, 2157, 4638, 2207, 4318, 3221, 7946, 5682, 4638, 102, 2769, 2157, 4638, 2207, 4318, 3221, 784, 720, 7582, 5682, 4638, 1450, 136, 102]
帶問答模型頭的模型輸出結(jié)果: (tensor([[ 0.2574, -0.0293, -0.8337, -0.5135, -0.3645, -0.2216, -0.1625, -0.2768,
-0.8368, -0.2581, 0.0131, -0.1736, -0.5908, -0.4104, -0.2155, -0.0307,
-0.1639, -0.2691, -0.4640, -0.1696, -0.4943, -0.0976, -0.6693, 0.2426,
0.0131]]), tensor([[-0.3788, -0.2393, -0.5264, -0.4911, -0.7277, -0.5425, -0.6280, -0.9800,
-0.6109, -0.2379, -0.0042, -0.2309, -0.4894, -0.5438, -0.6717, -0.5371,
-0.1701, 0.0826, 0.1411, -0.1180, -0.4732, -0.1541, 0.2543, 0.2163,
-0.0042]]))
輸出為兩個形狀1x25的張量, 他們是兩條句子合并長度的概率分布,
第一個張量中最大值所在的索引代表答案出現(xiàn)的起始索引,
第二個張量中最大值所在的索引代表答案出現(xiàn)的終止索引.
帶問答模型頭的模型輸出結(jié)果的尺寸: (torch.Size([1, 25]), torch.Size([1, 25]))
小節(jié)總結(jié)
加載和使用預訓練模型的工具:
在這里我們使用torch.hub工具進行模型的加載和使用. 這些預訓練模型由世界先進的NLP研發(fā)團隊huggingface提供.
加載和使用預訓練模型的步驟:
第一步: 確定需要加載的預訓練模型并安裝依賴包.
第二步: 加載預訓練模型的映射器tokenizer.
第三步: 加載帶/不帶頭的預訓練模型.
第四步: 使用模型獲得輸出結(jié)果.
2.5 遷移學習實踐
學習目標
了解并掌握指定任務類型的微調(diào)腳本使用方法.
了解并掌握通過微調(diào)腳本微調(diào)后模型的使用方法.
掌握通過微調(diào)方式進行遷移學習的兩種類型實現(xiàn)過程.
指定任務類型的微調(diào)腳本:
huggingface研究機構(gòu)向我們提供了針對GLUE數(shù)據(jù)集合任務類型的微調(diào)腳本, 這些微調(diào)腳本的核心都是微調(diào)模型的最后一個全連接層.
通過簡單的參數(shù)配置來指定GLUE中存在任務類型(如: CoLA對應文本二分類, MRPC對應句子對文本二分類, STS-B對應句子對文本多分類), 以及指定需要微調(diào)的預訓練模型.
指定任務類型的微調(diào)腳本使用步驟
第一步: 下載微調(diào)腳本文件
第二步: 配置微調(diào)腳本參數(shù)
第三步: 運行并檢驗效果
第一步: 下載微調(diào)腳本文件
克隆huggingface的transfomers文件
git clone https://github.com/huggingface/transformers.git
進行transformers文件夾
cd transformers
安裝python的transformer工具包, 因為微調(diào)腳本是py文件.
pip install .
當前的版本可能跟我們教學的版本并不相同,你還需要執(zhí)行:
pip install transformers==2.3.0
進入微調(diào)腳本所在路徑并查看
cd examples
ls
其中run_glue.py就是針對GLUE數(shù)據(jù)集合任務類型的微調(diào)腳本
注意:
對于run_glue.py,由于版本變更導致,請通過該地址http://git.itcast.cn/Stephen/AI-key-file/blob/master/run_glue.py復制里面的代碼,覆蓋原有內(nèi)容。
第二步: 配置微調(diào)腳本參數(shù)
在run_glue.py同級目錄下創(chuàng)建run_glue.sh文件, 寫入內(nèi)容如下:
定義DATA_DIR: 微調(diào)數(shù)據(jù)所在路徑, 這里我們使用glue_data中的數(shù)據(jù)作為微調(diào)數(shù)據(jù)
export DATA_DIR="…/…/glue_data"
定義SAVE_DIR: 模型的保存路徑, 我們將模型保存在當前目錄的bert_finetuning_test文件中
export SAVE_DIR="./bert_finetuning_test/"
使用python運行微調(diào)腳本
–model_type: 選擇需要微調(diào)的模型類型, 這里可以選擇BERT, XLNET, XLM, roBERTa, distilBERT, ALBERT
–model_name_or_path: 選擇具體的模型或者變體, 這里是在英文語料上微調(diào), 因此選擇bert-base-uncased
–task_name: 它將代表對應的任務類型, 如MRPC代表句子對二分類任務
–do_train: 使用微調(diào)腳本進行訓練
–do_eval: 使用微調(diào)腳本進行驗證
–data_dir: 訓練集及其驗證集所在路徑, 將自動尋找該路徑下的train.tsv和dev.tsv作為訓練集和驗證集
–max_seq_length: 輸入句子的最大長度, 超過則截斷, 不足則補齊
–learning_rate: 學習率
–num_train_epochs: 訓練輪數(shù)
–output_dir $SAVE_DIR: 訓練后的模型保存路徑
–overwrite_output_dir: 再次訓練時將清空之前的保存路徑內(nèi)容重新寫入
python run_glue.py
–model_type BERT
–model_name_or_path bert-base-uncased
–task_name MRPC
–do_train
–do_eval
–data_dir $DATA_DIR/MRPC/
–max_seq_length 128
–learning_rate 2e-5
–num_train_epochs 1.0
–output_dir $SAVE_DIR
–overwrite_output_dir
第三步: 運行并檢驗效果
使用sh命令運行
sh run_glue.sh
輸出效果:
最終打印模型的驗證結(jié)果:
01/05/2020 23:59:53 - INFO - main - Saving features into cached file …/…/glue_data/MRPC/cached_dev_bert-base-uncased_128_mrpc
01/05/2020 23:59:53 - INFO - main - ***** Running evaluation *****
01/05/2020 23:59:53 - INFO - main - Num examples = 408
01/05/2020 23:59:53 - INFO - main - Batch size = 8
Evaluating: 100%|█| 51/51 [00:23<00:00, 2.20it/s]
01/06/2020 00:00:16 - INFO - main - ***** Eval results *****
01/06/2020 00:00:16 - INFO - main - acc = 0.7671568627450981
01/06/2020 00:00:16 - INFO - main - acc_and_f1 = 0.8073344506341863
01/06/2020 00:00:16 - INFO - main - f1 = 0.8475120385232745
查看$SAVE_DIR的文件內(nèi)容:
added_tokens.json
checkpoint-450
checkpoint-400
checkpoint-350
checkpoint-200
checkpoint-300
checkpoint-250
checkpoint-200
checkpoint-150
checkpoint-100
checkpoint-50
pytorch_model.bin
training_args.bin
config.json
special_tokens_map.json
vocab.txt
eval_results.txt
tokenizer_config.json
文件解釋:
pytorch_model.bin代表模型參數(shù),可以使用torch.load加載查看;
traning_args.bin代表模型訓練時的超參,如batch_size,epoch等,仍可使用torch.load查看;
config.json是模型配置文件,如多頭注意力的頭數(shù),編碼器的層數(shù)等,代表典型的模型結(jié)構(gòu),如bert,xlnet,一般不更改;
added_token.json記錄在訓練時通過代碼添加的自定義token對應的數(shù)值,即在代碼中使用add_token方法添加的自定義詞匯;
special_token_map.json當添加的token具有特殊含義時,如分隔符,該文件存儲特殊字符的及其對應的含義,使文本中出現(xiàn)的特殊字符先映射成其含義,之后特殊字符的含義仍然使用add_token方法映射。
checkpoint: 若干步驟保存的模型參數(shù)文件(也叫檢測點文件)。
通過微調(diào)腳本微調(diào)后模型的使用步驟
第一步: 在https://huggingface.co/join上創(chuàng)建一個帳戶
第二步: 在服務器終端使用transformers-cli登陸
第三步: 使用transformers-cli上傳模型并查看
第四步: 使用pytorch.hub加載模型進行使用
第一步: 在https://huggingface.co/join上創(chuàng)建一個帳戶
如果由于網(wǎng)絡(luò)原因無法訪問, 我們已經(jīng)為你提供了默認賬戶
username: ItcastAI
password: ItcastAI
avatar
第二步: 在服務器終端使用transformers-cli登陸
在微調(diào)模型的服務器上登陸
使用剛剛注冊的用戶名和密碼
默認username: ItcastAI
默認password: ItcastAI
$ transformers-cli login
第三步: 使用transformers-cli上傳模型并查看
使用transformers-cli upload命令上傳模型
選擇正確的微調(diào)模型路徑
$ transformers-cli upload ./bert_finetuning_test/
查看上傳結(jié)果
$ transformers-cli ls
Filename LastModified ETag Size
bert_finetuning_test/added_tokens.json 2020-01-05T17:39:57.000Z “99914b932bd37a50b983c5e7c90ae93b” 2
bert_finetuning_test/checkpoint-400/config.json 2020-01-05T17:26:49.000Z “74d53ea41e5acb6d60496bc195d82a42” 684
bert_finetuning_test/checkpoint-400/training_args.bin 2020-01-05T17:26:47.000Z “b3273519c2b2b1cb2349937279880f50” 1207
bert_finetuning_test/checkpoint-450/config.json 2020-01-05T17:15:42.000Z “74d53ea41e5acb6d60496bc195d82a42” 684
bert_finetuning_test/checkpoint-450/pytorch_model.bin 2020-01-05T17:15:58.000Z “077cc0289c90b90d6b662cce104fe4ef” 437982584
bert_finetuning_test/checkpoint-450/training_args.bin 2020-01-05T17:15:40.000Z “b3273519c2b2b1cb2349937279880f50” 1207
bert_finetuning_test/config.json 2020-01-05T17:28:50.000Z “74d53ea41e5acb6d60496bc195d82a42” 684
bert_finetuning_test/eval_results.txt 2020-01-05T17:28:56.000Z “67d2d49a96afc4308d33bfcddda8a7c5” 81
bert_finetuning_test/pytorch_model.bin 2020-01-05T17:28:59.000Z “d46a8ccfb8f5ba9ecee70cef8306679e” 437982584
bert_finetuning_test/special_tokens_map.json 2020-01-05T17:28:54.000Z “8b3fb1023167bb4ab9d70708eb05f6ec” 112
bert_finetuning_test/tokenizer_config.json 2020-01-05T17:28:52.000Z “0d7f03e00ecb582be52818743b50e6af” 59
bert_finetuning_test/training_args.bin 2020-01-05T17:28:48.000Z “b3273519c2b2b1cb2349937279880f50” 1207
bert_finetuning_test/vocab.txt 2020-01-05T17:39:55.000Z “64800d5d8528ce344256daf115d4965e” 231508
第四步: 使用pytorch.hub加載模型進行使用, 更多信息請參考2.4 加載和使用預訓練模型
若之前使用過huggingface的transformers, 請清除~/.cache
import torch
如: ItcastAI/bert_finetuning_test
source = ‘huggingface/pytorch-transformers’
選定加載模型的哪一部分, 這里是模型的映射器
part = ‘tokenizer’
#############################################
加載的預訓練模型的名字
使用自己的模型名字"username/model_name"
如:‘ItcastAI/bert_finetuning_test’
model_name = ‘ItcastAI/bert_finetuning_test’
#############################################
tokenizer = torch.hub.load(‘huggingface/pytorch-transformers’, ‘tokenizer’, model_name)
model = torch.hub.load(‘huggingface/pytorch-transformers’, ‘modelForSequenceClassification’, model_name)
index = tokenizer.encode(“Talk is cheap”, “Please show me your code!”)
102是bert模型中的間隔(結(jié)束)符號的數(shù)值映射
mark = 102
找到第一個102的索引, 即句子對的間隔符號
k = index.index(mark)
句子對分割id列表, 由0,1組成, 0的位置代表第一個句子, 1的位置代表第二個句子
segments_ids = [0](k + 1) + [1](len(index) - k - 1)
轉(zhuǎn)化為tensor
tokens_tensor = torch.tensor([index])
segments_tensors = torch.tensor([segments_ids])
使用評估模式
with torch.no_grad():
# 使用模型預測獲得結(jié)果
result = model(tokens_tensor, token_type_ids=segments_tensors)
# 打印預測結(jié)果以及張量尺寸
print(result)
print(result[0].shape)
輸出效果:
(tensor([[-0.0181, 0.0263]]),)
torch.Size([1, 2])
通過微調(diào)方式進行遷移學習的兩種類型
類型一: 使用指定任務類型的微調(diào)腳本微調(diào)預訓練模型, 后接帶有輸出頭的預定義網(wǎng)絡(luò)輸出結(jié)果.
類型二: 直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網(wǎng)絡(luò)進行微調(diào)輸出結(jié)果.
說明: 所有類型的實戰(zhàn)演示, 都將針對中文文本進行.
類型一實戰(zhàn)演示
使用文本二分類的任務類型SST-2的微調(diào)腳本微調(diào)中文預訓練模型, 后接帶有分類輸出頭的預定義網(wǎng)絡(luò)輸出結(jié)果. 目標是判斷句子的情感傾向.
準備中文酒店評論的情感分析語料, 語料樣式與SST-2數(shù)據(jù)集相同, 標簽0代表差評, 標簽1好評.
語料存放在與glue_data/同級目錄cn_data/下, 其中的SST-2目錄包含train.tsv和dev.tsv
train.tsv
sentence label
早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好,餐廳不分吸煙區(qū).房間不分有無煙房. 0
去的時候 ,酒店大廳和餐廳在裝修,感覺大廳有點擠.由于餐廳裝修本來該享受的早飯,也沒有享受(他們是8點開始每個房間送,但是我時間來不及了)不過前臺服務員態(tài)度好! 1
有很長時間沒有在西藏大廈住了,以前去北京在這里住的較多。這次住進來發(fā)現(xiàn)換了液晶電視,但網(wǎng)絡(luò)不是很好,他們自己說是收費的原因造成的。其它還好。 1
非常好的地理位置,住的是豪華海景房,打開窗戶就可以看見棧橋和海景。記得很早以前也住過,現(xiàn)在重新裝修了。總的來說比較滿意,以后還會住 1
交通很方便,房間小了一點,但是干凈整潔,很有香港的特色,性價比較高,推薦一下哦 1
酒店的裝修比較陳舊,房間的隔音,主要是衛(wèi)生間的隔音非常差,只能算是一般的 0
酒店有點舊,房間比較小,但酒店的位子不錯,就在海邊,可以直接去游泳。8樓的海景打開窗戶就是海。如果想住在熱鬧的地帶,這里不是一個很好的選擇,不過威海城市真的比較小,打車還是相當便宜的。晚上酒店門口出租車比較少。 1
位置很好,走路到文廟、清涼寺5分鐘都用不了,周邊公交車很多很方便,就是出租車不太愛去(老城區(qū)路窄愛堵車),因為是老賓館所以設(shè)施要陳舊些, 1
酒店設(shè)備一般,套房里臥室的不能上網(wǎng),要到客廳去。 0
dev.tsv
sentence label
房間里有電腦,雖然房間的條件略顯簡陋,但環(huán)境、服務還有飯菜都還是很不錯的。如果下次去無錫,我還是會選擇這里的。 1
我們是5月1日通過攜程網(wǎng)入住的,條件是太差了,根本達不到四星級的標準,所有的東西都很陳舊,衛(wèi)生間水龍頭用完竟關(guān)不上,浴缸的漆面都掉了,估計是十年前的四星級吧,總之下次是不會入住了。 0
離火車站很近很方便。住在東樓標間,相比較在九江住的另一家酒店,房間比較大。衛(wèi)生間設(shè)施略舊。服務還好。10元中式早餐也不錯,很豐富,居然還有青菜肉片湯。 1
坐落在香港的老城區(qū),可以體驗香港居民生活,門口交通很方便,如果時間不緊,坐叮當車很好呀!周圍有很多小餐館,早餐就在中遠后面的南北嚼吃的,東西很不錯。我們定的大床房,挺安靜的,總體來說不錯。前臺結(jié)賬沒有銀聯(lián)! 1
酒店前臺服務差,對待客人不熱情。號稱攜程沒有預定。感覺是客人在求他們,我們一定得住。這樣的賓館下次不會入住! 0
價格確實比較高,而且還沒有早餐提供。 1
是一家很實惠的酒店,交通方便,房間也寬敞,晚上沒有電話騷擾,住了兩次,有一次住501房間,洗澡間排水不暢通,也許是個別問題.服務質(zhì)量很好,剛?cè)胱r沒有調(diào)好寬帶,服務員很快就幫忙解決了. 1
位置非常好,就在西街的街口,但是卻鬧中取靜,環(huán)境很清新優(yōu)雅。 1
房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設(shè)備也不錯. 1
在run_glue.py同級目錄下創(chuàng)建run_cn.sh文件, 寫入內(nèi)容如下:
定義DATA_DIR: 微調(diào)數(shù)據(jù)所在路徑
export DATA_DIR="…/…/cn_data"
定義SAVE_DIR: 模型的保存路徑, 我們將模型保存在當前目錄的bert_finetuning文件中
export SAVE_DIR="./bert_cn_finetuning/"
使用python運行微調(diào)腳本
–model_type: 選擇BERT
–model_name_or_path: 選擇bert-base-chinese
–task_name: 句子二分類任務SST-2
–do_train: 使用微調(diào)腳本進行訓練
–do_eval: 使用微調(diào)腳本進行驗證
–data_dir: “./cn_data/SST-2/”, 將自動尋找該路徑下的train.tsv和dev.tsv作為訓練集和驗證集
–max_seq_length: 128,輸入句子的最大長度
–output_dir $SAVE_DIR: “./bert_finetuning/”, 訓練后的模型保存路徑
python run_glue.py
–model_type BERT
–model_name_or_path bert-base-chinese
–task_name SST-2
–do_train
–do_eval
–data_dir $DATA_DIR/SST-2/
–max_seq_length 128
–learning_rate 2e-5
–num_train_epochs 1.0
–output_dir $SAVE_DIR
運行并檢驗效果
使用sh命令運行
sh run_cn.sh
輸出效果:
最終打印模型的驗證結(jié)果, 準確率高達0.88.
01/06/2020 14:22:36 - INFO - main - Saving features into cached file …/…/cn_data/SST-2/cached_dev_bert-base-chinese_128_sst-2
01/06/2020 14:22:36 - INFO - main - ***** Running evaluation *****
01/06/2020 14:22:36 - INFO - main - Num examples = 1000
01/06/2020 14:22:36 - INFO - main - Batch size = 8
Evaluating: 100%|████████████| 125/125 [00:56<00:00, 2.20it/s]
01/06/2020 14:23:33 - INFO - main - ***** Eval results *****
01/06/2020 14:23:33 - INFO - main - acc = 0.88
查看$SAVE_DIR的文件內(nèi)容:
added_tokens.json
checkpoint-350
checkpoint-200
checkpoint-300
checkpoint-250
checkpoint-200
checkpoint-150
checkpoint-100
checkpoint-50
pytorch_model.bin
training_args.bin
config.json
special_tokens_map.json
vocab.txt
eval_results.txt
tokenizer_config.json
使用transformers-cli上傳模型:
默認username: ItcastAI
默認password: ItcastAI
$ transformers-cli login
使用transformers-cli upload命令上傳模型
選擇正確的微調(diào)模型路徑
$ transformers-cli upload ./bert_cn_finetuning/
通過pytorch.hub加載模型進行使用:
import torch
source = ‘huggingface/pytorch-transformers’
模型名字為’ItcastAI/bert_cn_finetuning’
model_name = ‘ItcastAI/bert_cn_finetuning’
tokenizer = torch.hub.load(source, ‘tokenizer’, model_name)
model = torch.hub.load(source, ‘modelForSequenceClassification’, model_name)
def get_label(text):
index = tokenizer.encode(text)
tokens_tensor = torch.tensor([index])
# 使用評估模式
with torch.no_grad():
# 使用模型預測獲得結(jié)果
result = model(tokens_tensor)
predicted_label = torch.argmax(result[0]).item()
return predicted_label
if name == “main”:
# text = “早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好”
text = “房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設(shè)備也不錯.”
print(“輸入文本為:”, text)
print(“預測標簽為:”, get_label(text))
輸出效果:
輸入文本為: 早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好
預測標簽為: 0
輸入文本為: 房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設(shè)備也不錯.
預測標簽為: 1
類型二實戰(zhàn)演示
直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網(wǎng)絡(luò)進行微調(diào)輸出結(jié)果.
使用語料和完成的目標與類型一實戰(zhàn)相同.
直接加載預訓練模型進行輸入文本的特征表示:
import torch
進行句子的截斷補齊(規(guī)范長度)
from keras.preprocessing import sequence
source = ‘huggingface/pytorch-transformers’
直接使用預訓練的bert中文模型
model_name = ‘bert-base-chinese’
通過torch.hub獲得已經(jīng)訓練好的bert-base-chinese模型
model = torch.hub.load(source, ‘model’, model_name)
獲得對應的字符映射器, 它將把中文的每個字映射成一個數(shù)字
tokenizer = torch.hub.load(source, ‘tokenizer’, model_name)
句子規(guī)范長度
cutlen = 32
def get_bert_encode(text):
“”"
description: 使用bert-chinese編碼中文文本
:param text: 要進行編碼的文本
:return: 使用bert編碼后的文本張量表示
“”"
# 首先使用字符映射器對每個漢字進行映射
# 這里需要注意, bert的tokenizer映射后會為結(jié)果前后添加開始和結(jié)束標記即101和102
# 這對于多段文本的編碼是有意義的, 但在我們這里沒有意義, 因此使用[1:-1]對頭和尾進行切片
indexed_tokens = tokenizer.encode(text[:cutlen])[1:-1]
# 對映射后的句子進行截斷補齊
indexed_tokens = sequence.pad_sequences([indexed_tokens], cutlen)
# 之后將列表結(jié)構(gòu)轉(zhuǎn)化為tensor
tokens_tensor = torch.LongTensor(indexed_tokens)
# 使模型不自動計算梯度
with torch.no_grad():
# 調(diào)用模型獲得隱層輸出
encoded_layers, _ = model(tokens_tensor)
# 輸出的隱層是一個三維張量, 最外層一維是1, 我們使用[0]降去它.
encoded_layers = encoded_layers[0]
return encoded_layers
調(diào)用:
if name == “main”:
text = “早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好”
encoded_layers = get_bert_encode(text)
print(encoded_layers)
print(encoded_layers.shape)
輸出效果:
tensor([[-1.2282, 1.0551, -0.7953, …, 2.3363, -0.6413, 0.4174],
[-0.9769, 0.8361, -0.4328, …, 2.1668, -0.5845, 0.4836],
[-0.7990, 0.6181, -0.1424, …, 2.2845, -0.6079, 0.5288],
…,
[ 0.9514, 0.5972, 0.3120, …, 1.8408, -0.1362, -0.1206],
[ 0.1250, 0.1984, 0.0484, …, 1.2302, -0.1905, 0.3205],
[ 0.2651, 0.0228, 0.1534, …, 1.0159, -0.3544, 0.1479]])
torch.Size([32, 768])
自定義單層的全連接網(wǎng)絡(luò)作為微調(diào)網(wǎng)絡(luò):
根據(jù)實際經(jīng)驗, 自定義的微調(diào)網(wǎng)絡(luò)參數(shù)總數(shù)應大于0.5倍的訓練數(shù)據(jù)量, 小于10倍的訓練數(shù)據(jù)量, 這樣有助于模型在合理的時間范圍內(nèi)收斂.
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
“”“定義微調(diào)網(wǎng)絡(luò)的類”""
def init(self, char_size=32, embedding_size=768):
“”"
:param char_size: 輸入句子中的字符數(shù)量, 即輸入句子規(guī)范后的長度128.
:param embedding_size: 字嵌入的維度, 因為使用的bert中文模型嵌入維度是768, 因此embedding_size為768
“”"
super(Net, self).init()
# 將char_size和embedding_size傳入其中
self.char_size = char_size
self.embedding_size = embedding_size
# 實例化一個全連接層
self.fc1 = nn.Linear(char_size*embedding_size, 2)
調(diào)用:
if name == “main”:
# 隨機初始化一個輸入?yún)?shù)
x = torch.randn(1, 32, 768)
# 實例化網(wǎng)絡(luò)結(jié)構(gòu), 所有參數(shù)使用默認值
net = Net()
nr = net(x)
print(nr)
輸出效果:
tensor([[0.3279, 0.2519]], grad_fn=)
構(gòu)建訓練與驗證數(shù)據(jù)批次生成器:
import pandas as pd
from collections import Counter
from functools import reduce
from sklearn.utils import shuffle
def data_loader(train_data_path, valid_data_path, batch_size):
“”"
description: 從持久化文件中加載數(shù)據(jù)
:param train_data_path: 訓練數(shù)據(jù)路徑
:param valid_data_path: 驗證數(shù)據(jù)路徑
:param batch_size: 訓練和驗證數(shù)據(jù)集的批次大小
:return: 訓練數(shù)據(jù)生成器, 驗證數(shù)據(jù)生成器, 訓練數(shù)據(jù)數(shù)量, 驗證數(shù)據(jù)數(shù)量
“”"
# 使用pd進行csv數(shù)據(jù)的讀取, 并去除第一行的列名
train_data = pd.read_csv(train_data_path, header=None, sep="\t").drop([0])
valid_data = pd.read_csv(valid_data_path, header=None, sep="\t").drop([0])
調(diào)用:
if name == “main”:
train_data_path = “./cn_data/SST-2/train.tsv”
valid_data_path = “./cn_data/SST-2/dev.tsv”
batch_size = 16
train_data_labels, valid_data_labels,
train_data_len, valid_data_len = data_loader(train_data_path, valid_data_path, batch_size)
print(next(train_data_labels))
print(next(valid_data_labels))
print(“train_data_len:”, train_data_len)
print(“valid_data_len:”, valid_data_len)
輸出效果:
訓練數(shù)據(jù)集的正負樣本數(shù)量:
{‘0’: 1518, ‘1’: 1442}
驗證數(shù)據(jù)集的正負樣本數(shù)量:
{‘1’: 518, ‘0’: 482}
(tensor([[[-0.8328, 0.9376, -1.2489, …, 1.8594, -0.4636, -0.1682],
[-0.9798, 0.5113, -0.9868, …, 1.5500, -0.1934, 0.2521],
[-0.7574, 0.3086, -0.6031, …, 1.8467, -0.2507, 0.3916],
…,
[ 0.0064, 0.2321, 0.3785, …, 0.3376, 0.4748, -0.1272],
[-0.3175, 0.4018, -0.0377, …, 0.6030, 0.2916, -0.4172],
[-0.6154, 1.0439, 0.2921, …, 0.5048, -0.0983, 0.0061]]]), tensor([0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
1, 0, 1, 1, 1, 1, 0, 0]))
(tensor([[[-0.1611, 0.9182, -0.3419, …, 0.6323, -0.2013, 0.0184],
[-0.1224, 0.7706, -0.2386, …, 0.7925, 0.0444, 0.2160],
[-0.0301, 0.6867, -0.1510, …, 0.9140, 0.0308, 0.2611],
…,
[ 0.3662, -0.4925, 1.2332, …, 0.7741, -0.1007, -0.3099],
[-0.0932, -0.8494, 0.6586, …, 0.1235, -0.3152, -0.1635],
[ 0.5306, -0.5510, 0.3105, …, 1.2631, -0.5882, -0.1133]]]), tensor([1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1, 0, 0, 1, 1, 1, 0, 0]))
train_data_len: 2960
valid_data_len: 1000
編寫訓練和驗證函數(shù):
import torch.optim as optim
def train(train_data_labels):
“”"
description: 訓練函數(shù), 在這個過程中將更新模型參數(shù), 并收集準確率和損失
:param train_data_labels: 訓練數(shù)據(jù)和標簽的生成器對象
:return: 整個訓練過程的平均損失之和以及正確標簽的累加數(shù)
“”"
# 定義訓練過程的初始損失和準確率累加數(shù)
train_running_loss = 0.0
train_running_acc = 0.0
# 循環(huán)遍歷訓練數(shù)據(jù)和標簽生成器, 每個批次更新一次模型參數(shù)
for train_tensor, train_labels in train_data_labels:
# 初始化該批次的優(yōu)化器
optimizer.zero_grad()
# 使用微調(diào)網(wǎng)絡(luò)獲得輸出
train_outputs = net(train_tensor)
# 得到該批次下的平均損失
train_loss = criterion(train_outputs, train_labels)
# 將該批次的平均損失加到train_running_loss中
train_running_loss += train_loss.item()
# 損失反向傳播
train_loss.backward()
# 優(yōu)化器更新模型參數(shù)
optimizer.step()
# 將該批次中正確的標簽數(shù)量進行累加, 以便之后計算準確率
train_running_acc += (train_outputs.argmax(1) == train_labels).sum().item()
return train_running_loss, train_running_acc
def valid(valid_data_labels):
“”"
description: 驗證函數(shù), 在這個過程中將驗證模型的在新數(shù)據(jù)集上的標簽, 收集損失和準確率
:param valid_data_labels: 驗證數(shù)據(jù)和標簽的生成器對象
:return: 整個驗證過程的平均損失之和以及正確標簽的累加數(shù)
“”"
# 定義訓練過程的初始損失和準確率累加數(shù)
valid_running_loss = 0.0
valid_running_acc = 0.0
# 循環(huán)遍歷驗證數(shù)據(jù)和標簽生成器
for valid_tensor, valid_labels in valid_data_labels:
# 不自動更新梯度
with torch.no_grad():
# 使用微調(diào)網(wǎng)絡(luò)獲得輸出
valid_outputs = net(valid_tensor)
# 得到該批次下的平均損失
valid_loss = criterion(valid_outputs, valid_labels)
# 將該批次的平均損失加到valid_running_loss中
valid_running_loss += valid_loss.item()
# 將該批次中正確的標簽數(shù)量進行累加, 以便之后計算準確率
valid_running_acc += (valid_outputs.argmax(1) == valid_labels).sum().item()
return valid_running_loss, valid_running_acc
調(diào)用并保存模型:
if name == “main”:
# 設(shè)定數(shù)據(jù)路徑
train_data_path = “./cn_data/SST-2/train.tsv”
valid_data_path = “./cn_data/SST-2/dev.tsv”
# 定義交叉熵損失函數(shù)
criterion = nn.CrossEntropyLoss()
# 定義SGD優(yōu)化方法
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
# 定義訓練輪數(shù)
epochs = 4
# 定義批次樣本數(shù)量
batch_size = 16
# 進行指定輪次的訓練
for epoch in range(epochs):
# 打印輪次
print(“Epoch:”, epoch + 1)
# 通過數(shù)據(jù)加載器獲得訓練數(shù)據(jù)和驗證數(shù)據(jù)生成器, 以及對應的樣本數(shù)量
train_data_labels, valid_data_labels, train_data_len,
valid_data_len = data_loader(train_data_path, valid_data_path, batch_size)
# 調(diào)用訓練函數(shù)進行訓練
train_running_loss, train_running_acc = train(train_data_labels)
# 調(diào)用驗證函數(shù)進行驗證
valid_running_loss, valid_running_acc = valid(valid_data_labels)
# 計算每一輪的平均損失, train_running_loss和valid_running_loss是每個批次的平均損失之和
# 因此將它們乘以batch_size就得到了該輪的總損失, 除以樣本數(shù)即該輪次的平均損失
train_average_loss = train_running_loss * batch_size / train_data_len
valid_average_loss = valid_running_loss * batch_size / valid_data_len
輸出效果:
Epoch: 1
Train Loss: 2.144986984236597 | Train Acc: 0.7347972972972973
Valid Loss: 2.1898122818128902 | Valid Acc: 0.704
Epoch: 2
Train Loss: 1.3592962406135032 | Train Acc: 0.8435810810810811
Valid Loss: 1.8816152956699324 | Valid Acc: 0.784
Epoch: 3
Train Loss: 1.5507876996199943 | Train Acc: 0.8439189189189189
Valid Loss: 1.8626576719331536 | Valid Acc: 0.795
Epoch: 4
Train Loss: 0.7825378059198299 | Train Acc: 0.9081081081081082
Valid Loss: 2.121698483480899 | Valid Acc: 0.803
Finished Training
Finished Saving
加載模型進行使用:
if name == “main”:
MODEL_PATH = ‘./BERT_net.pth’
# 加載模型參數(shù)
net.load_state_dict(torch.load(MODEL_PATH))
輸出效果:
輸入文本為: 房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設(shè)備也不錯.
預測標簽為: 1
輸入文本為: 酒店設(shè)備一般,套房里臥室的不能上網(wǎng),要到客廳去。
預測標簽為: 0
小節(jié)總結(jié)
學習了指定任務類型的微調(diào)腳本:
huggingface研究機構(gòu)向我們提供了針對GLUE數(shù)據(jù)集合任務類型的微調(diào)腳本, 這些微調(diào)腳本的核心都是微調(diào)模型的最后一個全連接層.
通過簡單的參數(shù)配置來指定GLUE中存在任務類型(如: CoLA對應文本二分類, MRPC對應句子對文本二分類, STS-B對應句子對文本多分類), 以及指定需要微調(diào)的預訓練模型.
學習了指定任務類型的微調(diào)腳本使用步驟:
第一步: 下載微調(diào)腳本文件
第二步: 配置微調(diào)腳本參數(shù)
第三步: 運行并檢驗效果
學習了通過微調(diào)腳本微調(diào)后模型的使用步驟:
第一步: 在https://huggingface.co/join上創(chuàng)建一個帳戶
第二步: 在服務器終端使用transformers-cli登陸
第三步: 使用transformers-cli上傳模型并查看
第四步: 使用pytorch.hub加載模型進行使用
學習了通過微調(diào)方式進行遷移學習的兩種類型:
類型一: 使用指定任務類型的微調(diào)腳本微調(diào)預訓練模型, 后接帶有輸出頭的預定義網(wǎng)絡(luò)輸出結(jié)果.
類型二: 直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網(wǎng)絡(luò)進行微調(diào)輸出結(jié)果.
學習了類型一實戰(zhàn)演示:
使用文本二分類的任務類型SST-2的微調(diào)腳本微調(diào)中文預訓練模型, 后接帶有分類輸出頭的預定義網(wǎng)絡(luò)輸出結(jié)果. 目標是判斷句子的情感傾向.
準備中文酒店評論的情感分析語料, 語料樣式與SST-2數(shù)據(jù)集相同, 標簽0代表差評, 標簽1好評.
語料存放在與glue_data/同級目錄cn_data/下, 其中的SST-2目錄包含train.tsv和dev.tsv
學習了類型二實戰(zhàn)演示:
直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網(wǎng)絡(luò)進行微調(diào)輸出結(jié)果.
上一頁第一章:fasttext工具的使用
?Copyright 2019, itcast.cn.
Made with Material for MkDocs
總結(jié)
以上是生活随笔為你收集整理的11111111111111111111的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lubuntu安装屏幕键盘onboard
- 下一篇: 利用MATLAB对乐曲进行钢琴演奏【ma