您當前的位置:首頁 > 攝影

深度學習 NLP-Transformer and variant (TF and 魔改s)

作者:由 郝琳傑 發表于 攝影時間:2020-11-15

1。 寫在前面

開胃菜

這一部分主要闡述,寫這篇文章的動機,所以是開胃菜。

1。 所謂“魔改”

實際工業界裡,很難在論文中找到 模型+資料 都直接符合需求的NLP model。如果要在某類task上開始一輪新的工作,最好在相似的任務上“魔改”操作。

2。 why and how

總的來說,新的paper經過學術界同行監督,總是會有新的進步,比如: - 1。模型效果、提高可解釋性 - 2。加速推理、減少引數量 - 3。更好地提取資料特徵 - 4。泛化地在領域內的任務中應用

如何去做呢? - 1。以史為鑑:關注task發展史,看前輩如何踩坑避障 - 2。關注SOTA:瞭解最新的架構設計和應用 - 3。總結:聽專家總結,梳理自己的知識體系

3。 正文預告

15-16年,RNN架構非常火爆。直到現在,我個人首選的sequence tagging任務model依然是

bi-lstm+crf

。無他,效果穩定,模型簡單。 然而,儘管後續LSTM、GRU、SRU都算作是RNN的衍生物,但統統都不能解決推理時間過長的問題(上線的痛,懂的自然懂!)。因為語言模型處理輸入:序列,天然的要求前後依賴。輸入就是那麼長,每個time step會順序地做計算,並行化:“不存在的”!

RNN架構先天不足:難以並行化處理序列輸入,因為後一個time step總是依賴於前一個time step的輸出作為輸入

而Transformer,本身在架構設計上就是奔著並行化的目標去的。如果讀者瞭解過CNN中卷積、池化的概念,應該就可以順暢理解:儘管二維資料比一維序列更加複雜,但在感受野並行處理的情況下,完美利用GPU,速度飛快。

深度學習 NLP-Transformer and variant (TF and 魔改s)

(扯遠了,為什麼Transformer處理序列資料也夠快,會重新開新文章說的~)

“天下苦Transformer久矣”(

這是萬能必備句式,劃重點

)!

今天這篇文章,會總結式的記錄幾個基於Transformer魔改的新架構,全是“當前浪”獻上的滿滿厚愛!

2。 正文

主食

1。 速覽Transformer

what‘s Transformer?

一言以蔽之:seq2seq model with self-attention

深度學習 NLP-Transformer and variant (TF and 魔改s)

Transformer的核心在最右側的兩張圖中,分別是被框起來的 encoder和decoder部分。

從左向右、從下向上的看:

1。 encoder

1。首先實際序列中的每個

char_i

,透過一個固定size的對映矩陣,轉換為某個固定維度的embedding向量

x_i

2。向量

x_i

經過一個矩陣變化得到

a_i=Wx_i

,而

a_i

再加上每個

char_i

的位置向量

e_i

就可以得到對encoder不斷迴圈部分的輸入了

3。紅色的self-attention網路:

深度學習 NLP-Transformer and variant (TF and 魔改s)

透過

[q_i k_i v_i]^{-1} = [W_q W_k W_v]^{-1}(a_i + e_i)

的運算將輸入序列中的每個

char_i

,轉換為三種描述,分別是:

query_i,key_i,value_i

透過每兩個位置的char間的query和key兩兩比較,度量出一個相關程度

\alpha_{1,j}

,然後 透過softmax得到

\hat \alpha_{1,j}

。即從全域性視野考察,最後確定輸出其他位置的輸入和1號位的相關程度。

最後以

\hat \alpha_{1,j}

為權重,將對應位置的

value_i

做weighted sum,就可以得到self-attention的輸出

b_i

,類似的所有位置都經過上述過程。

4。add: 普通的add; Norm:

layer Norm

,而不是batch Norm

5。藍色的 前饋神經網路:Fully connected network

2。 decoder

而decoder,又多增加了一個 交叉注意力機制(右下角masked multi-head self-attention的輸出中,最終只有Q接到了上層) - 而mask則是在文字向量化過程中,由於文字長度小於Fix_length的Padding部分,在Padding部分對應index的score設為-inf。最後的效果就是使得經過softmax之後,Padding部分給予的attention權重為近似0 - 這種類似的操作在Decoder部分也使用了,目的是為了Decoder只關注早於當前輸出位置的部分。

2。 Sandwich Transformers

1。 動機

可能單純為了想得到一個效果更好的transformer。self-attention特徵提取能力比較強,而網路偏底層的部分,恰好是特徵較為集中的地方。所以,“不如多疊幾層self-attention試試看?”。

2。 做法

“reorder” the sub-layer module,調整self-attention和fully connected層的順序。 可以看到s層:self-attention層向左靠攏,聚集在一起了;與之對應f層:fully connected layer靠右聚集;中間部分則不變化。

深度學習 NLP-Transformer and variant (TF and 魔改s)

3。 實驗

深度學習 NLP-Transformer and variant (TF and 魔改s)

4。 結論

深度學習 NLP-Transformer and variant (TF and 魔改s)

不需要更多引數、記憶體;簡單底層多疊的self-attention,中間正常結構,top多疊fully connected layer,此時表現會比baseline要好。

3。 Universal Transformer

1。動機

Transformer在翻譯、句法分析上表現很好;而一旦測試序列長於訓練資料,因為沒見過相對應position embedding 就沒有辦法了。而且從理論上說transformer不是圖靈完備的,不能做重複某些字串之類的工作(很難理解)。 所以universal transformer想要改進其表現,使用新穎高效的時間並行迴圈方式將標準 Transformer 擴充套件為計算通用(圖靈完備)模型,從而可在更廣泛的任務中產生更強的結果。

2。做法

深度學習 NLP-Transformer and variant (TF and 魔改s)

- universal transformer將模型建立在 Transformer 的並行結構上,以保持其快速的訓練速度。 - 使用用單一的時間並行迴圈的變換函的多次應用代替了 Transformer 中不同變換函式的固定堆疊(即,相同的學習轉換函式在多個處理步驟中被並行應用於所有符號,其中每個time step的輸出饋入到下一個time step中)。 - 關鍵在於,RNN 逐個符號(從左到右)處理序列,而 Universal Transformer 同時處理所有符號(像 Transformer 一樣),隨後使用self-attention機制在可變數量的情況下並行地對每個符號的解釋進行細化。 這種時間並行迴圈機制比 RNN 中使用的順序迴圈更快,也使得 Universal Transformer 比標準前饋 Transformer 更強大。

3。 大白話

transformer的self-attention如果疊六層,雖然每一層結構一致,但是其實權重是不一樣的。而universal transformer則是藉助RNN的時間權重共享思路,讓同一個網路重複的在縱向時間軸上計算多次。

Universal Transformer 不像 RNN 那樣,每次輸入一個字元的embedding來進行時間迴圈,而是並行地使用多個self-attention 迴圈重複地修改句子中每一個符號的embedding表示。

而且Universal Transformer使用自適應計算時間機制(adaptive computation time,ACT),使模型動態調整句子中每個位置的embedding表示在時間上迭代的次數。到達迭代次數後,下一輪直接進行復制即可。

4。 用圖說話

下圖中的postion代表了輸入句子中的每個字,而每個字向量都縱向的向上輸入到 所有的self-attention中,即每個self-attention仍然會獲取到全域性視野。

而每個self-attention中 不同位置會經過多少個time step是由ACT決定的,即多個time-step後有的self-attention網路權重可能就不會再更新了,會保持不變。

深度學習 NLP-Transformer and variant (TF and 魔改s)

4。 Residual Shuffle Exchange Network

1。 結論

深度學習 NLP-Transformer and variant (TF and 魔改s)

- 引數少 - 速度快 - 用exchange、shuffle來取代self-attention,獲取到遠處的資訊

2。 做法

深度學習 NLP-Transformer and variant (TF and 魔改s)

1。 如何shuffle? - perfect shuffle:就好像洗牌,每兩層switch unit就會把把輸入的資料,從中間拆成兩份(a1a2a3,b1b2b3),然後像洗牌一樣再疊成新的序列(a1b1a2b2a3b3)。

深度學習 NLP-Transformer and variant (TF and 魔改s)

2。 detail of Switch Unit

深度學習 NLP-Transformer and variant (TF and 魔改s)

輸入的兩個元素,如圖分別進入上下兩條通路: - 上面的通路,做的是一些非線性轉換

而u則像是一個forget gate,決定:1。 非線性變換資訊 2。 交換過的資訊有,分別有多少會被傳遞至下一組unit中

下面的通路,做一個 swapHalf ,看起來就像是“洗牌”

$\left(\left[\begin{array}{l} a \ b \end{array}\right],\left[\begin{array}{l} c \ d \end{array}\right]\right)=\left[\left[\begin{array}{l} a \ d \end{array}\right],\left[\begin{array}{l} c \ b \end{array}\right]\right]$

butterfly network

深度學習 NLP-Transformer and variant (TF and 魔改s)

實際中使用的是右圖,即對稱的butterfly network

新文章的改進結構

簡化了switch unit的計算。

深度學習 NLP-Transformer and variant (TF and 魔改s)

小的缺點

深度學習 NLP-Transformer and variant (TF and 魔改s)

如果輸入8個字,那麼只需要

log_2{8}=3

層就可以 完成完全的位置交換。那整個結構就只需要

nlogn

就可以完全模擬self-attention結果了。 然而缺點是 序列長度必須要向上對齊到

2^n

3。 引數量對比

跟所需要的引數量相比,他的效能已經很好

在同樣的GPU Memory下,可以處理更長的序列;相同長度序列下,需要的時間卻更短

深度學習 NLP-Transformer and variant (TF and 魔改s)

深度學習 NLP-Transformer and variant (TF and 魔改s)

5。 Bert

BERT: bidirectional encoder representations from transformers

深度學習 NLP-Transformer and variant (TF and 魔改s)

從全稱中就已經可以明確得到指示:bert 就是把transformer中的decoder部分拿出來,透過預訓練得到一組真正有效的embedding表示。

深度學習 NLP-Transformer and variant (TF and 魔改s)

1。 masked LM

讓bert做完形填空 mask掉一些字元,根據對應位置的字向量輸出,後接簡單線性多分類器進行預測。

因為分類器能力很弱,所以要分類正確,那麼字向量要足夠的好

深度學習 NLP-Transformer and variant (TF and 魔改s)

2。 NSP:next sentence predication

預測兩個句子是否有上下文的關係 - nsp訓練一個分類器:預測兩個句子是否應該接在一起

bert 的內部是transformer——“天涯若比鄰”,所以cls安置在句子的開頭還是結尾完全是沒有差別的

深度學習 NLP-Transformer and variant (TF and 魔改s)

6。 ALBERT

1。 動機

降低引數消耗

2。 做法

bert vs albert: “a light bert”

簡化版bert: 每一層的weight都是share同一組引數的

深度學習 NLP-Transformer and variant (TF and 魔改s)

reduce embedding矩陣 使用(id, embedding)維度的矩陣,來編碼每一個字。實際輸入某個字時,網路使用id查詢對應的embedding。而這裡可以透過矩陣乘法,“時間換空間” 的將embedding的維度降低。

深度學習 NLP-Transformer and variant (TF and 魔改s)

多層self-attention layer共享引數

深度學習 NLP-Transformer and variant (TF and 魔改s)

參考albert的網路結構和引數資訊,看到確認到因為albert是多層引數共享的,所以引數量不會隨著層數增加而變化,只隨著hidden size改變而變化。

3。 pretrain

ALBERT:預訓練的task在NSP中有所差異

如果AB是合法的句子順序,那麼BA則作為反例輸入訓練集。

深度學習 NLP-Transformer and variant (TF and 魔改s)

BERT的NSP任務實際上是一個二分類,訓練資料的正樣本是透過取樣同一個文件中的兩個連續的句子,而負樣本是透過採用兩個不同的文件的句子。

NSP(Next Sentence Prediction):下一句預測, 正樣本=上下相鄰的2個句子,負樣本=隨機2個句子

在ALBERT中,為了只保留一致性任務去除主題識別的影響,提出了一個新的任務 sentence-order prediction(SOP)。 SOP (Sentence ):句子順序預測,正樣本=正常順序的2個相鄰句子,負樣本=調換順序的2個相鄰句子

對於NLI自然語言推理任務。研究發現NSP任務效果並不好,主要原因是因為其任務過於簡單。

NSP其實包含了兩個子任務,主題預測與關係一致性預測,但是主題預測相比於關係一致性預測簡單太多了。

因為只要模型發現兩個句子的主題不一樣就行了,而SOP預測任務能夠讓模型學習到更多的資訊。SOP因為是在同一個文件中選的,其只關注句子的順序並沒有主題方面的影響。

7。 Reformer

1。 multi-head

google對attention機制的完善。就是把Q,K,V透過引數矩陣對映一下,然後再做Attention,把這個過程重複做h次,結果拼接起來就行了,可謂“大道至簡”。

PS:這個應該在transfomer裡講的,忘記了。

深度學習 NLP-Transformer and variant (TF and 魔改s)

深度學習 NLP-Transformer and variant (TF and 魔改s)

2。 改進

可逆神經網路,將只需要儲存一層的啟用結果即可,N的因素消失了。

分塊計算前饋全連線層,節省記憶體。

採用區域性敏感雜湊技術,近似計算注意力,將時空開銷從O(L2)變為O(L)。

1。 Locality Sensitive Hashing Attention

reformer 針對長輸入序列做改進:LSH attention

因為self-attention內部QKV運算的空間複雜度是

n^2

,attention score的結果矩陣會迅速增大,但是其實並非所有的score都是重要的。

一個 query 和其他的所有的token的計算 attention score主要是取決於高相似度的幾個tokens之間,那麼就針對這裡做改進。

兩個新概念:

Shared-QK Transformer

在標準Transformer中,Q,K,V是由啟用結果A分別透過三個線性層對映得到。 但是這裡引入了LSH attention,我們需要Q和K是相同的(備註:其實這裡讓Q和K相同並不是LSH必須,LSH只需要讓Q、K變成單位向量即可,因為要在單位球面上進行相似查詢,本文讓Q和K一樣只是為了方便批處理,加速計算),讓Q和K透過相同的線性對映即可實現該目的。 我們稱這樣的模型為shared-QK Transformer,實驗結果表明共享Q、K並沒有影響Transformer的表現效果。

LSH attention

正如上面介紹的,我們每一次只計算一個qi和K的結果,但是我們需要和K中的每一個元素都計算嗎?其實不是,我們只需要關心與qi相近的keys即可,K中的每一個元素從宏觀上理解就是一個word。假設K的長度為64K,也就是有64K個tokens,我們只需要考慮其中的32或者64個最近的keys,那效率將大大提升。如何得到這最近的keys呢?利用Locality sensitive hashing就可以實現,它的基本思路就是距離相近的向量能夠很大機率hash到一個桶內,而相距較遠的向量hash到一個桶內的機率極低。

深度學習 NLP-Transformer and variant (TF and 魔改s)

使用hash函式的分桶策略,要求attend之後靠近在一起的幾個query-key score分在一個bucket中,然後在bucket內部進行self-attention。

hash function:

h(x)=\operatorname{argmax}[x R ;-x R]

其中:x是

d_k

維度的query or key,R是

\left[d_{k}, \frac{b}{2}\right]

大小的變換矩陣,而b是目標bucket的數量。

說明

右邊圖中,黑點代表在self-attention後softmax中占主導地位的score - a:屬於普通encoder的圖,因為decoder中

q_3

不能向前attend到

k_6

上去;而且可以明顯看到黑點分佈很稀疏,集中在幾組token之間 - b:將key-query hash到相同bucket後,對輸入先bucket排序,同個bucket內按照token 的 position排序 - c:b中藍色、綠色區域 key-query的分佈不均衡。為了減小bucket中q和k不均衡的問題,文章提出了保證透過令

k_{j}=\frac{q_{j}}{\left|q_{j}\right|}

從而使得

h\left(k_{j}\right)=h\left(q_{j}\right)

, 即使用了share-QK attention,得到圖c。因為Q=K,此時就能保證對角線都是attend to的,而且q和k在bucket中的個數一樣。同時因為同一個bucket中保證相似,所以同一個bucket都用小黑點高亮了。

- 我們注意到對角線的點為空心,這是因為我們雖然在正常實現上,我們的q會attend to本身位置的value。

- 但是在share-QK的實現下,如果attend to本身,會導致其值特別大,其他的值特別小,經過softmax之後,其他都是0,就自己本身是1。

- 所以為了避免這種情況,我們q不會去attend 自身位置的值,除非只有自己本身可以attend to(例如圖3/4的 q1 )

d: 極端情況,不同bucket中數量分佈不均衡。此時在操作c的基礎上進行chunk操作:對於bucket中的每個query,都可以attend to自己以及前一個bucket 中相同hash 值的key。如左邊圖的最後一行所表示,但每個輸入字不對自己進行attention

多輪LSH attention:

單個hash函式,總不可避免的會出現個別相近的items卻被分到不同的桶裡,多輪hash並行執行就可以避免。

總結下,過程就是:

首先我們令輸入序列的queries = keys

然後我們對其做LSH bucketing,得到每個query和key都在各自的bucket中(不同顏色表示)

我們跟根據bucket對query進行排序,同個bucket中,按照query原本的position進行排序。

在之後我們對於每個排序後的新序列,進行chunk 拆分

最後我們對於每個query只管制自己以及自己之前的chunk,對於這些候選集中相同bucket的key進行attend

假設輸入字是1024維度,現在每個bucket size變成32,複雜度由n方變為nlogn

2。 Reversible Layer

出發點:做誤差反傳時,每一層的權重、輸出都要在記憶體中做記錄,這其實佔據了很大的空間。這裡reversible layer要說的是,只要記住最後一層layer的資訊,來回推前面層的資訊就夠了。

“時間換空間”

在RevNet中,首先將輸入

x

copy為兩個部分

x_1

x_2

然後透過不同residual functions:

F(\cdot)

G(\cdot)

得到輸出

y_1

y_2

$\begin{array}{l} y_{1}=x_{1}+F\left(x_{2}\right) \ y_{2}=x_{2}+G\left(y_{1}\right) \end{array}

而反向計算時:

\begin{array}{l} x_{2}=y_{2}-G\left(y_{1}\right) \ x_{1}=y_{1}-F\left(x_{2}\right) \end{array}$

深度學習 NLP-Transformer and variant (TF and 魔改s)

F是fully connected的輸出,而g是Reversible layer的輸出。透過如上的操作,並行的存了兩份值,然後就可以相互作差、作和計算出前一層的輸出。

宣告:文章主體框架來自“李宏毅-深度學習”2020網路課程,文字、圖片部分包含了個人理解、講授內容和網路部落格。歡迎交流,時間倉促,請聯絡我!

標簽: Attention  self  Transformer  bucket  輸入