nlp中的经典深度学习模型(二)
attention和transformer都是面試重點。
文章目錄
- 3 seq2seq+Attention
- 3.1 Sequence to Sequence Model
- 3.1.2 模型介紹
- 3.1.2 模型訓練
- 3.2注意力機制
- 3.2.1介紹
- 3.2.1“Bahdanau” style attention
- 3.2.2“Luong” style attention
- 4 Transformer
- 4.1 Multi-head Attention
- 4.1.1 自注意力機制
- 4.1.2 自注意力機制加強版
- 4.1.3 Multi-head Attention
- 4.2 殘差鏈接
- 4.3 layer norm
- 4.4 前饋神經網絡以及后續操作
- 4.5解碼器部分
3 seq2seq+Attention
3.1 Sequence to Sequence Model
3.1.2 模型介紹
Sequence to Sequence Model解決y=f(x)的問題。
x是一個序列,y是一個序列。
最常應用于翻譯問題。
模型包含編碼器和解碼器2部分。
編碼器:輸入序列編碼為隱變量 。用RNN作為大體結構。得到一個隱變量h。
解碼器:auto-regressive自回歸解碼套路
對于一個序列使用前t-1個輸出,預測第t個輸出,這種方式稱為自回歸
模型中包含的參數
1 解碼器參數 θ1\theta_1θ1?
2 解碼器參數 θ2\theta_2θ2?
3 詞向量矩陣 θ3\theta_3θ3? ,隨機初始化(這個詞向量可以用skip-gram模型學出來的值嗎?)
4 h0′h_0'h0′?,h1′h_1'h1′?…映射到詞表上的那個矩陣 θ4\theta_4θ4?
3.1.2 模型訓練
- 要點1:模型是一個求條件概率的過程
y=F(x) 等價于 P(Y|X) 就是擬合了一個條件概率分布
P(Y∣X)=P(y1,y2...yn∣X)=P(y1∣X)P(y2∣y1,X)P(y3∣y1,y2,X)...=∏i=1nP(yi∣y1,y2...yi?1,X)P(Y|X) =P(y_1,y_2...y_n|X) = P(y_1|X)P(y_2|y_1,X)P(y_3|y_1,y_2,X)...=\prod_{i=1}^nP(y_i|y_1,y_2...y_{i-1},X)P(Y∣X)=P(y1?,y2?...yn?∣X)=P(y1?∣X)P(y2?∣y1?,X)P(y3?∣y1?,y2?,X)...=∏i=1n?P(yi?∣y1?,y2?...yi?1?,X)
預測y2: P(y2∣y1,h)=P(y2∣y1,X)P(y_2|y_1,h) = P(y2|y1,X)P(y2?∣y1?,h)=P(y2∣y1,X),hhh是由X決定的。
每一個時間步,做的是條件概率分布,做一個分類,損失函數交叉熵損失。所有時間的損失加起來就是整個loss。
- 要點2:輸入詞向量和輸出詞向量綁定
參數θ3\theta_3θ3?稱為輸入詞向量
參數θ4\theta_4θ4?稱為輸出詞向量
假如詞庫有10萬詞,詞向量的維度是100。
參數θ4\theta_4θ4?是一個10萬x100的矩陣,h0′h_0'h0′?是 一個100維的向量, θ4\theta_4θ4?xh0′h_0'h0′?=10萬維的向量,得到每個詞的概率分布。
參數θ3\theta_3θ3? 和參數θ4\theta_4θ4? 維度一樣。可以共享。可以降低計算量。 換句話說 輸入詞向量和輸出詞向量綁定。
- 要點3:teacher forcing
在第二個位置預測出一個錯誤的詞,怎么辦?
每次給下一階段的詞都是正確的詞,稱為teacher forcing
每次使用預測出來的詞給下一階段,稱為非teacher forcing 。這樣的模型具有糾錯功能
3.2注意力機制
3.2.1介紹
注意力機制是seq2seq帶給nlp最好的禮物。
上面模型的問題是,只有編碼器的最后一個輸出,作為解碼器的輸入。這樣會導致前面的輸入會忘記,影響力會低。
我們希望h1,h2,h3,h4h_1,h_2,h_3,h_4h1?,h2?,h3?,h4?都能參與到解碼器的計算中。這樣就需要給他們分配一個權重,那這個權重怎么學習呢?
我們把編碼器的輸出變量h1,h2,h3,h4h_1,h_2,h_3,h_4h1?,h2?,h3?,h4?稱為value。
把解碼器的每一步輸出hi′h_i'hi′?稱為query。
使用(query,key)對計算權重。key就是h1,h2,h3,h4h_1,h_2,h_3,h_4h1?,h2?,h3?,h4?。
上一步得到的權重與value(這里仍然是h1,h2,h3,h4h_1,h_2,h_3,h_4h1?,h2?,h3?,h4?)加權平均得到注意力輸出。
這樣的模式可以推廣到所有需要注意力模型的地方。
value通常是上一個階段的輸出,key和value是一樣的。
query通常是另外的一個向量。
使用 (query,key) 進行加權求和,得到的值作為權重,再對value進行加權求和。
這樣的話在decoder階段,每一步的輸入會有3個變量:編碼器經過注意力加權后的輸出h(這個時候的query是hi?1′h_{i-1}'hi?1′?),解碼器上一步的隱狀態hi?1′h_{i-1}'hi?1′?,上一步的輸出yi?1y_{i-1}yi?1?。
這里的公式可以參考第八課 RNN條件生成與Attention機制的2.2。
3.2.1“Bahdanau” style attention
論文:Dzmitry Bahdanau, KyungHyun Cho, Yoshua Bengio. Neural Machine Translation by Jointly Learning to Align and Translation
Bahdanau是注意力機制的一種計算方法,也是現在很多工具包中的實現方法。
輸入是X1,X2...XTX_1,X_2...X_TX1?,X2?...XT?,經過RNN之后得到多個隱狀態h1,h2,...hTh_1,h_2,...h_Th1?,h2?,...hT?。
我們使用這里的隱狀態作為key和value,使用解碼器的上一步隱狀態si?1s_{i-1}si?1?作為query。
如何計算第i步,每個隱狀態的權重呢?
P(yi∣y1,y2...yi?1,X)=g(yi?1,si,ci)P(y_i|y_1,y_2...y_{i-1},X) = g(y_{i-1},s_i,c_i)P(yi?∣y1?,y2?...yi?1?,X)=g(yi?1?,si?,ci?) 在計算第i步的輸出的時候,與上一步的輸出,這一步的隱狀態以及第i步的contex有關系。
si=f(si?1,yi?1,ci)s_i=f(s_{i-1},y_{i-1},c_i)si?=f(si?1?,yi?1?,ci?) 第i步的隱狀態是關于上一步的隱狀態,上一步的輸出以及第i步的contex的函數。
ci=∑j=1Txαijhjc_i=\sum_{j=1}^{T_x}\alpha_{ij}h_jci?=∑j=1Tx??αij?hj? 第i步的context是解碼器所有隱狀態的加權平均。
αij=exp(eij)∑j=1Txexp(eik)\alpha_{ij}=\dfrac{exp(e_{ij})}{\sum_{j=1}^{T_x}exp(e_{ik})}αij?=∑j=1Tx??exp(eik?)exp(eij?)?
eij=a(si?1,hj)e_{ij}=a(s_{i-1,h_j})eij?=a(si?1,hj??)
加權平均的參數αij\alpha_{ij}αij?是這樣計算的:解碼器上一步的隱狀態拼接hjh_jhj?得到一個2n維的向量,使用一個2nx1維度的矩陣乘以這個向量得到eije_{ij}eij?,對eije_{ij}eij?過softmax得到權重參數。
對上面的過程再做一次梳理:
當前處于解碼器中的第i步
在解碼器中上一步的隱狀態si?1s_{i-1}si?1?,上一步的輸出yi?1y_{i-1}yi?1?,這一步的上下文向量cic_ici?
在編碼器中的最后輸出的隱狀態為h1h_1h1?,h2h_2h2?,h3h_3h3?,h4h_4h4?
為了計算cic_ici?,需要使用注意力機制來解決。
value : h1h_1h1?,h2h_2h2?,h3h_3h3?,h4h_4h4?
query : si?1s_{i-1}si?1?
key : h1h_1h1?,h2h_2h2?,h3h_3h3?,h4h_4h4?
我們會使用(query,key)計算value的權重。對于其中第j個權重的計算方式是這樣的:
eij=a(si?1,hj)e_{ij}=a(s_{i-1,h_j})eij?=a(si?1,hj??) # 這里是將兩個向量拼接
αij=exp(eij)∑j=1Txexp(eik)\alpha_{ij}=\dfrac{exp(e_{ij})}{\sum_{j=1}^{T_x}exp(e_{ik})}αij?=∑j=1Tx??exp(eik?)exp(eij?)? #這里會保證權重和為1。這里Tx=4{T_x}=4Tx?=4
ci=∑j=1Txαijhjc_i=\sum_{j=1}^{T_x}\alpha_{ij}h_jci?=∑j=1Tx??αij?hj? #計算得到上下文向量,Tx=4{T_x}=4Tx?=4
si=f(si?1,yi?1,ci)s_i=f(s_{i-1},y_{i-1},c_i)si?=f(si?1?,yi?1?,ci?) #得到第i步的隱狀態
P(yi∣y1,y2...yi?1,X)=g(yi?1,si,ci)P(y_i|y_1,y_2...y_{i-1},X) = g(y_{i-1},s_i,c_i)P(yi?∣y1?,y2?...yi?1?,X)=g(yi?1?,si?,ci?) #得到第i步的輸出
3.2.2“Luong” style attention
在解碼器計算第i步的時候:
先用ht?1h_{t-1}ht?1?和yt?1y_{t-1}yt?1?計算得到hth_tht?,使用hth_tht?作為query。而在Bahdanau中是使用ht?1h_{t-1}ht?1?作為query的。
編碼器的隱狀態作為key和value。計算得到cic_ici?。
拼接cic_ici?和hth_tht?,作為輸入,去預測得到h~i\tilde{h}_ih~i?,再用h~i\tilde{h}_ih~i?預測得到yiy_iyi?。
這樣做的好處是,可以在解碼的時候堆疊很多層。讓解碼做得更好。
對(query,key)的處理,文章中提到了多種。
文章中還提供了local attention機制。隨著算力提升,這種策略也不再流行了。
4 Transformer
2017年某一天,有人提出將seq2seq中的RNN去掉,只留下attention。這樣的模型就是Transformer。
論文:Attention is All You Need
transformer由編碼器和解碼器兩部分構成。
這里有很重要的三種操作是Multi-head Attention、殘差鏈接和Add&Norm(層正則化)。
4.1 Multi-head Attention
Multi-head Attention是自注意力機制的一種特殊情況。
4.1.1 自注意力機制
自注意力機制是指注意力機制中的query不是別的向量,而是自己序列本身。
例如在學習x2x_2x2?的權重參數值時候,使用x2x_2x2?作為query,x1,x3,x4x_1,x_3,x_4x1?,x3?,x4?作為key和value。
對每個位置都計算得到權重參數,然后加權平均得到y2y_2y2?。
同理y3,y4,y1y_3,y_4,y_1y3?,y4?,y1?的計算也是一樣。
dkd_kdk?是embedding的維度。在歸一化之前會對每一個分數除以定值(embedding的維度開根號)。這樣可以讓softmax的分布更加平滑。
4.1.2 自注意力機制加強版
增強版的自注意力機制是
1 不使用x2x_2x2?作為query,而是先對x2x_2x2?做線性變換:Wqx2W_qx_2Wq?x2?,之后的向量作query。
2 x1,x3,x4x_1,x_3,x_4x1?,x3?,x4?不直接作為key和value,而是先做線性變換之后再做key和value。Wkx1W_kx_1Wk?x1?作為key,Wvx1W_vx_1Wv?x1?作為value。
其余步驟相同。
這樣的模型有更多的參數,模型性能也更加強大。
4.1.3 Multi-head Attention
在每一步計算的時候,對于向量映射之后再輸入到模型。例如xix_ixi?是一個100維的向量。h=5,那就是對query,key,value做5次映射,將其轉換到一個20維的空間。將query、key、value都做這樣的拆分。分別在5組向量上面做self-attention。得到5個20維的向量,然后拼接起來稱為一個100維的向量。
不同head的長度一樣,但是映射參數是不一樣的。
這5次映射參數不同。
公式如下:
輸入X,包含token embedding和position embedding
- 對X做變換
Qi=QWiQQ^i=QW^Q_iQi=QWiQ?,Ki=KWiKK^i=KW^K_iKi=KWiK?,Vi=VWiVV^i=VW^V_iVi=VWiV?
每一次映射不共享參數,每一次映射會有WiQ,WiK,WiV)W^Q_i,W^K_i,W^V_i)WiQ?,WiK?,WiV?)三個參數。
- 對多頭中的某一組做attention
Attention(Qi,Ki,Vi)=KiQiTdkViAttention(Q_i,K_i,V_i)=\dfrac{K_iQ_i^T}{\sqrt{d_k}}V_iAttention(Qi?,Ki?,Vi?)=dk??Ki?QiT??Vi?
headi=Attention(Qi,Ki,Vi)head_i=Attention(Q_i,K_i,V_i)headi?=Attention(Qi?,Ki?,Vi?)
h組并行計算
- 拼接之后輸出
MultiHead(Q,K,V)=Concat(head1,head2,...head5)MultiHead(Q,K,V)=Concat(head_1,head_2,...head_5)MultiHead(Q,K,V)=Concat(head1?,head2?,...head5?)
經過multi-head之后,得到h1,h2,h3,h4h_1,h_2,h_3,h_4h1?,h2?,h3?,h4?。
4.2 殘差鏈接
殘差鏈接是這樣的。
將輸入x加到multi-head的輸出h上。這樣可以加快訓練。
這一步得到的結果記為h1′,h2′,h3′,h4′h_1',h_2',h_3',h_4'h1′?,h2′?,h3′?,h4′?。
4.3 layer norm
層正則化,是對殘差鏈接的結果做正則化。
對h1′,h2′,h3′,h4′h_1',h_2',h_3',h_4'h1′?,h2′?,h3′?,h4′?這4個向量分別計算每個向量的均值μ\muμ和方差σ\sigmaσ。
γ\gammaγ和β\betaβ是共享的參數,在模型中需要訓練。
γ\gammaγ和β\betaβ可以在一定程度上抵消掉正則的操作。為什么正則了又要抵消呢?
這樣做可以讓每一個時間步的值更平均一些,差異不會特別大。
這一步的輸出是h1′′,h2′′,h3′′,h4′′h_1'',h_2'',h_3'',h_4''h1′′?,h2′′?,h3′′?,h4′′?。
4.4 前饋神經網絡以及后續操作
對于上一步的結果加一個前饋神經網絡。
FFN(x)=max(0,xW1+b1)W2+b2FFN(x) = max(0, xW_1 + b_1 )W_2 + b_2FFN(x)=max(0,xW1?+b1?)W2?+b2?
在每一個時間步會做一個y=F(x)的變化,得到另外的100維的向量。
對這一步的結果再加一個殘差鏈接和層正則化。
這樣就得到一個transformer block。
4.5解碼器部分
解碼器和編碼器差不多。
解碼器有一個master multi head attention。就是說在解碼的時候,每一個時間步只能看到它前面的狀態。例如在計算x2x_2x2?的參數時候,x2x_2x2?作為query,能作為key和value的只有x1x_1x1?。
還有一點不同是
這里是以解碼器的輸出作為key和value,這一時間步的輸出作為query計算attention。
假設兩層encoder+兩層decoder組成一個transformer block,其結構如下:
例如在t=3時刻,decoder的輸入有t=1,t=2時刻的輸出,先過一個self-attention+add & Formlalize,得到輸出output3output_3output3?
解碼器的輸出,作為key和value,output3output_3output3?作為query,做attention。
經過一個add & Formlalize。
做一層linear&softmax,輸出在這個時刻,在每個詞上的概率。
重點閱讀鏈接:
https://jalammar.github.io/illustrated-transformer/
中文翻譯
總結
以上是生活随笔為你收集整理的nlp中的经典深度学习模型(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: test blog
- 下一篇: 深度学习04-RNN