網(wǎng)站注冊怎么做北京seo排名優(yōu)化網(wǎng)站
文章目錄
- 0.卷積操作
- 1.注意力
- 1.1 注意力概述(Attention)
- 1.1.1 Encoder-Decoder
- 1.1.2 查詢、鍵和值
- 1.1.3 注意力匯聚: Nadaraya-Watson 核回歸
- 1.2 注意力評分函數(shù)
- 1.2.1 加性注意力
- 1.2.2 縮放點積注意力
- 1.3 自注意力(Self-Attention)
- 1.3.1 自注意力的定義和計算
- 1.3.2 自注意力的應用
- 1.3.3 Self-Attention 與 CNN 與 RNN
- 1.4 多頭自注意力 (Multihead Attention)
- 2. Transformer
- 2.1 Transformer的整體結構
- 2.2 Transformer的輸入
- 2.2.1 單詞Embedding
- 2.2.2 位置Encoding
- 2.3 Transformer的Encoder-Decoder
- 2.3.1 Encoder block
- 2.3.2 Decoder block
- 2.4 Transformer的輸出
- 2.5 Transformer的訓練過程和損失函數(shù)
- 2.5.1 訓練過程
- 2.5.2 損失函數(shù)
- 2.6 Transformer的代碼實現(xiàn)
- 2.6.1 基于位置的前饋神經(jīng)網(wǎng)絡
- 2.6.2 殘差連接和層規(guī)范化
- 2.6.3 編碼器
- 2.6.4 解碼器
- 2.6.5 訓練
- 3. pytorch中的注意力機制類
- 3.1 torch.nn.MultiheadAttention
- 4. Transformer 在計算機視覺領域的應用
- 4.1 Vision Transformer
- 4.1.1 ViT的總體結構
- 4.1.2 Embedding層結構詳解
- 4.1.3 Transformer Encoder詳解
- 4.1.4 MLP Head詳解
- 4.2 Swin Transformer
- 4.2.1 網(wǎng)絡的整體框架
- 4.2.2 Patch Mering
- 4.2.3 W-MSA
- 4.2.4 SW-MSA
- 參考文獻
0.卷積操作
深度學習中的卷積操作:https://blog.csdn.net/zyw2002/article/details/128306697
1.注意力
1.1 注意力概述(Attention)
1.1.1 Encoder-Decoder
Encoder-Decoder框架顧名思義也就是編碼-解碼框架,在NLP中Encoder-Decoder框架主要被用來處理序列-序列問題。也就是輸入一個序列,生成一個序列的問題。這兩個序列可以分別是任意長度。
具體到NLP中的任務比如:
- 文本摘要,輸入一篇文章(序列數(shù)據(jù)),生成文章的摘要(序列數(shù)據(jù))
- 文本翻譯,輸入一句或一篇英文(序列數(shù)據(jù)),生成翻譯后的中文(序列數(shù)據(jù))
- 問答系統(tǒng),輸入一個question(序列數(shù)據(jù)),生成一個answer(序列數(shù)據(jù))
基于Encoder-Decoder框架具體使用什么模型實現(xiàn),用的較多的應該就是seq2seq
模型和Transformer
了。
Encoder-Decoder中的輸入和輸出
輸入
1)輸入是一個向量
2)輸入是一組向量
輸出
1)每一個向量對應一個輸出
2)整個序列只輸出一個標簽
3)模型自己決定輸出序列的長度
Encoder-Decoder中的結構原理
Encoder:編碼器,對于輸入的序列<x1,x2,x3…xn>進行編碼,使其轉化為一個語義編碼C,這個C中就儲存了序列<x1,x2,x3…xn>的信息。
Encoder 是怎么編碼的呢?
編碼方式有很多種,在文本處理領域主要有RNN/LSTM/GRU/BiRNN/BiLSTM/BiGRU
,可以依照自己的喜好來選擇編碼方式
以RNN為例來具體說明一下:
以上圖為例,輸入<x1,x2,x3,x4>,通過RNN生成隱藏層的狀態(tài)值<h1,h2,h3,h4>,如何確定語義編碼C呢?最簡單的辦法直接用最后時刻輸出的ht作為C的狀態(tài)值,這里也就是可以用h4直接作為語義編碼C的值,也可以將所有時刻的隱藏層的值進行匯總,然后生成語義編碼C的值,這里就是C=q(h1,h2,h3,h4),q是非線性激活函數(shù)。
得到了語義編碼C之后,接下來就是要在Decoder中對語義編碼C進行解碼了。
Decoder:解碼器,根據(jù)輸入的語義編碼C,然后將其解碼成序列數(shù)據(jù),解碼方式也可以采用RNN/LSTM/GRU/BiRNN/BiLSTM/BiGRU
。
Decoder和Encoder的編碼解碼方式可以任意組合。
Decoder 是怎么解碼的呢?
基于
seq2seq
模型有兩種解碼方式:
解碼方法1:《Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation》
該方法指出,因為語義編碼C
包含了整個輸入序列的信息,所以在解碼的每一步都引入C
。文中Ecoder-Decoder均是使用RNN,在計算每一時刻的輸出yt時,都應該輸入語義編碼C
,即
類似的,下一個符號的條件分布是:
其中 h t h_t ht?為當前t時刻的隱藏層的值, y t ? 1 y_{t-1} yt?1?為上一時刻的預測輸出,作為t時刻的輸入,每一時刻的語義編碼C是相同地。
解碼方法2:《Sequence to Sequence Learning with Neural Networks》
這個編碼方式相對簡單,只在Decoder的初始輸入引入語義編碼C,將語義編碼C作為隱藏層狀態(tài)值 h 0 h_0 h0?的初始值,
如上圖,該模型讀取一個輸入句子“ABC”,并產(chǎn)生“WXYZ”作為輸出句子。模型在輸出句尾標記后停止進行預測。注意,LSTM讀取反向輸入句子,因為這樣做會在數(shù)據(jù)中引入許多短期依賴關系
基于
seq2seq
模型有兩種解碼方式都不太好(兩種解碼方式都只采用了一個語義編碼C),而基于attention
模型的編碼方式中采用了多個C
上圖就是引入了Attention 機制的Encoder-Decoder框架。咱們一眼就能看出上圖不再只有一個單一的語義編碼C,而是有多個C1,C2,C3這樣的編碼。當我們在預測Y1時,可能Y1的注意力是放在C1上,那咱們就用C1作為語義編碼,當預測Y2時,Y2的注意力集中在C2上,那咱們就用C2作為語義編碼,以此類推,就模擬了人類的注意力機制。
以機器翻譯例子"Tom chase Jerry" - "湯姆追逐杰瑞"來說明注意力機制:
當我們在翻譯"杰瑞"的時候,為了體現(xiàn)出輸入序列中英文單詞對于翻譯當前中文單詞不同的影響程度,比如給出類似下面一個概率分布值:
(Tom,0.3)(Chase,0.2)(Jerry,0.5)
每個英文單詞的概率代表了翻譯當前單詞“杰瑞”時,注意力分配模型分配給不同英文單詞的注意力大小。這對于正確翻譯目標語單詞肯定是有幫助的,因為引入了新的信息。同理,目標句子中的每個單詞都應該學會其對應的源語句子中單詞的注意力分配概率信息。這意味著在生成每個單詞Yi的時候,原先都是相同的中間語義表示C會替換成根據(jù)當前生成單詞而不斷變化的Ci。理解AM模型的關鍵就是這里,即由固定的中間語義表示C換成了根據(jù)當前輸出單詞來調(diào)整成加入注意力模型的變化的Ci。
每個Ci 對應這不同源語句子單詞的注意力分配概率,比如對于上面的英漢翻譯來說,對應的信息可能如下:
f2(“Tom”),f2(“Chase”),f2(“Jerry”)就是對應的隱藏層的值h(“Tom”),h(“Chase”),h(“Jerry”)。g函數(shù)就是加權求和。αi表示權值分布。因此Ci的公式就可以寫成:
怎么知道attention模型所需要的輸入句子單詞注意力分配概率分布值 a i j a_{ij} aij?呢? 我們可以通過下文介紹的注意力評分函數(shù)求得
1.1.2 查詢、鍵和值
下面來看看如何通過自主性的與非自主性的注意力提示, 用神經(jīng)網(wǎng)絡來設計注意力機制的框架。
首先,考慮一個相對簡單的狀況, 即只使用非自主性提示。 要想將選擇偏向于感官輸入, 則可以簡單地使用參數(shù)化的全連接層, 甚至是非參數(shù)化的最大匯聚層或平均匯聚層。
在注意力機制的背景下,自主性提示被稱為查詢(query)
。 給定任何查詢,注意力機制通過注意力匯聚(attention pooling)
將選擇引導至感官輸入(sensory inputs,例如中間特征表示)
。在注意力機制中,這些感官輸入被稱為值(value)
。 更通俗的解釋,每個值都與一個鍵(key)
配對, 這可以想象為感官輸入的非自主提示。
如上圖: 注意力機制通過注意力匯聚(注意力的分配方法)將查詢(自主性提示)和鍵(非自主性提示)結合在一起,實現(xiàn)對值(感官輸入)的選擇傾向。
1.1.3 注意力匯聚: Nadaraya-Watson 核回歸
上圖中的注意力匯聚
是怎么實現(xiàn)的呢?
可通過Nadaraya-Watson核回歸模型
來了解常見的注意力匯聚模型
(平均匯聚
、非參數(shù)注意力匯聚
、帶參數(shù)注意力匯聚
)。
為什么要在機器學習中引入注意力機制呢?
在全連接層,F(xiàn)C只能考慮相鄰的幾個數(shù)據(jù),但是無法考慮到整個序列。
注意力機制(self-attention)可以考慮到整個序列的信息。因此,輸出的向量帶有全局的上下文信息。
1.2 注意力評分函數(shù)
接下來,我們講解如何通過注意力評分函數(shù)來分配注意力。
我們使用高斯核來對查詢(query)和鍵(key)之間的關系建模。 我們可以將高斯核指數(shù)部分視為注意力評分函數(shù)(attention scoring function), 簡稱評分函數(shù)(scoring function)
,然后把這個函數(shù)的輸出結果輸入到softmax函數(shù)
中進行運算。 通過上述步驟,我們將得到與鍵對應的值的概率分布(即注意力權重)。最后,注意力匯聚的輸出就是基于這些注意力權重的值的加權和
。
下圖說明了如何將注意力匯聚的輸出計算成為值的加權和, 其中a表示注意力評分函數(shù)。 由于注意力權重是概率分布, 因此加權和其本質(zhì)上是加權平均值。
正如我們所看到的,選擇不同的注意力評分函數(shù)a會導致不同的注意力匯聚操作。 在本節(jié)中,我們將介紹兩個流行的評分函數(shù)(加性注意力、縮放點積注意力)
,稍后將用他們來實現(xiàn)更復雜的注意力機制
。
掩蔽softmax操作
掩蔽softmax操作, 是為實現(xiàn)下文的評分函數(shù)做鋪墊。
正如上面提到的,softmax操作用于輸出一個概率分布作為注意力權重。 在某些情況下,并非所有的值都應該被納入到注意力匯聚中。 例如,為了高效處理小批量數(shù)據(jù)集, 某些文本序列被填充了沒有意義的特殊詞元。 為了僅將有意義的詞元作為值來獲取注意力匯聚, 我們可以指定一個有效序列長度(即詞元的個數(shù)), 以便在計算softmax時過濾掉超出指定范圍的位置。 通過這種方式,我們可以在下面的masked_softmax
函數(shù)中 實現(xiàn)這樣的掩蔽softmax操作(masked softmax operation), 其中任何超出有效長度的位置都被掩蔽并置為0。
#@save
def masked_softmax(X, valid_lens):"""通過在最后一個軸上掩蔽元素來執(zhí)行softmax操作"""# X:3D張量,valid_lens:1D或2D張量if valid_lens is None:return nn.functional.softmax(X, dim=-1)else:shape = X.shapeif valid_lens.dim() == 1:valid_lens = torch.repeat_interleave(valid_lens, shape[1])else:valid_lens = valid_lens.reshape(-1)# 最后一軸上被掩蔽的元素使用一個非常大的負值替換,從而其softmax輸出為0X = d2l.sequence_mask(X.reshape(-1, shape[-1]), valid_lens,value=-1e6)return nn.functional.softmax(X.reshape(shape), dim=-1)
為了演示此函數(shù)是如何工作的, 考慮由兩個2×4矩陣表示的樣本, 這兩個樣本的有效長度分別為2和3。 經(jīng)過掩蔽softmax操作,超出有效長度的值都被掩蔽為0。
masked_softmax(torch.rand(2, 2, 4), torch.tensor([2, 3]))
tensor([[[0.5423, 0.4577, 0.0000, 0.0000],[0.6133, 0.3867, 0.0000, 0.0000]],[[0.3324, 0.2348, 0.4329, 0.0000],[0.2444, 0.3943, 0.3613, 0.0000]]])
同樣,我們也可以使用二維張量,為矩陣樣本中的每一行指定有效長度。
masked_softmax(torch.rand(2, 2, 4), torch.tensor([[1, 3], [2, 4]]))
tensor([[[1.0000, 0.0000, 0.0000, 0.0000],[0.4142, 0.3582, 0.2275, 0.0000]],[[0.5565, 0.4435, 0.0000, 0.0000],[0.3305, 0.2070, 0.2827, 0.1798]]])
1.2.1 加性注意力
#@save
class AdditiveAttention(nn.Module):"""加性注意力"""def __init__(self, key_size, query_size, num_hiddens, dropout, **kwargs):super(AdditiveAttention, self).__init__(**kwargs)self.W_k = nn.Linear(key_size, num_hiddens, bias=False)self.W_q = nn.Linear(query_size, num_hiddens, bias=False)self.w_v = nn.Linear(num_hiddens, 1, bias=False)self.dropout = nn.Dropout(dropout)def forward(self, queries, keys, values, valid_lens):queries, keys = self.W_q(queries), self.W_k(keys)# 在維度擴展后,# queries的形狀:(batch_size,查詢的個數(shù),1,num_hidden)# key的形狀:(batch_size,1,“鍵-值”對的個數(shù),num_hiddens)# 使用廣播方式進行求和features = queries.unsqueeze(2) + keys.unsqueeze(1)features = torch.tanh(features)# self.w_v僅有一個輸出,因此從形狀中移除最后那個維度。# scores的形狀:(batch_size,查詢的個數(shù),“鍵-值”對的個數(shù))scores = self.w_v(features).squeeze(-1)self.attention_weights = masked_softmax(scores, valid_lens)# values的形狀:(batch_size,“鍵-值”對的個數(shù),值的維度)return torch.bmm(self.dropout(self.attention_weights), values)
我們用一個小例子來演示上面的AdditiveAttention
類, 其中查詢、鍵和值的形狀為(批量大小,步數(shù)或詞元序列長度,特征大?。?, 實際輸出為(2,1,20)、(2,10,2)和(2,10,4)。 注意力匯聚輸出的形狀為(批量大小,查詢的步數(shù),值的維度)。
queries, keys = torch.normal(0, 1, (2, 1, 20)), torch.ones((2, 10, 2))
# values的小批量,兩個值矩陣是相同的
values = torch.