# Transformer Note
:::info
非文本內容的補充格式:
寫在文本翻譯之前
- 專有名詞、概念 1 [link](#) (此link for 大概念)
- 敘述 1 [link](#)(此link for 單一概念)
- 敘述 2
- 專有名詞、概念 2 [link](#)
- 敘述 1
- ...
:::
:::danger
有看不懂、有疑義的地方,請用
"::: danger"
":::"
包住,如此段
:::
## 1 Introduction
:::spoiler 補充
- short-term memory
- 對於單一份data(example),可以記得序列前面的內容
- long-term memory
- 可以記得不同份data內的內容(accross example)
- 注意力機制 [link](https://medium.com/programming-with-data/28-%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%A9%9F%E5%88%B6-attention-mechanism-f3937f289023)
- 然後根據symbol向量與Question向量的相關度(點積值等等),決定與該symbol的權重
- 再把每個symbol的向量做加權相加(有時候會再除以向量數做平均)(避免RNN的位置問題,只與相關度有關)
- RNN
- 
:::
RNN跟GRU(優化記憶方式的RNN)已經有很大的發展,他們通常根據symbol位置來分解資料成sequence,用這種序列化的方式做輸入輸出
但這種方式因為不支援平行的輸入輸出,所以對於long-term memory很難有好表現(越遠的context權重越低,類似股票的KD線吧)
注意力機制可以不管資料在sequence中的位置
然而注意力機制通常仍是跟RNN一起使用(輸入或許有用到注意力,但輸出仍是遞迴方式考慮前一個輸出值)(所以transformer最大的改變,就是multihead且連輸出也用注意力)
這篇paper提出的Transformer避免使用像RNN的遞迴方式,也避免使用CNN的卷積方式,而是完全依賴注意力機制,可以達到更好的平行運算,也可以減少大量的訓練時間。
本篇paper的兩組翻譯實驗都有顯著的結果。
Transformer 能夠在僅僅使用八塊 P100 GPU ,且訓練 12 個小時的情況下就能達到翻譯質量的最新技術水平。
## 2 Background
為了減少序列運算(避免遠處被忽略),有很多模型(見論文)被提出,但是這些模型還是會受到signal距離(N)的限制,運算量少到O(N),O(log(N))有少但不多
Transformer則可以直接把他變成O(1)的常數,雖然會因為平均注意力權重降低resolution效率就是了,但這問題在3.2會提到怎麼解決
自注意力(Self-attention)是對於sequence中的signal距離的注意力機制。
目前自注意力有成功被運用的例子有:
* 閱讀理解
* 抽象摘要 Abstractive summarization
* 文本蘊涵
* 學習與任務無關的句子表示
* 
端到端記憶網路End-to-end memory networks(包含encode, memory, decoder)是基於遞迴注意力機制(把很多注意力機制疊在一起),而非序列遞迴(RNN那個)。在簡單語言問答和語言建模任務上都有良好的表現。
Transformer是第一個完全依賴注意來計算其輸入和輸出表示的轉換模型。
## 3 Model Architecture
:::spoiler 補充
- point-wise(逐點)
- 一次只處理一個point,不與其他point相關
- 也可以指用1 * 1卷積核
:::
Encoder將符號表示的輸入序列(x1,…,xn)(離散的,ex: 字母)映射到連續表示的序列 z = (z1,…,zn)(映射到向量空間,所以連續)
給定 z,Decoder隨後生成一次生成一個符號的輸出序列(y1,…,ym)。
每一步,Transformer都是自我回歸的,也就是在生成下一個符號時,它會使用先前生成的符號作為additional input。
Transformer使用堆疊式(stacked)的自我注意力機制和point-wise的全連接層來遵循這種整體架構
### 3.1 Encoder and Decoder Stacks
:::spoiler 補充
- residual connection(殘差連接) [link](https://blog.csdn.net/weixin_42253689/article/details/110450298)
- 假設一個layer輸入x輸出H(x), x -> H(x)
- Residual殘差: F(x) = H(x) - x, 也就是輸出與輸入的差異
- 殘差連接的重點在於,H(x) = F(x) + x,讓layer學習到的東西是F(x),也就是學習殘差,然後再透過skip connection把輸入值x加回去
- 這是用來避免多層數下,梯度消失、梯度爆炸、網路退化的問題(詳見link)
:::

#### Encoder:
左邊的部分,由N=6個identical layer疊在一起組成(stacked),每個區塊包含2個sublayer,一個multi-head self-attention layer(後面會講),一個point-wise全連接層(圖上的Feed Forward)
在sublayer之間有一個residual connection,為了讓殘差可以順利加上去,網路的輸入輸出都會固定在$d_{model}=512$的維度
Residual connection後還有layer normalization。這樣每一層sublayer的輸出會是 $LayerNorm(x+Sublayer(x))$
* $Sublayer(x)$ 是下一層(sublayer)使用的函數
$LayerNorm$就是把數字標準化,讓他服從常態分佈((x-mean)/SD)
#### Decoder:
右邊的部分,也是N=6個identical layer,但是有三個sublayer。基本上跟左邊只差在第二sublayer(中間那個),跟第一層的一些
第二個sublayer,一樣是multi-head self-attention,不過吃了encoder的輸出作為輸入。
第一層則是把multi-head self-attention改成masked multi-head self-attention,其實就是讓輸出的位置移動1格,保證第i個只會參照<i的位置
### 3.2 Attention
Attention function是以query, set of pair(key,value)為參數,映射到output的函數
基本上是一種用於準確評估輸入序列的不同部分對於全局(global context)的重要性的一種機制
其中出現的變數都是向量
其中output的計算是藉由value乘上weight,而weight是由對應的key跟query算出來的
基本上就是用來計算query跟value關聯度,並給與加權的函數
可以讓計算時,相關度越高的signal(ex: 跟問題更相關的字詞),能有更高的權重
#### 3.2.1 Scaled Dot-Product Attention
input: keys: ${d_k}$, querys: ${d_k}$, values: ${d_v}$代表著輸入進去的key, query, value的總量
這個算式的關鍵在於,拿k跟q向量做點積,求其在向量空間的相關度,再除以$\sqrt{d_k}$(有點像是取平均的概念,因為矩陣相乘會導致數值被放大),然後丟進softmax變成0~1,再做為value的權重
在實務上,key跟value很常是同個東西(以字詞來說,value本身就是字詞映射到向量空間的向量,本來就可以拿來直接點積求相關度)
基本上計算時,會平行進行計算,所以會把向量放在一起變成矩陣Q,K,V
$K \in R^{tokens*d_k}$, $Q \in R^{tokens*d_k}$, $V \in R^{tokens*d_v}$

算式中,對於KQ做dot-product,利用他們在向量空間的的角度,來求他們的相似度
這裡的software對於矩陣中每個element做,出來的還是矩陣
soft-max得出的會是一個$R^{d_k * d_k}$的矩陣 ($d_{model}$即文字轉成向量的維度)
:::info
所以這樣的計算結果下,$d_k$一定要等於$d_v$才能做計算???
解決了,作者Ch6有提,如果不同的話,就不能用點積,而要用其他的更複雜的function,還有提到,讓他不同的話,效果會比較差
:::
常用的attention function: addititive與dot-product,dot-product是相對適合的,因為dot-product可以用矩陣方式來加速,但是additive不行,在實務上會更慢
而再{d_k}小的情況,additive跟dot-product的效果差不多,但{d_k}一大,additive就會明顯較好,可能是因為dot-product再高維度會加得太快,所以作者引入了$/\sqrt{d_K}$來減緩這問題

#### 3.2.2 Multi-Head Attention
比起把向量的維度全部設成$d_{model}$,作者發現經過線性投影(乘上一個權重,然後降維)之後會更好
作者對於向量做h次處理,每次稱為一個head
處理中,用學習過的線性投影(權重$W_i$來自於學習)成$d_k, d_v$會更好,接著,這些投影過後的向量,會輸出$d_v$的output,這樣
然後再把輸出串聯起來(concat),做最後一次線性投影,就會得到$維度d_{model}$的最終值
計算式如下:

每個head都是一個attention function,裡面包了乘上權重的三個向量矩陣
透過維度,可以看出,concat的方式,是把h個head($R^{d_v*d_v}$)橫向接起來,變成一個大的$R^{d_v*hd_v}$的矩陣,再去做最後一次線性投影成model中標準化的輸入輸出維度$d_{model}$
論文使用了h=8個(h是超參數)平行attention layer(亦可稱為heads)。每一個head,使用了$d_k=d_v=\dfrac{d_{model}}{h}=64$
因為每一個head的維度縮減,所以最後總運算時間(時間複雜度)和只使用一個head(也就是h=1)且完整維度的一樣,並且這h次會進行平行運算,可以讓運算效率比起直接算單個$d_{model}$head還高。

:::info
更正,這裡的W應該就是後面梯度下降要去學習的東西了
:::
#### 3.2.3 Applications of Attention in our Model
Transformer有三種不同的使用Multi-head attention方式:

1. 在編碼器-解碼器注意力層(Encoder-Decoder Attention Layer):
* decoder中的第二層
* 查詢(queries)來自前一個decoder layer
* 記憶鍵(memory keys)和值(values)來自encoder的輸出
* 這使得解碼器中的每個位置都可以關注輸入序列中的所有位置
* 這模仿了序列到序列模型中的典型編碼器-解碼器注意力機制
3. 在編碼器中的自我注意力層:
* 在自我注意力層中,所有的鍵、值和查詢都來自相同位置,也就是encoder中的前一層的輸出
* Encoder中的每個位置都可以關注(attend to)encoder輸入中的所有位置,讓輸出是參考過前後文的結果
* 主要目的是讓Decoder得到的輸入,每個位置其實都包含了全局的訊息
5. 在解碼器中的自我注意力層:
* 自我注意力層允許decoder中的每個位置關注decoder中包括該位置在內的所有位置,讓輸出是參考過前後文的結果(對於第一個decoder部件可能沒啥用,但對於後面2~6個就會有很大用處)
* 需要防止deocder中的左向信息流(sequence中,較後面(右)的資訊被較前面(左)的資訊使用到),以保持自回歸特性(auto-regressive property)
* 論文的實作方式是:通過點積注意力遮罩(把不合法(左向資訊)的值改掉,將其設置為-∞)
* 
### 3.3 Position-wise Feed-Forward Networks
逐點的全連接層,可以看做1 * 1捲積核的捲積層

max(0,...)即ReLU,所以可以看出,全連接層做的事是,線性變換->ReLU->線性變換
算式中可以看到分成$W_1$, $W_2$,也就是不同的線性變化會有不同的參數,帶來不一樣的學習成果(feature channel中不同的部分會被強調出來)
然後兩次線性變換(全連接層裡的兩層)用的kneral數不同,第一層用2048個kernel,所以會輸出feature channel 2048的向量,第二層則是用512個kernel,輸出512 feature channel的向量
所以過程會是512(input) -> 2048 -> 512(output),保持了整個model都在$d_{model}$的維度
### 3.4 Embeddings and Softmax
[參考link](https://zhuanlan.zhihu.com/p/372279569)
Embedding基本上,就是把資料變成可以輸入的向量,那一般來講方法會是讓字詞向量乘上一個學習過後的權重矩陣(就一般NLP那套)
在輸出成字詞的機率時,作者用的權重矩陣也是一樣的
基本上,這部分都是拿現成的東西來用,不過作者把那個現成的矩陣乘上了$\sqrt{d_{model}}$(蛤,這是為啥)
:::danger
乘上$\sqrt{d_{model}}$是為了可以和Positional Encoding 後的向量做相加嗎? 乘了$\sqrt{d_{model}}$之後,值也會介於-1和1之間
:::
### 3.5 Positional Encoding
model內沒有遞迴(RNN那套)或捲積的概念,只有用注意力機制找字詞相關性,但是輸入之間的位置關係還是很重要的(像文章在同個段落內的內容,會比較有相關性)
所以在輸入時,作者使用了positional encoding
[參考link](https://zhuanlan.zhihu.com/p/372279569)

透過不同週期的sin, cos,來確保不同的位置,在所有維度上,都不會有相同值,也就因此納入了位置的訊息

這個positional encoding得到的值,是直接加在向量上的
作者也試過,用學習的方式來做positional encoding
不過發現,用function做跟用學習做得到的結果差不太多,所以選用了function,就可以適應更長的sequence
在輸入的資料,帶有位置的資訊之後,model就會自己去學習出他們的關係了
## 4 Why Self-Attention
這章主要比較Self-Attention與recurrent、convolution方法之間,在對於sequence轉換的差別
比較的點有: 1. 每層的運算複雜度 2 可平行運算的數量(即找最少的序列運算) 3 long range depency的path length(即位置很遠時,要把它納入考量,需要的資源)
第3點是當時,其他sequence transduction模型最大的挑戰
以下是不同模型間的比較

Self-Attnetion(restrict)是只看附近r個position的資料,被限制後的模型
可以降低每層的運算量,但相對path len就會變長
除了這些,self-attention的可解釋性更高,可以看出不同的head學會了不同的任務,並且對於文句的文法、語意結構有有做出相關行為
剩下的不是很重要
## 5 Training
### 5.1 Training Data and Batching
WMT 2014 English-German dataset
WMT 2014 English-French dataset
### 5.2 Hardware and Schedule
one machine with 8 NVIDIA P100 GPUs
基本的model(用論文中提到的參數):
each training step(一個batch做完): 0.4s
train for 100,000 steps or 12 hours
大型model:
each training step(一個batch做完): 1s
train for 300,000 steps or 3.5 days


### 5.3 Optimizer
[關於各種optomizer](https://medium.com/%E9%9B%9E%E9%9B%9E%E8%88%87%E5%85%94%E5%85%94%E7%9A%84%E5%B7%A5%E7%A8%8B%E4%B8%96%E7%95%8C/%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92ml-note-sgd-momentum-adagrad-adam-optimizer-f20568c968db)
使用adam optomizer(會自動調整學習率,並參考以前變化的向量的梯度下降)
以下是超參數($\beta_1, \beta_2, \epsilon, warmup_step$),以及學習率設定的數據

學習率會先漸升再漸降,受warmup決定學習率的波型
:::danger
為什麼需要乘-0.5次方和-1.5次方?
by YouZhe: 我感覺這只是他們嘗試出來,結果比較好的,不然這個數字感覺不太能用數學去解釋
:::
### 5.4 Regularization
每個sublayer都有加上dropout(殘差連接之後,normalization之前)
enbedding跟positional encoding之後也有加上dropout
機率是$P_{dropout} = 0.1$
## 6 Results
### 6.1 Machine Translation
總之就是自賣自誇環節,在WMT 2014 English-to-German translation task第一名
### 6.2 Model Variations
在講調不同參數的結果,基本上就是圖呈現的(以英翻德為例)

[link](https://blog.csdn.net/vivi_cin/article/details/134808955)
BLEU(bilingual evaluation understudy): 越接近大代表翻譯的越好,基於Precision,也就是輸出中,正確結果比重越高越好(越少錯辭、冗言贅字)
公式:

[link](https://medium.com/nlp-tsupei/perplexity%E6%98%AF%E4%BB%80%E9%BA%BC-426f52897513)
PPL(Perplexity): 困惑度,越小越好,代表對於model輸出結果的信心(機率多高),公式中的$l$其實就是cross-entropy function(把機率視為平等後的結果)
公式:

## 7 Conclusion
在翻譯方面,Transformer的訓練速度比基於循環或卷積層的架構要快得多。
在WMT 2014英德翻譯和WMT 2014英法翻譯任務中,Transformer都取得了新的技術水平。
作者打算將Transformer擴展到涉及文本以外的輸入和輸出模式的問題,並研究局部、受限的注意機制,以有效處理諸如圖像、音頻和視頻之類的大型輸入和輸出。
使生成變得不那麼順序化是他們的另一個研究目標。