11111111111111111111
111111111111111111111111111111111111111111111111111111
跳轉至
logo
Transformer
第二章:Transformer架構解析
logo
Transformer
第一章:Transformer背景介紹
第二章:Transformer架構解析
目錄
2.1 認識Transformer架構
學習目標
Transformer模型的作用
Transformer總體架構圖
小節總結
2.2 輸入部分實現
學習目標
文本嵌入層的作用
位置編碼器的作用
小節總結
2.3 編碼器部分實現
學習目標
2.3.1 掩碼張量
2.3.2 注意力機制
2.3.3 多頭注意力機制
2.3.4 前饋全連接層
2.3.5 規范化層
2.3.6 子層連接結構
2.3.7 編碼器層
2.3.8 編碼器
2.4 解碼器部分實現
學習目標
2.4.1 解碼器層
2.4.2 解碼器
2.5 輸出部分實現
學習目標
線性層的作用
softmax層的作用
小節總結
2.6 模型構建
學習目標
編碼器-解碼器結構的代碼實現
Tansformer模型構建過程的代碼分析
小節總結
第二章:Transformer架構解析
2.1 認識Transformer架構
學習目標
了解Transformer模型的作用.
了解Transformer總體架構圖中各個組成部分的名稱.
Transformer模型的作用
基于seq2seq架構的transformer模型可以完成NLP領域研究的典型任務, 如機器翻譯, 文本生成等. 同時又可以構建預訓練語言模型,用于不同任務的遷移學習.
聲明:
在接下來的架構分析中, 我們將假設使用Transformer模型架構處理從一種語言文本到另一種語言文本的翻譯工作, 因此很多命名方式遵循NLP中的規則. 比如: Embeddding層將稱作文本嵌入層, Embedding層產生的張量稱為詞嵌入張量, 它的最后一維將稱作詞向量等.
Transformer總體架構圖
avatar
Transformer總體架構可分為四個部分:
輸入部分
輸出部分
編碼器部分
解碼器部分
輸入部分包含:
源文本嵌入層及其位置編碼器
目標文本嵌入層及其位置編碼器
avatar
輸出部分包含:
線性層
softmax層
avatar
編碼器部分:
由N個編碼器層堆疊而成
每個編碼器層由兩個子層連接結構組成
第一個子層連接結構包括一個多頭自注意力子層和規范化層以及一個殘差連接
第二個子層連接結構包括一個前饋全連接子層和規范化層以及一個殘差連接
avatar
解碼器部分:
由N個解碼器層堆疊而成
每個解碼器層由三個子層連接結構組成
第一個子層連接結構包括一個多頭自注意力子層和規范化層以及一個殘差連接
第二個子層連接結構包括一個多頭注意力子層和規范化層以及一個殘差連接
第三個子層連接結構包括一個前饋全連接子層和規范化層以及一個殘差連接
avatar
小節總結
學習了Transformer模型的作用:
基于seq2seq架構的transformer模型可以完成NLP領域研究的典型任務, 如機器翻譯, 文本生成等. 同時又可以構建預訓練語言模型,用于不同任務的遷移學習.
Transformer總體架構可分為四個部分:
輸入部分
輸出部分
編碼器部分
解碼器部分
輸入部分包含:
源文本嵌入層及其位置編碼器
目標文本嵌入層及其位置編碼器
輸出部分包含:
線性層
softmax處理器
編碼器部分:
由N個編碼器層堆疊而成
每個編碼器層由兩個子層連接結構組成
第一個子層連接結構包括一個多頭自注意力子層和規范化層以及一個殘差連接
第二個子層連接結構包括一個前饋全連接子層和規范化層以及一個殘差連接
解碼器部分:
由N個解碼器層堆疊而成
每個解碼器層由三個子層連接結構組成
第一個子層連接結構包括一個多頭自注意力子層和規范化層以及一個殘差連接
第二個子層連接結構包括一個多頭注意力子層和規范化層以及一個殘差連接
第三個子層連接結構包括一個前饋全連接子層和規范化層以及一個殘差連接
2.2 輸入部分實現
學習目標
了解文本嵌入層和位置編碼的作用.
掌握文本嵌入層和位置編碼的實現過程.
輸入部分包含:
源文本嵌入層及其位置編碼器
目標文本嵌入層及其位置編碼器
avatar
文本嵌入層的作用
無論是源文本嵌入還是目標文本嵌入,都是為了將文本中詞匯的數字表示轉變為向量表示, 希望在這樣的高維空間捕捉詞匯間的關系.
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系統安裝, python版本<=3.6
pip install torch==0.3.0.post4 numpy matplotlib seaborn
文本嵌入層的代碼分析:
導入必備的工具包
import torch
預定義的網絡層torch.nn, 工具開發者已經幫助我們開發好的一些常用層,
比如,卷積層, lstm層, embedding層等, 不需要我們再重新造輪子.
import torch.nn as nn
數學計算工具包
import math
torch中變量封裝函數Variable.
from torch.autograd import Variable
定義Embeddings類來實現文本嵌入層,這里s說明代表兩個一模一樣的嵌入層, 他們共享參數.
該類繼承nn.Module, 這樣就有標準層的一些功能, 這里我們也可以理解為一種模式, 我們自己實現的所有層都會這樣去寫.
class Embeddings(nn.Module):
def init(self, d_model, vocab):
“”“類的初始化函數, 有兩個參數, d_model: 指詞嵌入的維度, vocab: 指詞表的大小.”""
# 接著就是使用super的方式指明繼承nn.Module的初始化函數, 我們自己實現的所有層都會這樣去寫.
super(Embeddings, self).init()
# 之后就是調用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]]])
實例化參數:
詞嵌入維度是512維
d_model = 512
詞表大小是1000
vocab = 1000
輸入參數:
輸入x是一個使用Variable封裝的長整型張量, 形狀是2 x 4
x = Variable(torch.LongTensor([[100,2,421,508],[491,998,1,221]]))
調用:
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的編碼器結構中, 并沒有針對詞匯位置信息的處理,因此需要在Embedding層后加入位置編碼器,將詞匯位置不同可能會產生不同語義的信息加入到詞嵌入張量中, 以彌補位置信息的缺失.
位置編碼器的代碼分析:
定義位置編碼器類, 我們同樣把它看做一個層, 因此會繼承nn.Module
class PositionalEncoding(nn.Module):
def init(self, d_model, dropout, max_len=5000):
“”“位置編碼器類的初始化函數, 共有三個參數, 分別是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]])
實例化參數:
詞嵌入維度是512維
d_model = 512
置0比率為0.1
dropout = 0.1
句子最大長度
max_len=60
輸入參數:
輸入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]
調用:
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
創建一張15 x 5大小的畫布
plt.figure(figsize=(15, 5))
實例化PositionalEncoding類得到pe對象, 輸入參數是20和0
pe = PositionalEncoding(20, 0)
然后向pe傳入被Variable封裝的tensor, 這樣pe會直接執行forward函數,
且這個tensor里的數值都是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
效果分析:
每條顏色的曲線代表某一個詞匯中的特征在不同位置的含義.
保證同一詞匯隨著所在位置不同它對應位置嵌入向量會發生變化.
正弦波和余弦波的值域范圍都是1到-1這又很好的控制了嵌入數值的大小, 有助于梯度的快速計算.
小節總結
學習了文本嵌入層的作用:
無論是源文本嵌入還是目標文本嵌入,都是為了將文本中詞匯的數字表示轉變為向量表示, 希望在這樣的高維空間捕捉詞匯間的關系.
學習并實現了文本嵌入層的類: Embeddings
初始化函數以d_model, 詞嵌入維度, 和vocab, 詞匯總數為參數, 內部主要使用了nn中的預定層Embedding進行詞嵌入.
在forward函數中, 將輸入x傳入到Embedding的實例化對象中, 然后乘以一個根號下d_model進行縮放, 控制數值大小.
它的輸出是文本嵌入后的結果.
學習了位置編碼器的作用:
因為在Transformer的編碼器結構中, 并沒有針對詞匯位置信息的處理,因此需要在Embedding層后加入位置編碼器,將詞匯位置不同可能會產生不同語義的信息加入到詞嵌入張量中, 以彌補位置信息的缺失.
學習并實現了位置編碼器的類: PositionalEncoding
初始化函數以d_model, dropout, max_len為參數, 分別代表d_model: 詞嵌入維度, dropout: 置0比率, max_len: 每個句子的最大長度.
forward函數中的輸入參數為x, 是Embedding層的輸出.
最終輸出一個加入了位置編碼信息的詞嵌入張量.
實現了繪制詞匯向量中特征的分布曲線:
保證同一詞匯隨著所在位置不同它對應位置嵌入向量會發生變化.
正弦波和余弦波的值域范圍都是1到-1, 這又很好的控制了嵌入數值的大小, 有助于梯度的快速計算.
2.3 編碼器部分實現
學習目標
了解編碼器中各個組成部分的作用.
掌握編碼器中各個組成部分的實現過程.
編碼器部分:
由N個編碼器層堆疊而成
每個編碼器層由兩個子層連接結構組成
第一個子層連接結構包括一個多頭自注意力子層和規范化層以及一個殘差連接
第二個子層連接結構包括一個前饋全連接子層和規范化層以及一個殘差連接
avatar
2.3.1 掩碼張量
學習目標:
了解什么是掩碼張量以及它的作用.
掌握生成掩碼張量的實現過程.
什么是掩碼張量:
掩代表遮掩,碼就是我們張量中的數值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩還是1位置被遮掩可以自定義,因此它的作用就是讓另外一個張量中的一些數值被遮掩,也可以說被替換, 它的表現形式是一個張量.
掩碼張量的作用:
在transformer中, 掩碼張量的主要作用在應用attention(將在下一小節講解)時,有一些生成的attention張量中的值計算有可能已知了未來信息而得到的,未來信息被看到是因為訓練時會把整個輸出結果都一次性進行Embedding,但是理論上解碼器的的輸出卻不是一次就能產生最終結果的,而是一次次通過上一次結果綜合得出的,因此,未來的信息可能被提前利用. 所以,我們會進行遮掩. 關于解碼器的有關知識將在后面的章節中講解.
生成掩碼張量的代碼分析:
def subsequent_mask(size):
“”“生成向后遮掩的掩碼張量, 參數size是掩碼張量最后兩個維度的大小, 它的最后兩維形成一個方陣”""
# 在函數中, 首先定義掩碼張量的形狀
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
調用:
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的位置一眼望過去還是黃色, 說明第一次詞還沒有產生, 從第二個位置看過去, 就能看到位置1的詞, 其他位置看不到, 以此類推.
2.3.1 掩碼張量總結:
學習了什么是掩碼張量:
掩代表遮掩,碼就是我們張量中的數值,它的尺寸不定,里面一般只有1和0的元素,代表位置被遮掩或者不被遮掩,至于是0位置被遮掩還是1位置被遮掩可以自定義,因此它的作用就是讓另外一個張量中的一些數值被遮掩, 也可以說被替換, 它的表現形式是一個張量.
學習了掩碼張量的作用:
在transformer中, 掩碼張量的主要作用在應用attention(將在下一小節講解)時,有一些生成的attetion張量中的值計算有可能已知量未來信息而得到的,未來信息被看到是因為訓練時會把整個輸出結果都一次性進行Embedding,但是理論上解碼器的的輸出卻不是一次就能產生最終結果的,而是一次次通過上一次結果綜合得出的,因此,未來的信息可能被提前利用. 所以,我們會進行遮掩. 關于解碼器的有關知識將在后面的章節中講解.
學習并實現了生成向后遮掩的掩碼張量函數: subsequent_mask
它的輸入是size, 代表掩碼張量的大小.
它的輸出是一個最后兩維形成1方陣的下三角陣.
最后對生成的掩碼張量進行了可視化分析, 更深一步理解了它的用途.
2.3.2 注意力機制
學習目標:
了解什么是注意力計算規則和注意力機制.
掌握注意力計算規則的實現過程.
什么是注意力:
我們觀察事物時,之所以能夠快速判斷一種事物(當然允許判斷是錯誤的), 是因為我們大腦能夠很快把注意力放在事物最具有辨識度的部分從而作出判斷,而并非是從頭到尾的觀察一遍事物后,才能有判斷結果. 正是基于這樣的理論,就產生了注意力機制.
什么是注意力計算規則:
它需要三個指定的輸入Q(query), K(key), V(value), 然后通過公式得到注意力的計算結果, 這個結果代表query在key和value作用下的表示. 而這個具體的計算規則有很多種, 我這里只介紹我們用到的這一種.
我們這里使用的注意力的計算規則:
avatar
Q, K, V的比喻解釋:
假如我們有一個問題: 給出一段文本,使用一些關鍵詞對它進行描述!
為了方便統一正確答案,這道題可能預先已經給大家寫出了一些關鍵詞作為提示.其中這些給出的提示就可以看作是key,
而整個的文本信息就相當于是query,value的含義則更抽象,可以比作是你看到這段文本信息后,腦子里浮現的答案信息,
這里我們又假設大家最開始都不是很聰明,第一次看到這段文本后腦子里基本上浮現的信息就只有提示這些信息,
因此key與value基本是相同的,但是隨著我們對這個問題的深入理解,通過我們的思考腦子里想起來的東西原來越多,
并且能夠開始對我們query也就是這段文本,提取關鍵信息進行表示. 這就是注意力作用的過程, 通過這個過程,
我們最終腦子里的value發生了變化,
根據提示key生成了query的關鍵詞表示方法,也就是另外一種特征表示方法.
剛剛我們說到key和value一般情況下默認是相同,與query是不同的,這種是我們一般的注意力輸入形式,
但有一種特殊情況,就是我們query與key和value相同,這種情況我們稱為自注意力機制,就如同我們的剛剛的例子,
使用一般注意力機制,是使用不同于給定文本的關鍵詞表示它. 而自注意力機制,
需要用給定文本自身來表達自己,也就是說你需要從給定文本中抽取關鍵詞來表述它, 相當于對文本自身的一次特征提取.
什么是注意力機制:
注意力機制是注意力計算規則能夠應用的深度學習網絡的載體, 除了注意力計算規則外, 還包括一些必要的全連接層以及相關張量處理, 使其與應用網絡融為一體. 使用自注意力計算規則的注意力機制稱為自注意力機制.
注意力機制在網絡中實現的圖形表示:
avatar
注意力計算規則的代碼分析:
def attention(query, key, value, mask=None, dropout=None):
“”“注意力機制的實現, 輸入分別是query, key, value, mask: 掩碼張量,
dropout是nn.Dropout層的實例化對象, 默認為None”""
# 在函數中, 首先取query的最后一維的大小, 一般情況下就等同于我們的詞嵌入維度, 命名為d_k
d_k = query.size(-1)
# 按照注意力公式, 將query與key的轉置相乘, 這里面key是將最后兩個維度進行轉置, 再除以縮放系數根號下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]
輸入參數:
我們令輸入的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]
調用:
attn, p_attn = attention(query, key, value)
print(“attn:”, attn)
print(“p_attn:”, p_attn)
輸出效果:
將得到兩個結果
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的輸入參數:
query = key = value = pe_result
令mask為一個2x4x4的零張量
mask = Variable(torch.zeros(2, 4, 4))
調用:
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 注意力機制總結:
學習了什么是注意力:
我們觀察事物時,之所以能夠快速判斷一種事物(當然允許判斷是錯誤的), 是因為我們大腦能夠很快把注意力放在事物最具有辨識度的部分從而作出判斷,而并非是從頭到尾的觀察一遍事物后,才能有判斷結果. 正是基于這樣的理論,就產生了注意力機制.
什么是注意力計算規則:
它需要三個指定的輸入Q(query), K(key), V(value), 然后通過公式得到注意力的計算結果, 這個結果代表query在key和value作用下的表示. 而這個具體的計算規則有很多種, 我這里只介紹我們用到的這一種.
學習了Q, K, V的比喻解釋:
Q是一段準備被概括的文本; K是給出的提示; V是大腦中的對提示K的延伸.
當Q=K=V時, 稱作自注意力機制.
什么是注意力機制:
注意力機制是注意力計算規則能夠應用的深度學習網絡的載體, 除了注意力計算規則外, 還包括一些必要的全連接層以及相關張量處理, 使其與應用網絡融為一體. 使用自注意力計算規則的注意力機制稱為自注意力機制.
學習并實現了注意力計算規則的函數: attention
它的輸入就是Q,K,V以及mask和dropout, mask用于掩碼, dropout用于隨機置0.
它的輸出有兩個, query的注意力表示以及注意力張量.
2.3.3 多頭注意力機制
學習目標:
了解多頭注意力機制的作用.
掌握多頭注意力機制的實現過程.
什么是多頭注意力機制:
從多頭注意力的結構圖中,貌似這個所謂的多個頭就是指多組線性變換層,其實并不是,我只有使用了一組線性變化層,即三個變換張量對Q,K,V分別進行線性變換,這些變換不會改變原有張量的尺寸,因此每個變換矩陣都是方陣,得到輸出結果后,多頭的作用才開始顯現,每個頭開始從詞義層面分割輸出的張量,也就是每個頭都想獲得一組Q,K,V進行注意力機制的計算,但是句子中的每個詞的表示只獲得一部分,也就是只分割了最后一維的詞嵌入向量. 這就是所謂的多頭,將每個頭的獲得的輸入送到注意力機制中, 就形成多頭注意力機制.
多頭注意力機制結構圖:
avatar
多頭注意力機制的作用:
這種結構設計能讓每個注意力機制去優化每個詞匯的不同特征部分,從而均衡同一種注意力機制可能產生的偏差,讓詞義擁有來自更多元的表達,實驗表明可以從而提升模型效果.
多頭注意力機制的代碼實現:
用于深度拷貝的copy工具包
import copy
首先需要定義克隆函數, 因為在多頭注意力機制的實現中, 用到多個結構相同的線性層.
我們將使用clone函數將他們一同初始化在一個網絡層列表對象中. 之后的結構中也會用到該函數.
def clones(module, N):
“”“用于生成相同網絡層的克隆函數, 它的參數module表示要克隆的目標網絡層, N代表需要克隆的數量”""
# 在函數中, 我們通過for循環對module進行N次深度拷貝, 使其每個module成為獨立的層,
# 然后將其放在nn.ModuleList類型的列表中存放.
return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])
我們使用一個類來實現多頭注意力機制的處理
class MultiHeadedAttention(nn.Module):
def init(self, head, embedding_dim, dropout=0.1):
“”“在類的初始化時, 會傳入三個參數,head代表頭數,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]])
實例化參數:
頭數head
head = 8
詞嵌入維度embedding_dim
embedding_dim = 512
置零比率dropout
dropout = 0.2
輸入參數:
假設輸入的Q,K,V仍然相等
query = value = key = pe_result
輸入的掩碼張量mask
mask = Variable(torch.zeros(8, 4, 4))
調用:
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 多頭注意力機制總結:
學習了什么是多頭注意力機制:
每個頭開始從詞義層面分割輸出的張量,也就是每個頭都想獲得一組Q,K,V進行注意力機制的計算,但是句子中的每個詞的表示只獲得一部分,也就是只分割了最后一維的詞嵌入向量. 這就是所謂的多頭.將每個頭的獲得的輸入送到注意力機制中, 就形成了多頭注意力機制.
學習了多頭注意力機制的作用:
這種結構設計能讓每個注意力機制去優化每個詞匯的不同特征部分,從而均衡同一種注意力機制可能產生的偏差,讓詞義擁有來自更多元的表達,實驗表明可以從而提升模型效果.
學習并實現了多頭注意力機制的類: MultiHeadedAttention
因為多頭注意力機制中需要使用多個相同的線性層, 首先實現了克隆函數clones.
clones函數的輸入是module,N,分別代表克隆的目標層,和克隆個數.
clones函數的輸出是裝有N個克隆層的Module列表.
接著實現MultiHeadedAttention類, 它的初始化函數輸入是h, d_model, dropout分別代表頭數,詞嵌入維度和置零比率.
它的實例化對象輸入是Q, K, V以及掩碼張量mask.
它的實例化對象輸出是通過多頭注意力機制處理的Q的注意力表示.
2.3.4 前饋全連接層
學習目標:
了解什么是前饋全連接層及其它的作用.
掌握前饋全連接層的實現過程.
什么是前饋全連接層:
在Transformer中前饋全連接層就是具有兩層線性層的全連接網絡.
前饋全連接層的作用:
考慮注意力機制可能對復雜過程的擬合程度不夠, 通過增加兩層網絡來增強模型的能力.
前饋全連接層的代碼分析:
通過類PositionwiseFeedForward來實現前饋全連接層
class PositionwiseFeedForward(nn.Module):
def init(self, d_model, d_ff, dropout=0.1):
“”“初始化函數有三個輸入參數分別是d_model, d_ff,和dropout=0.1,第一個是線性層的輸入維度也是第二個線性層的輸出維度,
因為我們希望輸入通過前饋全連接層后輸入和輸出的維度不變. 第二個參數d_ff就是第二個線性層的輸入維度和第一個線性層的輸出維度.
最后一個是dropout置0比率.”""
super(PositionwiseFeedForward, self).init()
ReLU函數公式: ReLU(x)=max(0, x)
ReLU函數圖像:
avatar
實例化參數:
d_model = 512
線性變化的維度
d_ff = 64
dropout = 0.2
輸入參數:
輸入參數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])
調用:
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 前饋全連接層總結:
學習了什么是前饋全連接層:
在Transformer中前饋全連接層就是具有兩層線性層的全連接網絡.
學習了前饋全連接層的作用:
考慮注意力機制可能對復雜過程的擬合程度不夠, 通過增加兩層網絡來增強模型的能力.
學習并實現了前饋全連接層的類: PositionwiseFeedForward
它的實例化參數為d_model, d_ff, dropout, 分別代表詞嵌入維度, 線性變換維度, 和置零比率.
它的輸入參數x, 表示上層的輸出.
它的輸出是經過2層線性網絡變換的特征表示.
2.3.5 規范化層
學習目標:
了解規范化層的作用.
掌握規范化層的實現過程.
規范化層的作用:
它是所有深層網絡模型都需要的標準網絡層,因為隨著網絡層數的增加,通過多層的計算后參數可能開始出現過大或過小的情況,這樣可能會導致學習過程出現異常,模型可能收斂非常的慢. 因此都會在一定層數后接規范化層進行數值的規范化,使其特征數值在合理范圍內.
規范化層的代碼實現:
通過LayerNorm實現規范化層的類
class LayerNorm(nn.Module):
def init(self, features, eps=1e-6):
“”“初始化函數有兩個參數, 一個是features, 表示詞嵌入的維度,
另一個是eps它是一個足夠小的數, 在規范化公式的分母中出現,
防止分母為0.默認是1e-6.”""
super(LayerNorm, self).init()
實例化參數:
features = d_model = 512
eps = 1e-6
輸入參數:
輸入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])
調用:
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 規范化層總結:
學習了規范化層的作用:
它是所有深層網絡模型都需要的標準網絡層,因為隨著網絡層數的增加,通過多層的計算后參數可能開始出現過大或過小的情況,這樣可能會導致學習過程出現異常,模型可能收斂非常的慢. 因此都會在一定層數后接規范化層進行數值的規范化,使其特征數值在合理范圍內.
學習并實現了規范化層的類: LayerNorm
它的實例化參數有兩個, features和eps,分別表示詞嵌入特征大小,和一個足夠小的數.
它的輸入參數x代表來自上一層的輸出.
它的輸出就是經過規范化的特征表示.
2.3.6 子層連接結構
學習目標:
了解什么是子層連接結構.
掌握子層連接結構的實現過程.
什么是子層連接結構:
如圖所示,輸入到每個子層以及規范化層的過程中,還使用了殘差鏈接(跳躍連接),因此我們把這一部分結構整體叫做子層連接(代表子層及其鏈接結構),在每個編碼器層中,都有兩個子層,這兩個子層加上周圍的鏈接結構就形成了兩個子層連接結構.
子層連接結構圖:
avatar
avatar
子層連接結構的代碼分析:
使用SublayerConnection來實現子層連接結構的類
class SublayerConnection(nn.Module):
def init(self, size, dropout=0.1):
“”“它輸入參數有兩個, size以及dropout, size一般是都是詞嵌入維度的大小,
dropout本身是對模型結構中的節點數進行隨機抑制的比率,
又因為節點被抑制等效就是該節點的輸出都是0,因此也可以把dropout看作是對輸出矩陣的隨機置0的比率.
“””
super(SublayerConnection, self).init()
# 實例化了規范化對象self.norm
self.norm = LayerNorm(size)
# 又使用nn中預定義的droupout實例化一個self.dropout對象.
self.dropout = nn.Dropout(p=dropout)
實例化參數
size = 512
dropout = 0.2
head = 8
d_model = 512
輸入參數:
令x為位置編碼器的輸出
x = pe_result
mask = Variable(torch.zeros(8, 4, 4))
假設子層中裝的是多頭注意力層, 實例化這個類
self_attn = MultiHeadedAttention(head, d_model)
使用lambda獲得一個函數類型的子層
sublayer = lambda x: self_attn(x, x, x, mask)
調用:
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 子層連接結構總結:
什么是子層連接結構:
如圖所示,輸入到每個子層以及規范化層的過程中,還使用了殘差鏈接(跳躍連接),因此我們把這一部分結構整體叫做子層連接(代表子層及其鏈接結構), 在每個編碼器層中,都有兩個子層,這兩個子層加上周圍的鏈接結構就形成了兩個子層連接結構.
學習并實現了子層連接結構的類: SublayerConnection
類的初始化函數輸入參數是size, dropout, 分別代表詞嵌入大小和置零比率.
它的實例化對象輸入參數是x, sublayer, 分別代表上一層輸出以及子層的函數表示.
它的輸出就是通過子層連接結構處理的輸出.
2.3.7 編碼器層
學習目標:
了解編碼器層的作用.
掌握編碼器層的實現過程.
編碼器層的作用:
作為編碼器的組成單元, 每個編碼器層完成一次對輸入的特征提取過程, 即編碼過程.
編碼器層的構成圖:
avatar
編碼器層的代碼分析:
使用EncoderLayer類實現編碼器層
class EncoderLayer(nn.Module):
def init(self, size, self_attn, feed_forward, dropout):
“”“它的初始化函數參數有四個,分別是size,其實就是我們詞嵌入維度的大小,它也將作為我們編碼器層的大小,
第二個self_attn,之后我們將傳入多頭自注意力子層實例化對象, 并且是自注意力機制,
第三個是feed_froward, 之后我們將傳入前饋全連接層實例化對象, 最后一個是置0比率dropout.”""
super(EncoderLayer, self).init()
實例化參數:
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))
調用:
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 編碼器層總結:
學習了編碼器層的作用:
作為編碼器的組成單元, 每個編碼器層完成一次對輸入的特征提取過程, 即編碼過程.
學習并實現了編碼器層的類: EncoderLayer
類的初始化函數共有4個, 別是size,其實就是我們詞嵌入維度的大小. 第二個self_attn,之后我們將傳入多頭自注意力子層實例化對象, 并且是自注意力機制. 第三個是feed_froward, 之后我們將傳入前饋全連接層實例化對象. 最后一個是置0比率dropout.
實例化對象的輸入參數有2個,x代表來自上一層的輸出, mask代表掩碼張量.
它的輸出代表經過整個編碼層的特征表示.
2.3.8 編碼器
學習目標:
了解編碼器的作用.
掌握編碼器的實現過程.
編碼器的作用:
編碼器用于對輸入進行指定的特征提取過程, 也稱為編碼, 由N個編碼器層堆疊而成.
編碼器的結構圖:
avatar
編碼器的代碼分析:
使用Encoder類來實現編碼器
class Encoder(nn.Module):
def init(self, layer, N):
“”“初始化函數的兩個參數分別代表編碼器層和編碼器層的個數”""
super(Encoder, self).init()
# 首先使用clones函數克隆N個編碼器層放在self.layers中
self.layers = clones(layer, N)
# 再初始化一個規范化層, 它將用在編碼器的最后面.
self.norm = LayerNorm(layer.size)
實例化參數:
第一個實例化參數layer, 它是一個編碼器層的實例化對象, 因此需要傳入編碼器層的參數
又因為編碼器層中的子層是不共享的, 因此需要使用深度拷貝各個對象.
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)
編碼器中編碼器層的個數N
N = 8
mask = Variable(torch.zeros(8, 4, 4))
調用:
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 編碼器總結:
學習了編碼器的作用:
編碼器用于對輸入進行指定的特征提取過程, 也稱為編碼, 由N個編碼器層堆疊而成.
學習并實現了編碼器的類: Encoder
類的初始化函數參數有兩個,分別是layer和N,代表編碼器層和編碼器層的個數.
forward函數的輸入參數也有兩個, 和編碼器層的forward相同, x代表上一層的輸出, mask代碼掩碼張量.
編碼器類的輸出就是Transformer中編碼器的特征提取表示, 它將成為解碼器的輸入的一部分.
2.4 解碼器部分實現
學習目標
了解解碼器中各個組成部分的作用.
掌握解碼器中各個組成部分的實現過程.
解碼器部分:
由N個解碼器層堆疊而成
每個解碼器層由三個子層連接結構組成
第一個子層連接結構包括一個多頭自注意力子層和規范化層以及一個殘差連接
第二個子層連接結構包括一個多頭注意力子層和規范化層以及一個殘差連接
第三個子層連接結構包括一個前饋全連接子層和規范化層以及一個殘差連接
avatar
說明:
解碼器層中的各個部分,如,多頭注意力機制,規范化層,前饋全連接網絡,子層連接結構都與編碼器中的實現相同. 因此這里可以直接拿來構建解碼器層.
2.4.1 解碼器層
學習目標:
了解解碼器層的作用.
掌握解碼器層的實現過程.
解碼器層的作用:
作為解碼器的組成單元, 每個解碼器層根據給定的輸入向目標方向進行特征提取操作,即解碼過程.
解碼器層的代碼實現:
使用DecoderLayer的類實現解碼器層
class DecoderLayer(nn.Module):
def init(self, size, self_attn, src_attn, feed_forward, dropout):
“”“初始化函數的參數有5個, 分別是size,代表詞嵌入的維度大小, 同時也代表解碼器層的尺寸,
第二個是self_attn,多頭自注意力對象,也就是說這個注意力機制需要Q=K=V,
第三個是src_attn,多頭注意力對象,這里Q!=K=V, 第四個是前饋全連接層對象,最后就是droupout置0比率.
“””
super(DecoderLayer, self).init()
# 在初始化函數中, 主要就是將這些輸入傳到類中
self.size = size
self.self_attn = self_attn
self.src_attn = src_attn
self.feed_forward = feed_forward
# 按照結構圖使用clones函數克隆三個子層連接對象.
self.sublayer = clones(SublayerConnection(size, dropout), 3)
實例化參數:
類的實例化參數與解碼器層類似, 相比多出了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)
輸入參數:
x是來自目標數據的詞嵌入表示, 但形式和源數據的詞嵌入表示相同, 這里使用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
調用:
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 解碼器層總結:
學習了解碼器層的作用:
作為解碼器的組成單元, 每個解碼器層根據給定的輸入向目標方向進行特征提取操作,即解碼過程.
學習并實現了解碼器層的類: DecoderLayer
類的初始化函數的參數有5個, 分別是size,代表詞嵌入的維度大小, 同時也代表解碼器層的尺寸,第二個是self_attn,多頭自注意力對象,也就是說這個注意力機制需要Q=K=V,第三個是src_attn,多頭注意力對象,這里Q!=K=V, 第四個是前饋全連接層對象,最后就是droupout置0比率.
forward函數的參數有4個,分別是來自上一層的輸入x,來自編碼器層的語義存儲變量mermory, 以及源數據掩碼張量和目標數據掩碼張量.
最終輸出了由編碼器輸入和目標數據一同作用的特征提取結果.
2.4.2 解碼器
學習目標:
了解解碼器的作用.
掌握解碼器的實現過程.
解碼器的作用:
根據編碼器的結果以及上一次預測的結果, 對下一次可能出現的’值’進行特征表示.
解碼器的代碼分析:
使用類Decoder來實現解碼器
class Decoder(nn.Module):
def init(self, layer, N):
“”“初始化函數的參數有兩個,第一個就是解碼器層layer,第二個是解碼器層的個數N.”""
super(Decoder, self).init()
# 首先使用clones方法克隆了N個layer,然后實例化了一個規范化層.
# 因為數據走過了所有的解碼器層后最后要做規范化處理.
self.layers = clones(layer, N)
self.norm = LayerNorm(layer.size)
實例化參數:
分別是解碼器層layer和解碼器層的個數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
輸入參數:
輸入參數與解碼器層的輸入參數相同
x = pe_result
memory = en_result
mask = Variable(torch.zeros(8, 4, 4))
source_mask = target_mask = mask
調用:
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 解碼器總結:
學習了解碼器的作用:
根據編碼器的結果以及上一次預測的結果, 對下一次可能出現的’值’進行特征表示.
學習并實現了解碼器的類: Decoder
類的初始化函數的參數有兩個,第一個就是解碼器層layer,第二個是解碼器層的個數N.
forward函數中的參數有4個,x代表目標數據的嵌入表示,memory是編碼器層的輸出,src_mask, tgt_mask代表源數據和目標數據的掩碼張量.
輸出解碼過程的最終特征表示.
2.5 輸出部分實現
學習目標
了解線性層和softmax的作用.
掌握線性層和softmax的實現過程.
輸出部分包含:
線性層
softmax層
avatar
線性層的作用
通過對上一步的線性變化得到指定維度的輸出, 也就是轉換維度的作用.
softmax層的作用
使最后一維的向量中的數字縮放到0-1的概率值域內, 并滿足他們的和為1.
線性層和softmax層的代碼分析:
nn.functional工具包裝載了網絡層中那些只進行計算, 而沒有參數的層
import torch.nn.functional as F
將線性層和softmax計算層一起實現, 因為二者的共同目標是生成最后的結構
因此把類的名字叫做Generator, 生成器類
class Generator(nn.Module):
def init(self, d_model, vocab_size):
“”“初始化函數的輸入參數有兩個, d_model代表詞嵌入維度, vocab_size代表詞表大小.”""
super(Generator, self).init()
# 首先就是使用nn中的預定義線性層進行實例化, 得到一個對象self.project等待使用,
# 這個線性層的參數有兩個, 就是初始化函數傳進來的兩個參數: 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])
實例化參數:
詞嵌入維度是512維
d_model = 512
詞表大小是1000
vocab_size = 1000
輸入參數:
輸入x是上一層網絡的輸出, 我們使用來自解碼器層的輸出
x = de_result
調用:
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])
小節總結
學習了輸出部分包含:
線性層
softmax層
線性層的作用:
通過對上一步的線性變化得到指定維度的輸出, 也就是轉換維度的作用.
softmax層的作用:
使最后一維的向量中的數字縮放到0-1的概率值域內, 并滿足他們的和為1.
學習并實現了線性層和softmax層的類: Generator
初始化函數的輸入參數有兩個, d_model代表詞嵌入維度, vocab_size代表詞表大小.
forward函數接受上一層的輸出.
最終獲得經過線性層和softmax層處理的結果.
2.6 模型構建
學習目標
掌握編碼器-解碼器結構的實現過程.
掌握Transformer模型的構建過程.
通過上面的小節, 我們已經完成了所有組成部分的實現, 接下來就來實現完整的編碼器-解碼器結構.
Transformer總體架構圖:
avatar
編碼器-解碼器結構的代碼實現
使用EncoderDecoder類來實現編碼器-解碼器結構
class EncoderDecoder(nn.Module):
def init(self, encoder, decoder, source_embed, target_embed, generator):
“”“初始化函數中有5個參數, 分別是編碼器對象, 解碼器對象,
源數據嵌入函數, 目標數據嵌入函數, 以及輸出部分的類別生成器對象
“””
super(EncoderDecoder, self).init()
# 將參數傳入到類中
self.encoder = encoder
self.decoder = decoder
self.src_embed = source_embed
self.tgt_embed = target_embed
self.generator = generator
實例化參數
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
輸入參數:
假設源數據與目標數據相同, 實際中并不相同
source = target = Variable(torch.LongTensor([[100, 2, 421, 508], [491, 998, 1, 221]]))
假設src_mask與tgt_mask相同,實際中并不相同
source_mask = target_mask = Variable(torch.zeros(8, 4, 4))
調用:
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])
接著將基于以上結構構建用于訓練的模型.
Tansformer模型構建過程的代碼分析
def make_model(source_vocab, target_vocab, N=6,
d_model=512, d_ff=2048, head=8, dropout=0.1):
“”“該函數用來構建模型, 有7個參數,分別是源數據特征(詞匯)總數,目標數據特征(詞匯)總數,
編碼器和解碼器堆疊數,詞向量映射維度,前饋全連接網絡中變換矩陣的維度,
多頭注意力結構中的多頭數,以及置零比率dropout.”""
nn.init.xavier_uniform演示:
結果服從均勻分布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]])
輸入參數:
source_vocab = 11
target_vocab = 11
N = 6
其他參數都使用默認值
調用:
if name == ‘main’:
res = make_model(source_vocab, target_vocab, N)
print(res)
輸出效果:
根據Transformer結構圖構建的最終模型結構
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)
)
)
小節總結
學習并實現了編碼器-解碼器結構的類: EncoderDecoder
類的初始化函數傳入5個參數, 分別是編碼器對象, 解碼器對象, 源數據嵌入函數, 目標數據嵌入函數, 以及輸出部分的類別生成器對象.
類中共實現三個函數, forward, encode, decode
forward是主要邏輯函數, 有四個參數, source代表源數據, target代表目標數據, source_mask和target_mask代表對應的掩碼張量.
encode是編碼函數, 以source和source_mask為參數.
decode是解碼函數, 以memory即編碼器的輸出, source_mask, target, target_mask為參數
學習并實現了模型構建函數: make_model
有7個參數,分別是源數據特征(詞匯)總數,目標數據特征(詞匯)總數,編碼器和解碼器堆疊數,詞向量映射維度,前饋全連接網絡中變換矩陣的維度,多頭注意力結構中的多頭數,以及置零比率dropout.
該函數最后返回一個構建好的模型對象.
上一頁第一章:Transformer背景介紹
?Copyright 2019, itcast.cn.
Made with Material for MkDocs
跳轉至
logo
遷移學習
第一章:fasttext工具的使用
logo
遷移學習
第一章:fasttext工具的使用
第二章:遷移學習
目錄
1.1 認識fasttext工具
學習目標
1.2 進行文本分類
學習目標
什么是文本分類
文本分類的種類
使用fasttext工具進行文本分類的過程
第一步: 獲取數據
第二步: 訓練集與驗證集的劃分
第三步: 訓練模型
第四步: 使用模型進行預測并評估
第五步: 模型調優
第六步: 模型保存與重加載
小節總結
1.3 訓練詞向量
學習目標
使用fasttext工具訓練詞向量的過程
第一步: 獲取數據
第二步: 訓練詞向量
第三步: 模型超參數設定
第四步: 模型效果檢驗
第五步: 模型的保存與重加載
小節總結
1.4 詞向量遷移
學習目標
如何使用fasttext進行詞向量模型遷移
第一步: 下載詞向量模型壓縮的bin.gz文件
第二步: 解壓bin.gz文件到bin文件
第三步: 加載bin文件獲取詞向量
第四步: 利用鄰近詞進行效果檢驗
小節總結
第一章:fasttext工具的使用
1.1 認識fasttext工具
學習目標
了解fasttext工具的作用.
了解fasttext工具的優勢及其原因.
掌握fasttext的安裝方法.
作為NLP工程領域常用的工具包, fasttext有兩大作用:
進行文本分類
訓練詞向量
fasttext工具包的優勢:
正如它的名字, 在保持較高精度的情況下, 快速的進行訓練和預測是fasttext的最大優勢.
fasttext優勢的原因:
fasttext工具包中內含的fasttext模型具有十分簡單的網絡結構.
使用fasttext模型訓練詞向量時使用層次softmax結構, 來提升超多類別下的模型性能.
由于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 “license” for more information.
import fasttext
1.2 進行文本分類
學習目標
了解什么是文本分類及其種類.
掌握fasttext工具進行文本分類的過程.
什么是文本分類
文本分類的是將文檔(例如電子郵件,帖子,文本消息,產品評論等)分配給一個或多個類別. 當今文本分類的實現多是使用機器學習方法從訓練數據中提取分類規則以進行分類, 因此構建文本分類器需要帶標簽的數據.
文本分類的種類
二分類:
文本被分類兩個類別中, 往往這兩個類別是對立面, 比如: 判斷一句評論是好評還是差評.
單標簽多分類:
文本被分入到多個類別中, 且每條文本只能屬于某一個類別(即被打上某一個標簽), 比如: 輸入一個人名, 判斷它是來自哪個國家的人名.
多標簽多分類:
文本被分人到多個類別中, 但每條文本可以屬于多個類別(即被打上多個標簽), 比如: 輸入一段描述, 判斷可能是和哪些興趣愛好有關, 一段描述中可能即討論了美食, 又太討論了游戲愛好.
使用fasttext工具進行文本分類的過程
第一步: 獲取數據
第二步: 訓練集與驗證集的劃分
第三步: 訓練模型
第四步: 使用模型進行預測并評估
第五步: 模型調優
第六步: 模型保存與重加載
第一步: 獲取數據
獲取烹飪相關的數據集, 它是由facebook AI實驗室提供的演示數據集
$ wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz && tar xvzf cooking.stackexchange.tar.gz
查看數據的前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
數據說明:
cooking.stackexchange.txt中的每一行都包含一個標簽列表,后跟相應的文檔, 標簽列表以類似"__label__sauce __label__cheese"的形式展現, 代表有兩個標簽sauce和cheese, 所有標簽__label__均以前綴開頭,這是fastText識別標簽或單詞的方式. 標簽之后的一段話就是文本信息.如: How much does potato starch affect a cheese sauce recipe?
第二步: 訓練集與驗證集的劃分
查看數據總數
$ wc cooking.stackexchange.txt
15404 169582 1401900 cooking.stackexchange.txt
12404條數據作為訓練數據
$ head -n 12404 cooking.stackexchange.txt > cooking.train
3000條數據作為驗證數據
$ tail -n 3000 cooking.stackexchange.txt > cooking.valid
第三步: 訓練模型
代碼運行在python解釋器中
導入fasttext
import fasttext
使用fasttext的train_supervised方法進行文本分類模型的訓練
model = fasttext.train_supervised(input=“cooking.train”)
獲得結果
Read 0M words
不重復的詞匯總數
Number of words: 14543
標簽總數
Number of labels: 735
Progress: 訓練進度, 因為我們這里顯示的是最后的訓練完成信息, 所以進度是100%
words/sec/thread: 每個線程每秒處理的平均詞匯數
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]))
為了評估模型到底表現如何, 我們在3000條的驗證集上進行測試
model.test(“cooking.valid”)
元組中的每項分別代表, 驗證集樣本數量, 精度以及召回率
我們看到模型精度和召回率表現都很差, 接下來我們講學習如何進行優化.
(3000, 0.124, 0.0541)
第五步: 模型調優
原始數據處理:
通過查看數據, 我們發現數據中存在許多標點符號與單詞相連以及大小寫不統一,
這些因素對我們最終的分類目標沒有益處, 反是增加了模型提取分類規律的難度,
因此我們選擇將它們去除或轉化
處理前的部分數據
__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?
通過服務器終端進行簡單的數據預處理
使標點符號與單詞分離并統一使用小寫字母
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
處理后的部分數據
__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 ?
數據處理后進行訓練并測試:
重新訓練
model = fasttext.train_supervised(input=“cooking.train”)
Read 0M words
不重復的詞匯總數減少很多, 因為之前會把帶大寫字母或者與標點符號相連接的單詞都認為是新的單詞
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)
增加訓練輪數:
設置train_supervised方法中的參數epoch來增加訓練輪數, 默認的輪數是5次
增加輪數意味著模型能夠有更多機會在有限數據中調整分類規律, 當然這也會增加訓練時間
model = fasttext.train_supervised(input=“cooking.train”, epoch=25)
Read 0M words
Number of words: 8952
Number of labels: 735
我們看到平均損失繼續下降
Progress: 100.0% words/sec/thread: 66283 lr: 0.000000 avg.loss: 7.203885 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度已經提升到了42%, 召回率提升至18%.
(3000, 0.4206666666666667, 0.1819230214790255)
調整學習率:
設置train_supervised方法中的參數lr來調整學習率, 默認的學習率大小是0.1
增大學習率意味著增大了梯度下降的步長使其在有限的迭代步驟下更接近最優點
model = fasttext.train_supervised(input=“cooking.train”, lr=1.0, epoch=25)
Read 0M words
Number of words: 8952
Number of labels: 735
平均損失繼續下降
Progress: 100.0% words/sec/thread: 66027 lr: 0.000000 avg.loss: 4.278283 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度已經提升到了47%, 召回率提升至20%.
(3000, 0.47633333333333333, 0.20599682860025947)
增加n-gram特征:
設置train_supervised方法中的參數wordNgrams來添加n-gram特征, 默認是1, 也就是沒有n-gram特征
我們這里將其設置為2意味著添加2-gram特征, 這些特征幫助模型捕捉前后詞匯之間的關聯, 更好的提取分類規則用于模型分類, 當然這也會增加模型訓時練占用的資源和時間.
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
平均損失繼續下降
Progress: 100.0% words/sec/thread: 65084 lr: 0.000000 avg.loss: 3.189422 ETA: 0h 0m 0s
model.test(“cooking.valid”)
我們看到精度已經提升到了49%, 召回率提升至21%.
(3000, 0.49233333333333335, 0.2129162462159435)
修改損失計算方式:
隨著我們不斷的添加優化策略, 模型訓練速度也越來越慢
為了能夠提升fasttext模型的訓練效率, 減小訓練時間
設置train_supervised方法中的參數loss來修改損失計算方式(等效于輸出層的結構), 默認是softmax層結構
我們這里將其設置為’hs’, 代表層次softmax結構, 意味著輸出層的結構(計算方式)發生了變化, 將以一種更低復雜度的方式來計算損失.
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)
自動超參數調優:
手動調節和尋找超參數是非常困難的, 因為參數之間可能相關, 并且不同數據集需要的超參數也不同,
因此可以使用fasttext的autotuneValidationFile參數進行自動超參數調優.
autotuneValidationFile參數需要指定驗證數據集所在路徑, 它將在驗證集上使用隨機搜索方法尋找可能最優的超參數.
使用autotuneDuration參數可以控制隨機搜索的時間, 默認是300s, 根據不同的需求, 我們可以延長或縮短時間.
驗證集路徑’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
實際生產中多標簽多分類問題的損失計算方式:
針對多標簽多分類問題, 使用’softmax’或者’hs’有時并不是最佳選擇, 因為我們最終得到的應該是多個標簽, 而softmax卻只能最大化一個標簽.
所以我們往往會選擇為每個標簽使用獨立的二分類器作為輸出層結構,
對應的損失計算方式為’ova’表示one vs all.
這種輸出層的改變意味著我們在統一語料下同時訓練多個二分類模型,
對于二分類模型來講, lr不宜過大, 這里我們設置為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
我們使用模型進行單條樣本的預測, 來看一下它的輸出結果.
參數k代表指定模型輸出多少個標簽, 默認為1, 這里設置為-1, 意味著盡可能多的輸出.
參數threshold代表顯示的標簽概率閾值, 設置為0.5, 意味著顯示概率大于0.5的標簽
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]))
第六步: 模型保存與重加載
使用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]))
小節總結
學習了什么是文本分類:
文本分類的是將文檔(例如電子郵件,帖子,文本消息,產品評論等)分配給一個或多個類別. 當今文本分類的實現多是使用機器學習方法從訓練數據中提取分類規則以進行分類, 因此構建文本分類器需要帶標簽的數據.
文本分類的種類:
二分類:
文本被分類兩個類別中, 往往這兩個類別是對立面, 比如: 判斷一句評論是好評還是差評.
單標簽多分類:
文本被分入到多個類別中, 且每條文本只能屬于某一個類別(即被打上某一個標簽), 比如: 輸入一個人名, 判斷它是來自哪個國家的人名.
多標簽多分類:
文本被分人到多個類別中, 但每條文本可以屬于多個類別(即被打上多個標簽), 比如: 輸入一段描述, 判斷可能是和哪些興趣愛好有關, 一段描述中可能即討論了美食, 又太討論了游戲愛好.
使用fasttext工具進行文本分類的過程:
第一步: 獲取數據
第二步: 訓練集與驗證集的劃分
第三步: 訓練模型
第四步: 使用模型進行預測并評估
第五步: 模型調優
第六步: 模型保存與重加載
1.3 訓練詞向量
學習目標
了解詞向量的相關知識.
掌握fasttext工具訓練詞向量的過程.
詞向量的相關知識:
用向量表示文本中的詞匯(或字符)是現代機器學習中最流行的做法, 這些向量能夠很好的捕捉語言之間的關系, 從而提升基于詞向量的各種NLP任務的效果.
使用fasttext工具訓練詞向量的過程
第一步: 獲取數據
第二步: 訓練詞向量
第三步: 模型超參數設定
第四步: 模型效果檢驗
第五步: 模型的保存與重加載
第一步: 獲取數據
在這里, 我們將研究英語維基百科的部分網頁信息, 它的大小在300M左右
這些語料已經被準備好, 我們可以通過Matt Mahoney的網站下載.
首先創建一個存儲數據的文件夾data
$ mkdir data
使用wget下載數據的zip壓縮包, 它將存儲在data目錄中
$ wget -c http://mattmahoney.net/dc/enwik9.zip -P data
使用unzip解壓, 如果你的服務器中還沒有unzip命令, 請使用: yum install unzip -y
解壓后在data目錄下會出現enwik9的文件夾
$ unzip data/enwik9.zip -d data
查看原始數據:
$ head -10 data/enwik9
原始數據將輸出很多包含XML/HTML格式的內容, 這些內容并不是我們需要的
Wikipedia http://en.wikipedia.org/wiki/Main_Page MediaWiki 1.6alpha first-letter Media Special 原始數據處理:使用wikifil.pl文件處理腳本來清除XML/HTML格式的內容
注: wikifil.pl文件已為大家提供
$ perl wikifil.pl data/enwik9 > data/fil9
查看預處理后的數據:
查看前80個字符
head -c 80 data/fil9
輸出結果為由空格分割的單詞
anarchism originated as a term of abuse first used against early working class
第二步: 訓練詞向量
代碼運行在python解釋器中
導入fasttext
import fasttext
使用fasttext的train_unsupervised(無監督訓練方法)進行詞向量的訓練
它的參數是數據集的持久化文件路徑’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)
第三步: 模型超參數設定
在訓練詞向量過程中, 我們可以設定很多常用超參數來調節我們的模型效果, 如:
無監督訓練模式: ‘skipgram’ 或者 ‘cbow’, 默認為’skipgram’, 在實踐中,skipgram模式在利用子詞方面比cbow更好.
詞嵌入維度dim: 默認為100, 但隨著語料庫的增大, 詞嵌入的維度往往也要更大.
數據循環次數epoch: 默認為5, 但當你的數據集足夠大, 可能不需要那么多次.
學習率lr: 默認為0.05, 根據經驗, 建議選擇[0.01,1]范圍內.
使用的線程數thread: 默認為12個線程, 一般建議和你的cpu核數相同.
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
第四步: 模型效果檢驗
檢查單詞向量質量的一種簡單方法就是查看其鄰近單詞, 通過我們主觀來判斷這些鄰近單詞是否與目標單詞相關來粗略評定模型效果好壞.
查找"運動"的鄰近單詞, 我們可以發現"體育網", “運動汽車”, "運動服"等.
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’)]
查找"音樂"的鄰近單詞, 我們可以發現與音樂有關的詞匯.
model.get_nearest_neighbors(‘music’)
[(0.8908010125160217, ‘emusic’), (0.8464668393135071, ‘musicmoz’), (0.8444250822067261, ‘musics’), (0.8113634586334229, ‘allmusic’), (0.8106718063354492, ‘musices’), (0.8049437999725342, ‘musicam’), (0.8004694581031799, ‘musicom’), (0.7952923774719238, ‘muchmusic’), (0.7852965593338013, ‘musicweb’), (0.7767147421836853, ‘musico’)]
查找"小狗"的鄰近單詞, 我們可以發現與小狗有關的詞匯.
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)
小節總結
學習了詞向量的相關知識:
用向量表示文本中的詞匯(或字符)是現代機器學習中最流行的做法, 這些向量能夠很好的捕捉語言之間的關系, 從而提升基于詞向量的各種NLP任務的效果.
使用fasttext工具訓練詞向量的過程:
第一步: 獲取數據
第二步: 訓練詞向量
第三步: 模型超參數設定
第四步: 模型效果檢驗
第五步: 模型的保存與重加載
1.4 詞向量遷移
學習目標
了解什么是詞向量遷移.
了解fasttext工具中有哪些可遷移的詞向量模型.
掌握如何使用fasttext進行詞向量模型遷移.
什么是詞向量遷移:
使用在大型語料庫上已經進行訓練完成的詞向量模型.
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)
第四步: 利用鄰近詞進行效果檢驗
以’音樂’為例, 返回的鄰近詞基本上與音樂都有關系, 如樂曲, 音樂會, 聲樂等.
model.get_nearest_neighbors(“音樂”)
[(0.6703276634216309, ‘樂曲’), (0.6569967269897461, ‘音樂人’), (0.6565821170806885, ‘聲樂’), (0.6557438373565674, ‘輕音樂’), (0.6536258459091187, ‘音樂家’), (0.6502416133880615, ‘配樂’), (0.6501686573028564, ‘藝術’), (0.6437276005744934, ‘音樂會’), (0.639589250087738, ‘原聲’), (0.6368917226791382, ‘音響’)]
以’美術’為例, 返回的鄰近詞基本上與美術都有關系, 如藝術, 繪畫, 霍廷霄(滿城盡帶黃金甲的美術師)等.
model.get_nearest_neighbors(“美術”)
[(0.724744975566864, ‘藝術’), (0.7165924310684204, ‘繪畫’), (0.6741853356361389, ‘霍廷霄’), (0.6470299363136292, ‘純藝’), (0.6335071921348572, ‘美術家’), (0.6304370164871216, ‘美院’), (0.624431312084198, ‘藝術類’), (0.6244068741798401, ‘陳浩忠’), (0.62302166223526, ‘美術史’), (0.621710479259491, ‘環藝系’)]
以’周杰倫’為例, 返回的鄰近詞基本上與明星有關系, 如杰倫, 周董, 陳奕迅等.
model.get_nearest_neighbors(“周杰倫”)
[(0.6995140910148621, ‘杰倫’), (0.6967097520828247, ‘周杰倫’), (0.6859776377677917, ‘周董’), (0.6381043195724487, ‘陳奕迅’), (0.6367626190185547, ‘張靚穎’), (0.6313326358795166, ‘張韶涵’), (0.6271176338195801, ‘謝霆鋒’), (0.6188404560089111, ‘周華健’), (0.6184280514717102, ‘林俊杰’), (0.6143589019775391, ‘王力宏’)]
小節總結
學習了什么是詞向量遷移:
使用在大型語料庫上已經進行訓練完成的詞向量模型.
學習了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
跳轉至
logo
遷移學習
第二章:遷移學習
logo
遷移學習
第一章:fasttext工具的使用
第二章:遷移學習
目錄
2.1 遷移學習理論
學習目標
2.2 NLP中的標準數據集
學習目標
GLUE數據集合包含以下數據集
GLUE數據集合中子數據集的樣式及其任務類型
CoLA數據集文件樣式
SST-2數據集文件樣式
MRPC數據集文件樣式
STS-B數據集文件樣式
QQP數據集文件樣式
(MNLI/SNLI)數據集文件樣式
(QNLI/RTE/WNLI)數據集文件樣式
小節總結
2.3 NLP中的常用預訓練模型
學習目標
當下NLP中流行的預訓練模型
小節總結
2.4 加載和使用預訓練模型
學習目標
加載和使用預訓練模型的工具
加載和使用預訓練模型的步驟
第一步: 確定需要加載的預訓練模型并安裝依賴包
第二步: 加載預訓練模型的映射器tokenizer
第三步: 加載帶/不帶頭的預訓練模型
第四步: 使用模型獲得輸出結果
小節總結
2.5 遷移學習實踐
學習目標
指定任務類型的微調腳本使用步驟
第一步: 下載微調腳本文件
第二步: 配置微調腳本參數
第三步: 運行并檢驗效果
通過微調腳本微調后模型的使用步驟
第一步: 在https://huggingface.co/join上創建一個帳戶
第二步: 在服務器終端使用transformers-cli登陸
第三步: 使用transformers-cli上傳模型并查看
第四步: 使用pytorch.hub加載模型進行使用, 更多信息請參考2.4 加載和使用預訓練模型
通過微調方式進行遷移學習的兩種類型
類型一實戰演示
類型二實戰演示
小節總結
第二章:遷移學習
2.1 遷移學習理論
學習目標
了解遷移學習中的有關概念.
掌握遷移學習的兩種遷移方式.
遷移學習中的有關概念:
預訓練模型
微調
微調腳本
預訓練模型(Pretrained model):
一般情況下預訓練模型都是大型模型,具備復雜的網絡結構,眾多的參數量,以及在足夠大的數據集下進行訓練而產生的模型. 在NLP領域,預訓練模型往往是語言模型,因為語言模型的訓練是無監督的,可以獲得大規模語料,同時語言模型又是許多典型NLP任務的基礎,如機器翻譯,文本生成,閱讀理解等,常見的預訓練模型有BERT, GPT, roBERTa, transformer-XL等.
微調(Fine-tuning):
根據給定的預訓練模型,改變它的部分參數或者為其新增部分輸出結構后,通過在小部分數據集上訓練,來使整個模型更好的適應特定任務.
微調腳本(Fine-tuning script):
實現微調過程的代碼文件。這些腳本文件中,應包括對預訓練模型的調用,對微調參數的選定以及對微調結構的更改等,同時,因為微調是一個訓練過程,它同樣需要一些超參數的設定,以及損失函數和優化器的選取等, 因此微調腳本往往也包含了整個遷移學習的過程.
關于微調腳本的說明:
一般情況下,微調腳本應該由不同的任務類型開發者自己編寫,但是由于目前研究的NLP任務類型(分類,提取,生成)以及對應的微調輸出結構都是有限的,有些微調方式已經在很多數據集上被驗證是有效的,因此微調腳本也可以使用已經完成的規范腳本.
兩種遷移方式:
直接使用預訓練模型,進行相同任務的處理,不需要調整參數或模型結構,這些模型開箱即用。但是這種情況一般只適用于普適任務, 如:fasttest工具包中預訓練的詞向量模型。另外,很多預訓練模型開發者為了達到開箱即用的效果,將模型結構分各個部分保存為不同的預訓練模型,提供對應的加載方法來完成特定目標.
更加主流的遷移學習方式是發揮預訓練模型特征抽象的能力,然后再通過微調的方式,通過訓練更新小部分參數以此來適應不同的任務。這種遷移方式需要提供小部分的標注數據來進行監督學習.
關于遷移方式的說明:
直接使用預訓練模型的方式, 已經在fasttext的詞向量遷移中學習. 接下來的遷移學習實踐將主要講解通過微調的方式進行遷移學習.
2.2 NLP中的標準數據集
學習目標
了解NLP中GLUE標準數據集合的相關知識.
掌握GLUE標準數據集合的下載方式, 數據樣式及其對應的任務類型.
GLUE數據集合的介紹:
GLUE由紐約大學, 華盛頓大學, Google聯合推出, 涵蓋不同NLP任務類型, 截止至2020年1月其中包括11個子任務數據集, 成為衡量NLP研究發展的衡量標準.
GLUE數據集合包含以下數據集
CoLA 數據集
SST-2 數據集
MRPC 數據集
STS-B 數據集
QQP 數據集
MNLI 數據集
SNLI 數據集
QNLI 數據集
RTE 數據集
WNLI 數據集
diagnostics數據集(官方未完善)
GLUE數據集合的下載方式:
下載腳本代碼:
‘’’ 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=‘all’)
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:]))
運行腳本下載所有數據集:
假設你已經將以上代碼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數據集合中子數據集的樣式及其任務類型
CoLA數據集文件樣式
- CoLA/
- dev.tsv
- original/
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數據樣式相同, 都是帶有標簽的數據, 其中test.tsv是不帶有標簽的數據.
train.tsv數據樣式:
…
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數據樣式說明:
train.tsv中的數據內容共分為4列, 第一列數據, 如gj04, bc01等代表每條文本數據的來源即出版物代號; 第二列數據, 0或1, 代表每條文本數據的語法是否正確, 0代表不正確, 1代表正確; 第三列數據, ‘’, 是作者最初的正負樣本標記, 與第二列意義相同, ''表示不正確; 第四列即是被標注的語法使用是否正確的文本句子.
test.tsv數據樣式:
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數據樣式說明:
test.tsv中的數據內容共分為2列, 第一列數據代表每條文本數據的索引; 第二列數據代表用于測試的句子.
CoLA數據集的任務類型:
二分類任務
評估指標為: MCC(馬修斯相關系數, 在正負樣本分布十分不均衡的情況下使用的二分類評估指標)
SST-2數據集文件樣式
- SST-2/
- dev.tsv
- original/
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數據樣式相同, 都是帶有標簽的數據, 其中test.tsv是不帶有標簽的數據.
train.tsv數據樣式:
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數據樣式說明:
train.tsv中的數據內容共分為2列, 第一列數據代表具有感情色彩的評論文本; 第二列數據, 0或1, 代表每條文本數據是積極或者消極的評論, 0代表消極, 1代表積極.
test.tsv數據樣式:
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數據樣式說明: * test.tsv中的數據內容共分為2列, 第一列數據代表每條文本數據的索引; 第二列數據代表用于測試的句子.
SST-2數據集的任務類型:
二分類任務
評估指標為: ACC
MRPC數據集文件樣式
- 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數據樣式相同, 都是帶有標簽的數據, 其中test.tsv是不帶有標簽的數據.
train.tsv數據樣式:
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數據樣式說明:
train.tsv中的數據內容共分為5列, 第一列數據, 0或1, 代表每對句子是否具有相同的含義, 0代表含義不相同, 1代表含義相同. 第二列和第三列分別代表每對句子的id, 第四列和第五列分別具有相同/不同含義的句子對.
test.tsv數據樣式:
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數據樣式說明: * test.tsv中的數據內容共分為5列, 第一列數據代表每條文本數據的索引; 其余列的含義與train.tsv中相同.
MRPC數據集的任務類型:
句子對二分類任務
評估指標為: ACC和F1
STS-B數據集文件樣式
- STS-B/
- dev.tsv
- test.tsv
- train.tsv- LICENSE.txt
- readme.txt
- original/
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數據樣式相同, 都是帶有標簽的數據, 其中test.tsv是不帶有標簽的數據.
train.tsv數據樣式:
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數據樣式說明:
train.tsv中的數據內容共分為10列, 第一列數據是數據索引; 第二列代表每對句子的來源, 如main-captions表示來自字幕; 第三列代表來源的具體保存文件名, 第四列代表出現時間(年); 第五列代表原始數據的索引; 第六列和第七列分別代表句子對原始來源; 第八列和第九列代表相似程度不同的句子對; 第十列代表句子對的相似程度由低到高, 值域范圍是[0, 5].
test.tsv數據樣式:
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數據樣式說明:
test.tsv中的數據內容共分為9列, 含義與train.tsv前9列相同.
STS-B數據集的任務類型:
句子對多分類任務/句子對回歸任務
評估指標為: Pearson-Spearman Corr
QQP數據集文件樣式
- QQP/
- dev.tsv
- original/
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數據樣式相同, 都是帶有標簽的數據, 其中test.tsv是不帶有標簽的數據.
train.tsv數據樣式:
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數據樣式說明:
train.tsv中的數據內容共分為6列, 第一列代表文本數據索引; 第二列和第三列數據分別代表問題1和問題2的id; 第四列和第五列代表需要進行’是否重復’判定的句子對; 第六列代表上述問題是/不是重復性問題的標簽, 0代表不重復, 1代表重復.
test.tsv數據樣式:
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數據樣式說明:
test.tsv中的數據內容共分為3列, 第一列數據代表每條文本數據的索引; 第二列和第三列數據代表用于測試的問題句子對.
QQP數據集的任務類型:
句子對二分類任務
評估指標為: ACC/F1
(MNLI/SNLI)數據集文件樣式
- (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數據樣式相同, 都是帶有標簽的數據, 其中test_matched.tsv與test_mismatched.tsv數據樣式相同, 都是不帶有標簽的數據.
train.tsv數據樣式:
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數據樣式說明:
train.tsv中的數據內容共分為12列, 第一列代表文本數據索引; 第二列和第三列數據分別代表句子對的不同類型id; 第四列代表句子對的來源; 第五列和第六列代表具有句法結構分析的句子對表示; 第七列和第八列代表具有句法結構和詞性標注的句子對表示, 第九列和第十列代表原始的句子對, 第十一和第十二列代表不同標準的標注方法產生的標簽, 在這里,他們始終相同, 一共有三種類型的標簽, neutral代表兩個句子既不矛盾也不蘊含, entailment代表兩個句子具有蘊含關系, contradiction代表兩個句子觀點矛盾.
test_matched.tsv數據樣式:
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數據樣式說明:
test_matched.tsv中的數據內容共分為10列, 與train.tsv的前10列含義相同.
(MNLI/SNLI)數據集的任務類型:
句子對多分類任務
評估指標為: ACC
(QNLI/RTE/WNLI)數據集文件樣式
- QNLI, RTE, WNLI三個數據集的樣式基本相同.
- (QNLI/RTE/WNLI)/
- dev.tsv
- test.tsv
- train.tsv
文件樣式說明:
在使用中常用到的文件是train.tsv, dev.tsv, test.tsv, 分別代表訓練集, 驗證集和測試集. 其中train.tsv與dev.tsv數據樣式相同, 都是帶有標簽的數據, 其中test.tsv是不帶有標簽的數據.
QNLI中的train.tsv數據樣式:
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數據樣式:
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數據樣式:
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數據樣式說明:
train.tsv中的數據內容共分為4列, 第一列代表文本數據索引; 第二列和第三列數據代表需要進行’是否蘊含’判定的句子對; 第四列數據代表兩個句子是否具有蘊含關系, 0/not_entailment代表不是蘊含關系, 1/entailment代表蘊含關系.
QNLI中的test.tsv數據樣式:
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數據樣式:
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數據樣式說明:
test.tsv中的數據內容共分為3列, 第一列數據代表每條文本數據的索引; 第二列和第三列數據代表需要進行’是否蘊含’判定的句子對.
(QNLI/RTE/WNLI)數據集的任務類型:
句子對二分類任務
評估指標為: ACC
小節總結
學習了GLUE數據集合的介紹:
GLUE由紐約大學, 華盛頓大學, Google聯合推出, 涵蓋不同NLP任務類型, 截止至2020年1月其中包括11個子任務數據集, 成為衡量NLP研究發展的衡量標準.
GLUE數據集合包含以下數據集:
CoLA 數據集
SST-2 數據集
MRPC 數據集
STS-B 數據集
QQP 數據集
MNLI 數據集
SNLI 數據集
QNLI 數據集
RTE 數據集
WNLI 數據集
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參數量, 在小寫的英文文本上進行訓練而得到.
bert-large-uncased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共340M參數量, 在小寫的英文文本上進行訓練而得到.
bert-base-cased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數量, 在不區分大小寫的英文文本上進行訓練而得到.
bert-large-cased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共340M參數量, 在不區分大小寫的英文文本上進行訓練而得到.
bert-base-multilingual-uncased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數量, 在小寫的102種語言文本上進行訓練而得到.
bert-large-multilingual-uncased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共340M參數量, 在小寫的102種語言文本上進行訓練而得到.
bert-base-chinese: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數量, 在簡體和繁體中文文本上進行訓練而得到.
GPT:
openai-gpt: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數量, 由OpenAI在英文語料上進行訓練而得到.
GPT-2及其變體:
gpt2: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共117M參數量, 在OpenAI GPT-2英文語料上進行訓練而得到.
gpt2-xl: 編碼器具有48個隱層, 輸出1600維張量, 25個自注意力頭, 共1558M參數量, 在大型的OpenAI GPT-2英文語料上進行訓練而得到.
Transformer-XL:
transfo-xl-wt103: 編碼器具有18個隱層, 輸出1024維張量, 16個自注意力頭, 共257M參數量, 在wikitext-103英文語料進行訓練而得到.
XLNet及其變體:
xlnet-base-cased: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共110M參數量, 在英文語料上進行訓練而得到.
xlnet-large-cased: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共240參數量, 在英文語料上進行訓練而得到.
XLM:
xlm-mlm-en-2048: 編碼器具有12個隱層, 輸出2048維張量, 16個自注意力頭, 在英文文本上進行訓練而得到.
RoBERTa及其變體:
roberta-base: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共125M參數量, 在英文文本上進行訓練而得到.
roberta-large: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共355M參數量, 在英文文本上進行訓練而得到.
DistilBERT及其變體:
distilbert-base-uncased: 基于bert-base-uncased的蒸餾(壓縮)模型, 編碼器具有6個隱層, 輸出768維張量, 12個自注意力頭, 共66M參數量.
distilbert-base-multilingual-cased: 基于bert-base-multilingual-uncased的蒸餾(壓縮)模型, 編碼器具有6個隱層, 輸出768維張量, 12個自注意力頭, 共66M參數量.
ALBERT:
albert-base-v1: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共125M參數量, 在英文文本上進行訓練而得到.
albert-base-v2: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共125M參數量, 在英文文本上進行訓練而得到, 相比v1使用了更多的數據量, 花費更長的訓練時間.
T5及其變體:
t5-small: 編碼器具有6個隱層, 輸出512維張量, 8個自注意力頭, 共60M參數量, 在C4語料上進行訓練而得到.
t5-base: 編碼器具有12個隱層, 輸出768維張量, 12個自注意力頭, 共220M參數量, 在C4語料上進行訓練而得到.
t5-large: 編碼器具有24個隱層, 輸出1024維張量, 16個自注意力頭, 共770M參數量, 在C4語料上進行訓練而得到.
XLM-RoBERTa及其變體:
xlm-roberta-base: 編碼器具有12個隱層, 輸出768維張量, 8個自注意力頭, 共125M參數量, 在2.5TB的100種語言文本上進行訓練而得到.
xlm-roberta-large: 編碼器具有24個隱層, 輸出1027維張量, 16個自注意力頭, 共355M參數量, 在2.5TB的100種語言文本上進行訓練而得到.
預訓練模型說明:
所有上述預訓練模型及其變體都是以transformer為基礎,只是在模型結構如神經元連接方式,編碼器隱層數,多頭注意力的頭數等發生改變,這些改變方式的大部分依據都是由在標準數據集上的表現而定,因此,對于我們使用者而言,不需要從理論上深度探究這些預訓練模型的結構設計的優劣,只需要在自己處理的目標數據上,盡量遍歷所有可用的模型對比得到最優效果即可.
小節總結
當下NLP中流行的預訓練模型:
BERT
GPT
GPT-2
Transformer-XL
XLNet
XLM
RoBERTa
DistilBERT
ALBERT
T5
XLM-RoBERTa
2.4 加載和使用預訓練模型
學習目標
了解加載和使用預訓練模型的工具.
掌握加載和使用預訓練模型的過程.
加載和使用預訓練模型的工具
在這里我們使用torch.hub工具進行模型的加載和使用.
這些預訓練模型由世界先進的NLP研發團隊huggingface提供.
注意: 下面使用的代碼需要國外服務器的資源, 在國內使用的時候, 國內的網站下載可能會出現在原地卡死不動, 或是網絡連接超時等一些網絡報錯, 均是網絡問題, 不是代碼問題, 這個可以先行跳過, 把主要邏輯梳理完成即可
加載和使用預訓練模型的步驟
第一步: 確定需要加載的預訓練模型并安裝依賴包.
第二步: 加載預訓練模型的映射器tokenizer.
第三步: 加載帶/不帶頭的預訓練模型.
第四步: 使用模型獲得輸出結果.
第一步: 確定需要加載的預訓練模型并安裝依賴包
能夠加載哪些模型可以參考2.3 NLP中的常用預訓練模型
這里假設我們處理的是中文文本任務, 需要加載的模型是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)的張量, 用于進行分類任務判定結果.
加載不帶頭的預訓練模型
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)
第四步: 使用模型獲得輸出結果
使用不帶頭的模型進行輸出:
輸入的中文文本
input_text = “人生該如何起頭”
使用tokenizer進行數值映射
indexed_tokens = tokenizer.encode(input_text)
打印映射后的結構
print(“indexed_tokens:”, indexed_tokens)
將映射結構轉化為張量輸送給不帶頭的預訓練模型
tokens_tensor = torch.tensor([indexed_tokens])
使用不帶頭的預訓練模型獲得結果
with torch.no_grad():
encoded_layers, _ = model(tokens_tensor)
print(“不帶頭的模型輸出結果:”, encoded_layers)
print(“不帶頭的模型輸出結果的尺寸:”, encoded_layers.shape)
輸出效果:
tokenizer映射后的結果, 101和102是起止符,
中間的每個數字對應"人生該如何起頭"的每個字.
indexed_tokens: [101, 782, 4495, 6421, 1963, 862, 6629, 1928, 102]
不帶頭的模型輸出結果: 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, 即每個字已經使用768維的向量進行了表示,
我們可以基于此編碼結果進行接下來的自定義操作, 如: 編寫自己的微調網絡進行最終輸出.
不帶頭的模型輸出結果的尺寸: torch.Size([1, 9, 768])
使用帶有語言模型頭的模型進行輸出:
使用帶有語言模型頭的預訓練模型獲得結果
with torch.no_grad():
lm_output = lm_model(tokens_tensor)
print(“帶語言模型頭的模型輸出結果:”, lm_output)
print(“帶語言模型頭的模型輸出結果的尺寸:”, lm_output[0].shape)
輸出效果:
帶語言模型頭的模型輸出結果: (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, 即每個字已經使用21128維的向量進行了表示,
同不帶頭的模型一樣, 我們可以基于此編碼結果進行接下來的自定義操作, 如: 編寫自己的微調網絡進行最終輸出.
帶語言模型頭的模型輸出結果的尺寸: torch.Size([1, 9, 21128])
使用帶有分類模型頭的模型進行輸出:
使用帶有分類模型頭的預訓練模型獲得結果
with torch.no_grad():
classification_output = classification_model(tokens_tensor)
print(“帶分類模型頭的模型輸出結果:”, classification_output)
print(“帶分類模型頭的模型輸出結果的尺寸:”, classification_output[0].shape)
輸出效果:
帶分類模型頭的模型輸出結果: (tensor([[-0.0649, -0.1593]]),)
輸出尺寸為1x2, 可直接用于文本二分問題的輸出
帶分類模型頭的模型輸出結果的尺寸: torch.Size([1, 2])
使用帶有問答模型頭的模型進行輸出:
使用帶有問答模型頭的模型進行輸出時, 需要使輸入的形式為句子對
第一條句子是對客觀事物的陳述
第二條句子是針對第一條句子提出的問題
問答模型最終將得到兩個張量,
每個張量中最大值對應索引的分別代表答案的在文本中的起始位置和終止位置.
input_text1 = “我家的小狗是黑色的”
input_text2 = “我家的小狗是什么顏色的呢?”
映射兩個句子
indexed_tokens = tokenizer.encode(input_text1, input_text2)
print(“句子對的indexed_tokens:”, 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]
用0,1來區分第一條和第二條句子
segments_ids = [0]*11 + [1]*14
轉化張量形式
segments_tensors = torch.tensor([segments_ids])
tokens_tensor = torch.tensor([indexed_tokens])
使用帶有問答模型頭的預訓練模型獲得結果
with torch.no_grad():
start_logits, end_logits = qa_model(tokens_tensor, token_type_ids=segments_tensors)
print(“帶問答模型頭的模型輸出結果:”, (start_logits, end_logits))
print(“帶問答模型頭的模型輸出結果的尺寸:”, (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]
帶問答模型頭的模型輸出結果: (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的張量, 他們是兩條句子合并長度的概率分布,
第一個張量中最大值所在的索引代表答案出現的起始索引,
第二個張量中最大值所在的索引代表答案出現的終止索引.
帶問答模型頭的模型輸出結果的尺寸: (torch.Size([1, 25]), torch.Size([1, 25]))
小節總結
加載和使用預訓練模型的工具:
在這里我們使用torch.hub工具進行模型的加載和使用. 這些預訓練模型由世界先進的NLP研發團隊huggingface提供.
加載和使用預訓練模型的步驟:
第一步: 確定需要加載的預訓練模型并安裝依賴包.
第二步: 加載預訓練模型的映射器tokenizer.
第三步: 加載帶/不帶頭的預訓練模型.
第四步: 使用模型獲得輸出結果.
2.5 遷移學習實踐
學習目標
了解并掌握指定任務類型的微調腳本使用方法.
了解并掌握通過微調腳本微調后模型的使用方法.
掌握通過微調方式進行遷移學習的兩種類型實現過程.
指定任務類型的微調腳本:
huggingface研究機構向我們提供了針對GLUE數據集合任務類型的微調腳本, 這些微調腳本的核心都是微調模型的最后一個全連接層.
通過簡單的參數配置來指定GLUE中存在任務類型(如: CoLA對應文本二分類, MRPC對應句子對文本二分類, STS-B對應句子對文本多分類), 以及指定需要微調的預訓練模型.
指定任務類型的微調腳本使用步驟
第一步: 下載微調腳本文件
第二步: 配置微調腳本參數
第三步: 運行并檢驗效果
第一步: 下載微調腳本文件
克隆huggingface的transfomers文件
git clone https://github.com/huggingface/transformers.git
進行transformers文件夾
cd transformers
安裝python的transformer工具包, 因為微調腳本是py文件.
pip install .
當前的版本可能跟我們教學的版本并不相同,你還需要執行:
pip install transformers==2.3.0
進入微調腳本所在路徑并查看
cd examples
ls
其中run_glue.py就是針對GLUE數據集合任務類型的微調腳本
注意:
對于run_glue.py,由于版本變更導致,請通過該地址http://git.itcast.cn/Stephen/AI-key-file/blob/master/run_glue.py復制里面的代碼,覆蓋原有內容。
第二步: 配置微調腳本參數
在run_glue.py同級目錄下創建run_glue.sh文件, 寫入內容如下:
定義DATA_DIR: 微調數據所在路徑, 這里我們使用glue_data中的數據作為微調數據
export DATA_DIR="…/…/glue_data"
定義SAVE_DIR: 模型的保存路徑, 我們將模型保存在當前目錄的bert_finetuning_test文件中
export SAVE_DIR="./bert_finetuning_test/"
使用python運行微調腳本
–model_type: 選擇需要微調的模型類型, 這里可以選擇BERT, XLNET, XLM, roBERTa, distilBERT, ALBERT
–model_name_or_path: 選擇具體的模型或者變體, 這里是在英文語料上微調, 因此選擇bert-base-uncased
–task_name: 它將代表對應的任務類型, 如MRPC代表句子對二分類任務
–do_train: 使用微調腳本進行訓練
–do_eval: 使用微調腳本進行驗證
–data_dir: 訓練集及其驗證集所在路徑, 將自動尋找該路徑下的train.tsv和dev.tsv作為訓練集和驗證集
–max_seq_length: 輸入句子的最大長度, 超過則截斷, 不足則補齊
–learning_rate: 學習率
–num_train_epochs: 訓練輪數
–output_dir $SAVE_DIR: 訓練后的模型保存路徑
–overwrite_output_dir: 再次訓練時將清空之前的保存路徑內容重新寫入
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
輸出效果:
最終打印模型的驗證結果:
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的文件內容:
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代表模型參數,可以使用torch.load加載查看;
traning_args.bin代表模型訓練時的超參,如batch_size,epoch等,仍可使用torch.load查看;
config.json是模型配置文件,如多頭注意力的頭數,編碼器的層數等,代表典型的模型結構,如bert,xlnet,一般不更改;
added_token.json記錄在訓練時通過代碼添加的自定義token對應的數值,即在代碼中使用add_token方法添加的自定義詞匯;
special_token_map.json當添加的token具有特殊含義時,如分隔符,該文件存儲特殊字符的及其對應的含義,使文本中出現的特殊字符先映射成其含義,之后特殊字符的含義仍然使用add_token方法映射。
checkpoint: 若干步驟保存的模型參數文件(也叫檢測點文件)。
通過微調腳本微調后模型的使用步驟
第一步: 在https://huggingface.co/join上創建一個帳戶
第二步: 在服務器終端使用transformers-cli登陸
第三步: 使用transformers-cli上傳模型并查看
第四步: 使用pytorch.hub加載模型進行使用
第一步: 在https://huggingface.co/join上創建一個帳戶
如果由于網絡原因無法訪問, 我們已經為你提供了默認賬戶
username: ItcastAI
password: ItcastAI
avatar
第二步: 在服務器終端使用transformers-cli登陸
在微調模型的服務器上登陸
使用剛剛注冊的用戶名和密碼
默認username: ItcastAI
默認password: ItcastAI
$ transformers-cli login
第三步: 使用transformers-cli上傳模型并查看
使用transformers-cli upload命令上傳模型
選擇正確的微調模型路徑
$ transformers-cli upload ./bert_finetuning_test/
查看上傳結果
$ 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模型中的間隔(結束)符號的數值映射
mark = 102
找到第一個102的索引, 即句子對的間隔符號
k = index.index(mark)
句子對分割id列表, 由0,1組成, 0的位置代表第一個句子, 1的位置代表第二個句子
segments_ids = [0](k + 1) + [1](len(index) - k - 1)
轉化為tensor
tokens_tensor = torch.tensor([index])
segments_tensors = torch.tensor([segments_ids])
使用評估模式
with torch.no_grad():
# 使用模型預測獲得結果
result = model(tokens_tensor, token_type_ids=segments_tensors)
# 打印預測結果以及張量尺寸
print(result)
print(result[0].shape)
輸出效果:
(tensor([[-0.0181, 0.0263]]),)
torch.Size([1, 2])
通過微調方式進行遷移學習的兩種類型
類型一: 使用指定任務類型的微調腳本微調預訓練模型, 后接帶有輸出頭的預定義網絡輸出結果.
類型二: 直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網絡進行微調輸出結果.
說明: 所有類型的實戰演示, 都將針對中文文本進行.
類型一實戰演示
使用文本二分類的任務類型SST-2的微調腳本微調中文預訓練模型, 后接帶有分類輸出頭的預定義網絡輸出結果. 目標是判斷句子的情感傾向.
準備中文酒店評論的情感分析語料, 語料樣式與SST-2數據集相同, 標簽0代表差評, 標簽1好評.
語料存放在與glue_data/同級目錄cn_data/下, 其中的SST-2目錄包含train.tsv和dev.tsv
train.tsv
sentence label
早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好,餐廳不分吸煙區.房間不分有無煙房. 0
去的時候 ,酒店大廳和餐廳在裝修,感覺大廳有點擠.由于餐廳裝修本來該享受的早飯,也沒有享受(他們是8點開始每個房間送,但是我時間來不及了)不過前臺服務員態度好! 1
有很長時間沒有在西藏大廈住了,以前去北京在這里住的較多。這次住進來發現換了液晶電視,但網絡不是很好,他們自己說是收費的原因造成的。其它還好。 1
非常好的地理位置,住的是豪華海景房,打開窗戶就可以看見棧橋和海景。記得很早以前也住過,現在重新裝修了。總的來說比較滿意,以后還會住 1
交通很方便,房間小了一點,但是干凈整潔,很有香港的特色,性價比較高,推薦一下哦 1
酒店的裝修比較陳舊,房間的隔音,主要是衛生間的隔音非常差,只能算是一般的 0
酒店有點舊,房間比較小,但酒店的位子不錯,就在海邊,可以直接去游泳。8樓的海景打開窗戶就是海。如果想住在熱鬧的地帶,這里不是一個很好的選擇,不過威海城市真的比較小,打車還是相當便宜的。晚上酒店門口出租車比較少。 1
位置很好,走路到文廟、清涼寺5分鐘都用不了,周邊公交車很多很方便,就是出租車不太愛去(老城區路窄愛堵車),因為是老賓館所以設施要陳舊些, 1
酒店設備一般,套房里臥室的不能上網,要到客廳去。 0
dev.tsv
sentence label
房間里有電腦,雖然房間的條件略顯簡陋,但環境、服務還有飯菜都還是很不錯的。如果下次去無錫,我還是會選擇這里的。 1
我們是5月1日通過攜程網入住的,條件是太差了,根本達不到四星級的標準,所有的東西都很陳舊,衛生間水龍頭用完竟關不上,浴缸的漆面都掉了,估計是十年前的四星級吧,總之下次是不會入住了。 0
離火車站很近很方便。住在東樓標間,相比較在九江住的另一家酒店,房間比較大。衛生間設施略舊。服務還好。10元中式早餐也不錯,很豐富,居然還有青菜肉片湯。 1
坐落在香港的老城區,可以體驗香港居民生活,門口交通很方便,如果時間不緊,坐叮當車很好呀!周圍有很多小餐館,早餐就在中遠后面的南北嚼吃的,東西很不錯。我們定的大床房,挺安靜的,總體來說不錯。前臺結賬沒有銀聯! 1
酒店前臺服務差,對待客人不熱情。號稱攜程沒有預定。感覺是客人在求他們,我們一定得住。這樣的賓館下次不會入住! 0
價格確實比較高,而且還沒有早餐提供。 1
是一家很實惠的酒店,交通方便,房間也寬敞,晚上沒有電話騷擾,住了兩次,有一次住501房間,洗澡間排水不暢通,也許是個別問題.服務質量很好,剛入住時沒有調好寬帶,服務員很快就幫忙解決了. 1
位置非常好,就在西街的街口,但是卻鬧中取靜,環境很清新優雅。 1
房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設備也不錯. 1
在run_glue.py同級目錄下創建run_cn.sh文件, 寫入內容如下:
定義DATA_DIR: 微調數據所在路徑
export DATA_DIR="…/…/cn_data"
定義SAVE_DIR: 模型的保存路徑, 我們將模型保存在當前目錄的bert_finetuning文件中
export SAVE_DIR="./bert_cn_finetuning/"
使用python運行微調腳本
–model_type: 選擇BERT
–model_name_or_path: 選擇bert-base-chinese
–task_name: 句子二分類任務SST-2
–do_train: 使用微調腳本進行訓練
–do_eval: 使用微調腳本進行驗證
–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
輸出效果:
最終打印模型的驗證結果, 準確率高達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的文件內容:
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命令上傳模型
選擇正確的微調模型路徑
$ 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():
# 使用模型預測獲得結果
result = model(tokens_tensor)
predicted_label = torch.argmax(result[0]).item()
return predicted_label
if name == “main”:
# text = “早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好”
text = “房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設備也不錯.”
print(“輸入文本為:”, text)
print(“預測標簽為:”, get_label(text))
輸出效果:
輸入文本為: 早餐不好,服務不到位,晚餐無西餐,早餐晚餐相同,房間條件不好
預測標簽為: 0
輸入文本為: 房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設備也不錯.
預測標簽為: 1
類型二實戰演示
直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網絡進行微調輸出結果.
使用語料和完成的目標與類型一實戰相同.
直接加載預訓練模型進行輸入文本的特征表示:
import torch
進行句子的截斷補齊(規范長度)
from keras.preprocessing import sequence
source = ‘huggingface/pytorch-transformers’
直接使用預訓練的bert中文模型
model_name = ‘bert-base-chinese’
通過torch.hub獲得已經訓練好的bert-base-chinese模型
model = torch.hub.load(source, ‘model’, model_name)
獲得對應的字符映射器, 它將把中文的每個字映射成一個數字
tokenizer = torch.hub.load(source, ‘tokenizer’, model_name)
句子規范長度
cutlen = 32
def get_bert_encode(text):
“”"
description: 使用bert-chinese編碼中文文本
:param text: 要進行編碼的文本
:return: 使用bert編碼后的文本張量表示
“”"
# 首先使用字符映射器對每個漢字進行映射
# 這里需要注意, bert的tokenizer映射后會為結果前后添加開始和結束標記即101和102
# 這對于多段文本的編碼是有意義的, 但在我們這里沒有意義, 因此使用[1:-1]對頭和尾進行切片
indexed_tokens = tokenizer.encode(text[:cutlen])[1:-1]
# 對映射后的句子進行截斷補齊
indexed_tokens = sequence.pad_sequences([indexed_tokens], cutlen)
# 之后將列表結構轉化為tensor
tokens_tensor = torch.LongTensor(indexed_tokens)
# 使模型不自動計算梯度
with torch.no_grad():
# 調用模型獲得隱層輸出
encoded_layers, _ = model(tokens_tensor)
# 輸出的隱層是一個三維張量, 最外層一維是1, 我們使用[0]降去它.
encoded_layers = encoded_layers[0]
return encoded_layers
調用:
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])
自定義單層的全連接網絡作為微調網絡:
根據實際經驗, 自定義的微調網絡參數總數應大于0.5倍的訓練數據量, 小于10倍的訓練數據量, 這樣有助于模型在合理的時間范圍內收斂.
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
“”“定義微調網絡的類”""
def init(self, char_size=32, embedding_size=768):
“”"
:param char_size: 輸入句子中的字符數量, 即輸入句子規范后的長度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)
調用:
if name == “main”:
# 隨機初始化一個輸入參數
x = torch.randn(1, 32, 768)
# 實例化網絡結構, 所有參數使用默認值
net = Net()
nr = net(x)
print(nr)
輸出效果:
tensor([[0.3279, 0.2519]], grad_fn=)
構建訓練與驗證數據批次生成器:
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: 從持久化文件中加載數據
:param train_data_path: 訓練數據路徑
:param valid_data_path: 驗證數據路徑
:param batch_size: 訓練和驗證數據集的批次大小
:return: 訓練數據生成器, 驗證數據生成器, 訓練數據數量, 驗證數據數量
“”"
# 使用pd進行csv數據的讀取, 并去除第一行的列名
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])
調用:
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)
輸出效果:
訓練數據集的正負樣本數量:
{‘0’: 1518, ‘1’: 1442}
驗證數據集的正負樣本數量:
{‘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
編寫訓練和驗證函數:
import torch.optim as optim
def train(train_data_labels):
“”"
description: 訓練函數, 在這個過程中將更新模型參數, 并收集準確率和損失
:param train_data_labels: 訓練數據和標簽的生成器對象
:return: 整個訓練過程的平均損失之和以及正確標簽的累加數
“”"
# 定義訓練過程的初始損失和準確率累加數
train_running_loss = 0.0
train_running_acc = 0.0
# 循環遍歷訓練數據和標簽生成器, 每個批次更新一次模型參數
for train_tensor, train_labels in train_data_labels:
# 初始化該批次的優化器
optimizer.zero_grad()
# 使用微調網絡獲得輸出
train_outputs = net(train_tensor)
# 得到該批次下的平均損失
train_loss = criterion(train_outputs, train_labels)
# 將該批次的平均損失加到train_running_loss中
train_running_loss += train_loss.item()
# 損失反向傳播
train_loss.backward()
# 優化器更新模型參數
optimizer.step()
# 將該批次中正確的標簽數量進行累加, 以便之后計算準確率
train_running_acc += (train_outputs.argmax(1) == train_labels).sum().item()
return train_running_loss, train_running_acc
def valid(valid_data_labels):
“”"
description: 驗證函數, 在這個過程中將驗證模型的在新數據集上的標簽, 收集損失和準確率
:param valid_data_labels: 驗證數據和標簽的生成器對象
:return: 整個驗證過程的平均損失之和以及正確標簽的累加數
“”"
# 定義訓練過程的初始損失和準確率累加數
valid_running_loss = 0.0
valid_running_acc = 0.0
# 循環遍歷驗證數據和標簽生成器
for valid_tensor, valid_labels in valid_data_labels:
# 不自動更新梯度
with torch.no_grad():
# 使用微調網絡獲得輸出
valid_outputs = net(valid_tensor)
# 得到該批次下的平均損失
valid_loss = criterion(valid_outputs, valid_labels)
# 將該批次的平均損失加到valid_running_loss中
valid_running_loss += valid_loss.item()
# 將該批次中正確的標簽數量進行累加, 以便之后計算準確率
valid_running_acc += (valid_outputs.argmax(1) == valid_labels).sum().item()
return valid_running_loss, valid_running_acc
調用并保存模型:
if name == “main”:
# 設定數據路徑
train_data_path = “./cn_data/SST-2/train.tsv”
valid_data_path = “./cn_data/SST-2/dev.tsv”
# 定義交叉熵損失函數
criterion = nn.CrossEntropyLoss()
# 定義SGD優化方法
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
# 定義訓練輪數
epochs = 4
# 定義批次樣本數量
batch_size = 16
# 進行指定輪次的訓練
for epoch in range(epochs):
# 打印輪次
print(“Epoch:”, epoch + 1)
# 通過數據加載器獲得訓練數據和驗證數據生成器, 以及對應的樣本數量
train_data_labels, valid_data_labels, train_data_len,
valid_data_len = data_loader(train_data_path, valid_data_path, batch_size)
# 調用訓練函數進行訓練
train_running_loss, train_running_acc = train(train_data_labels)
# 調用驗證函數進行驗證
valid_running_loss, valid_running_acc = valid(valid_data_labels)
# 計算每一輪的平均損失, train_running_loss和valid_running_loss是每個批次的平均損失之和
# 因此將它們乘以batch_size就得到了該輪的總損失, 除以樣本數即該輪次的平均損失
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’
# 加載模型參數
net.load_state_dict(torch.load(MODEL_PATH))
輸出效果:
輸入文本為: 房間應該超出30平米,是HK同級酒店中少有的大;重裝之后,設備也不錯.
預測標簽為: 1
輸入文本為: 酒店設備一般,套房里臥室的不能上網,要到客廳去。
預測標簽為: 0
小節總結
學習了指定任務類型的微調腳本:
huggingface研究機構向我們提供了針對GLUE數據集合任務類型的微調腳本, 這些微調腳本的核心都是微調模型的最后一個全連接層.
通過簡單的參數配置來指定GLUE中存在任務類型(如: CoLA對應文本二分類, MRPC對應句子對文本二分類, STS-B對應句子對文本多分類), 以及指定需要微調的預訓練模型.
學習了指定任務類型的微調腳本使用步驟:
第一步: 下載微調腳本文件
第二步: 配置微調腳本參數
第三步: 運行并檢驗效果
學習了通過微調腳本微調后模型的使用步驟:
第一步: 在https://huggingface.co/join上創建一個帳戶
第二步: 在服務器終端使用transformers-cli登陸
第三步: 使用transformers-cli上傳模型并查看
第四步: 使用pytorch.hub加載模型進行使用
學習了通過微調方式進行遷移學習的兩種類型:
類型一: 使用指定任務類型的微調腳本微調預訓練模型, 后接帶有輸出頭的預定義網絡輸出結果.
類型二: 直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網絡進行微調輸出結果.
學習了類型一實戰演示:
使用文本二分類的任務類型SST-2的微調腳本微調中文預訓練模型, 后接帶有分類輸出頭的預定義網絡輸出結果. 目標是判斷句子的情感傾向.
準備中文酒店評論的情感分析語料, 語料樣式與SST-2數據集相同, 標簽0代表差評, 標簽1好評.
語料存放在與glue_data/同級目錄cn_data/下, 其中的SST-2目錄包含train.tsv和dev.tsv
學習了類型二實戰演示:
直接加載預訓練模型進行輸入文本的特征表示, 后接自定義網絡進行微調輸出結果.
上一頁第一章:fasttext工具的使用
?Copyright 2019, itcast.cn.
Made with Material for MkDocs
總結
以上是生活随笔為你收集整理的11111111111111111111的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lubuntu安装屏幕键盘onboard
- 下一篇: FPGA学习笔记_图像处理3_FPGA实