動手推導Self-Attention

2021-12-23 小白學視覺

點擊上方「小白學視覺」,選擇加"星標"或「置頂

重磅乾貨,第一時間送達

譯者: 在 medium 看到一篇文章從代碼的角度,作者直接用 pytorch 可視化了 Attention 的 QKV 矩陣,之前我對 self-Attention 的理解還是比較表面的,大部分時候也是直接就調用 API 來用, 看看原理也挺有意思的,作者同時製作了可在線運行的 colab作為演示,遂翻譯給大家一起看看:The illustrations are best viewed on Desktop. A Colab version can be found here, (thanks to Manuel Romero!).有人問在transformer模型的眾多派生BERT,RoBERTa,ALBERT,SpanBERT,DistilBERT,SesameBERT,SemBERT,SciBERT,BioBERT,MobileBERT,TinyBERT和CamemBERT有什麼共同點?我們的並不期待你回答都有字母"BERT"🤭.
事實上,答案是 Self-Attention🤗.我們不僅要談論「BERT」的架構,更正確地說是基於`Transformer架構。基於Transformer的架構主要用於對自然語言理解任務進行建模,避免使用神經網絡中的遞歸神經網絡,而是完全依賴Self-Attention機制來繪製輸入和輸出之間的全局依存關係。但是,這背後的數學原理是什麼?這就是我們今天要發掘的問題。這篇文章的主要內容是引導您完成Self-Attention模塊中涉及的數學運算。在本文結尾處,您應該能夠從頭開始編寫或編寫Self-Attention模塊。

本文的目的並不是為了通過提供不同的數字表示形式和數學運算來給出Self-attention的直觀解釋。它也不是為了證明:為什麼且如何在Transformers使用中Self-Attention(我相信那裡已經有很多東西了)。請注意,本文也沒有詳細介紹注意力和自我注意力之間的區別。


如果你認為自注意力機制類似於注意力機制,那麼恭喜你答對了,它們從根本上有很多相同的概念和許多常見的數學運算。

一個self-attention模塊輸入為 n,輸出也為 n.那麼在這個模塊內部發生了什麼?用門外漢的術語來說,self-attention機制允許輸入彼此之間進行交互(「self」)並找出它們應該更多關注的區域(「Attention」)。輸出是這些交互作用和注意力得分的總和。



例子分為以下步驟:

準備輸入

初始化權重

導出key, query and value的表示

計算輸入1 的注意力得分(attention scores)

計算softmax

將attention scores乘以value

對加權後的value求和以得到輸出1

Note:
 實際上,數學運算是向量化的,即所有輸入都一起進行數學運算。我們稍後會在「代碼」部分中看到此信息。

在本教程中,我們從3個輸入開始,每個輸入的尺寸為4。

    Input 1: [1, 0, 1, 0]     Input 2: [0, 2, 0, 2]    Input 3: [1, 1, 1, 1]

每個輸入必須具有三個表示形式(請參見下圖)。這些表示稱為key(橙色),`query(紅色)和value(紫色)。在此示例中,假設我們希望這些表示的尺寸為3。由於每個輸入的尺寸均為4,這意味著每組權重的形狀都必須為4×3。Note:
 稍後我們將看到value的維度也就是輸出的維度。

Fig. 1.2: Deriving key, query and value representations from each input為了獲得這些表示,將每個輸入(綠色)乘以一組用於key的權重,另一組用於query的權重和一組value的權重。在我們的示例中,我們如下初始化三組權重。

key的權重

    [[0, 0, 1],     [1, 1, 0],     [0, 1, 0],     [1, 1, 0]]

query的權重

    [[1, 0, 1],     [1, 0, 0],     [0, 0, 1],     [0, 1, 1]]

value的權重

    [[0, 2, 0],     [0, 3, 0],     [1, 0, 3],     [1, 1, 0]]

在神經網絡的設置中,這些權重通常是很小的數,使用適當的隨機分布(如高斯,Xavie 和 Kaiming 分布)隨機初始化。初始化在訓練之前完成一次。

3  從每個輸入中導出key, query and value的表示
現在我們有了三組值的權重,讓我們實際查看每個輸入的查詢表示形式。

輸入 1 的key的表示形式

                   [0, 0, 1]    [1, 0, 1, 0] x [1, 1, 0] = [0, 1, 1]                   [0, 1, 0]                   [1, 1, 0]

使用相同的權重集獲得輸入 2 的key的表示形式:

                   [0, 0, 1]    [0, 2, 0, 2] x [1, 1, 0] = [4, 4, 0]                   [0, 1, 0]                   [1, 1, 0]

使用相同的權重集獲得輸入 3 的key的表示形式:

                   [0, 0, 1]    [1, 1, 1, 1] x [1, 1, 0] = [2, 3, 1]                   [0, 1, 0]                   [1, 1, 0]

一種更快的方法是對上述操作進行矩陣運算:

                   [0, 0, 1]    [1, 0, 1, 0]   [1, 1, 0]   [0, 1, 1]    [0, 2, 0, 2] x [0, 1, 0] = [4, 4, 0]    [1, 1, 1, 1]   [1, 1, 0]   [2, 3, 1]

Fig. 1.3a: Derive key representations from each input

讓我們做同樣的事情以獲得每個輸入的value表示形式:

                   [0, 2, 0]    [1, 0, 1, 0]   [0, 3, 0]   [1, 2, 3]     [0, 2, 0, 2] x [1, 0, 3] = [2, 8, 0]    [1, 1, 1, 1]   [1, 1, 0]   [2, 6, 3]

Fig. 1.3b: Derive value representations from each input

以及query的表示形式:

                   [1, 0, 1]    [1, 0, 1, 0]   [1, 0, 0]   [1, 0, 2]    [0, 2, 0, 2] x [0, 0, 1] = [2, 2, 2]    [1, 1, 1, 1]   [0, 1, 1]   [2, 1, 3]

Fig. 1.3c: Derive query representations from each input

Notes:
 實際上,可以將偏差向量b添加到矩陣乘法的乘積中。

譯者注:y=w·x+b

4 計算輸入的注意力得分(attention scores)

為了獲得注意力分數,我們首先在輸入1的query(紅色)與所有key(橙色)(包括其自身)之間取點積。由於有3個key表示(因為我們有3個輸入),因此我們獲得3個注意力得分(藍色)。

                [0, 4, 2]    [1, 0, 2] x [1, 4, 3] = [2, 4, 4]                [1, 0, 1]

Fig. 1.4: Calculating attention scores (blue) from query 1請注意,在這裡我們僅使用輸入1的query。稍後,我們將對其他查詢重複相同的步驟。

Note:
 上面的操作被稱為"點積注意力",是幾種sorce之一。其他評分功能包括縮放的點積和拼接。

更多 sorce:https://towardsdatascience.com/attn-illustrated-attention-5ec4ad276ee3

5 計算softmax

Fig. 1.5: Softmax the attention scores (blue)

將attention scores通過 softmax 函數(藍色)得到概率

    softmax([2, 4, 4]) = [0.0, 0.5, 0.5]

6 將attention scores乘以value

Fig. 1.6: Derive weighted value representation (yellow) from multiply value (purple) and score (blue)

每個輸入的softmax注意力得分(藍色)乘以其相應的value(紫色)。這將得到3個對齊的向量(黃色)。在本教程中,我們將它們稱為"加權值"。

    1: 0.0 * [1, 2, 3] = [0.0, 0.0, 0.0]    2: 0.5 * [2, 8, 0] = [1.0, 4.0, 0.0]    3: 0.5 * [2, 6, 3] = [1.0, 3.0, 1.5]

7 對加權後的value求和以得到輸出1

Fig. 1.7: Sum all weighted values (yellow) to get Output 1 (dark green)

對所有加權值(黃色)按元素求和:

      [0.0, 0.0, 0.0]    + [1.0, 4.0, 0.0]    + [1.0, 3.0, 1.5]    --    = [2.0, 7.0, 1.5]

得到的向量[2.0, 7.0, 1.5] (深綠)是輸出 1 , 它是基於「輸入1」的「query表示的形式」 與所有其他key(包括其自身)進行的交互。

現在我們已經完成了輸出1,我們將對輸出2和輸出3重複步驟4至7。我相信我可以讓您自己進行操作👍🏼。

Fig. 1.8: Repeat previous steps for Input 2 & Input 3

Notes:
 因為點積得分函數 query和key的維度必須始終相同.但是value的維數可能與query和key的維數不同。因此輸出結果將遵循value的維度。

這裡要一份 pytorch 代碼🤗,pytorch 是一種非常受歡迎的深度學習框架.為了在以下代碼段中使用「 @」運算符,.T和None索引的API,請確保您使用的Python≥3.6和PyTorch 1.3.1。只需將它們複製並粘貼到Python / IPython REPL或Jupyter Notebook中即可。

Step 1: 準備輸入

    import torch    x = [      [1, 0, 1, 0], # Input 1      [0, 2, 0, 2], # Input 2      [1, 1, 1, 1]  # Input 3     ]    x = torch.tensor(x, dtype=torch.float32)

Step 2: 初始化權重

    w_key = [      [0, 0, 1],      [1, 1, 0],      [0, 1, 0],      [1, 1, 0]    ]    w_query = [      [1, 0, 1],      [1, 0, 0],      [0, 0, 1],      [0, 1, 1]    ]    w_value = [      [0, 2, 0],      [0, 3, 0],      [1, 0, 3],      [1, 1, 0]    ]    w_key = torch.tensor(w_key, dtype=torch.float32)    w_query = torch.tensor(w_query, dtype=torch.float32)    w_value = torch.tensor(w_value, dtype=torch.float32)

Step 3:導出key, query and value的表示

    keys = x @ w_key    querys = x @ w_query    values = x @ w_value    print(keys)                print(querys)                print(values)            

Step 4: 計算輸入的注意力得分(attention scores)

    attn_scores = querys @ keys.T            

Step 5: 計算softmax

    from torch.nn.functional import softmax    attn_scores_softmax = softmax(attn_scores, dim=-1)    attn_scores_softmax = [      [0.0, 0.5, 0.5],      [0.0, 1.0, 0.0],      [0.0, 0.9, 0.1]    ]    attn_scores_softmax = torch.tensor(attn_scores_softmax)


Step 6: 將attention scores乘以value

    weighted_values = values[:,None] * attn_scores_softmax.T[:,:,None]                                            

Step 7: 對加權後的value求和以得到輸出

    outputs = weighted_values.sum(dim=0)            

Note*
 PyTorch has provided an API for this called* *nn.MultiheadAttention*. However, this API requires that you feed in key, query and value PyTorch tensors. Moreover, the outputs of this module undergo a linear transformation.

Step 8:對輸入2重複步驟4–7


那麼我們該何去何從?Transformers!確實,我們生活在深度學習研究和高計算資源令人興奮的時代。Transformers是 Attention Is All You Need的應用。研究人員從這裡開始進行組裝,切割,添加和擴展零件,並將其用途擴展到更多的語言任務。

在這裡,我將簡要提及如何將自Self-Attention擴展到Transformer體系結構。(專業術語不譯)

Within the self-attention module:

Inputs to the self-attention module:

Embedding module

Positional encoding

Truncating

Masking

Adding more self-attention modules:

Modules between self-attention modules:

Linear transformations

LayerNorm



Attention Is All You Need (https://arxiv.org/abs/1706.03762)

The Illustrated Transformer (https://jalammar.github.io/illustrated-transformer/)



Attn: Illustrated Attention (https://towardsdatascience.com/attn-illustrated-attention-5ec4ad276ee3)



Special thanks to Xin Jie, Serene, Ren Jie, Kevin and Wei Yih for ideas, suggestions and corrections to this article.

Follow me on Twitter @remykarem for digested articles and other tweets on AI, ML, Deep Learning and Python.

下載1:OpenCV-Contrib擴展模塊中文版教程
在「小白學視覺」公眾號後臺回覆:擴展模塊中文教程即可下載全網第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標跟蹤、生物視覺、超解析度處理等二十多章內容。在「小白學視覺」公眾號後臺回覆:Python視覺實戰項目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數、添加眼線、車牌識別、字符識別、情緒檢測、文本內容提取、面部識別等31個視覺實戰項目,助力快速學校計算機視覺。在「小白學視覺」公眾號後臺回覆:OpenCV實戰項目20講即可下載含有20個基於OpenCV實現20個實戰項目,實現OpenCV學習進階。

交流群


歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫學影像、GAN、算法競賽等微信群(以後會逐漸細分),請掃描下面微信號加群,備註:」暱稱+學校/公司+研究方向「,例如:」張三 + 上海交大 + 視覺SLAM「。請按照格式備註,否則不予通過。添加成功後會根據研究方向邀請進入相關微信群。請勿在群內發送廣告,否則會請出群,謝謝理解~


相關焦點

  • Self-Attention GAN 中的 self-attention 機制
    這兩個技術我還沒有來得及看,而且 PyTorch 版本的 self-attention GAN 代碼中也沒有實現,就先不管它們了。本文主要說的是 self-attention 這部分內容。,self).
  • Self-attention Mask詳解
    從self-attention的計算公式來看,Q先與K的轉置相乘,經過縮放和softmax之後再與V相乘。那麼我們來圖解一下整個過程(為簡化,我們設batch為1):最後,與V矩陣進行相乘得到self-attention的結果,如下圖:
  • 【Self-Attention】幾篇較新的計算機視覺Self-Attention
    Hard-attention,就是0/1問題,哪些區域是被 attentioned,哪些區域不關注2.Soft-attention,[0,1]間連續分布問題,每個區域被關注的程度高低,用0~1的score表示Self-attention自注意力,就是 feature map 間的自主學習,分配權重(可以是 spatial,可以是 temporal,也可以是 channel間)[1] Non-local NN, CVPR2018FAIR的傑作,主要 inspired by
  • 從原始碼剖析Self-Attention知識點
    不考慮多頭的原因,self-attention中詞向量不乘QKV參數矩陣,會怎麼樣?對於 Attention 機制,都可以用統一的 query/key/value 模式去解釋,而對於  self-attention,一般會說它的 q=k=v,這裡的相等實際上是指它們來自同一個基礎向量,而在實際計算時,它們是不一樣的,因為這三者都是乘了 QKV 參數矩陣的。
  • 從Seq2seq到Attention模型到Self Attention(二)
    「The transformer」在計算attention的方式有三種,1. encoder self attention,存在於encoder間. 2. decoder self attention,存在於decoder間
  • Transformer + self-attention
    ‍來源https://zhuanlan.zhihu.com/p/432814387作者Ziyang Li 東北電力大學機器人工程專業最近剛開始閱讀transformer文獻感覺有一些晦澀,尤其是關於其中Q、K、V的理解,故在這裡記錄自己的閱讀心得,供於分享交流一、self-attention
  • 乾貨 | NLP中的self-attention【自-注意力】機制
    可以看到,如果輸入序列n小於表示維度d的話,每一層的時間複雜度self-attention是比較有優勢的。當n比較大時,作者也給出了一種解決方案self-attention(restricted)即每個詞不是和所有詞計算attention,而是只與限制的r個詞去計算attention。在並行方面,多頭attention和CNN一樣不依賴於前一時刻的計算,可以很好的並行,優於RNN。
  • 人人都能看得懂的Self-Attention詳解
    QKV是qkv的矩陣形式, 所以本質是搞清楚qkv是幹嘛的;在self-attention中,q、k、v都是輸入參數矩陣變換而來的(增加可學習性)其中q和k是算相似度的得權重的,v是用來跟權重做加權求和的
  • Self-Attention與Transformer
    其中,padding mask 在所有的 scaled dot-product attention 裡面都需要用到,而 sequence mask 只有在 Decoder 的 self-attention 裡面用到。(1)padding mask什麼是 padding mask 呢?
  • 乾貨|理解attention機制本質及self-attention
    > 點擊上方「AI遇見機器學習」,選擇「星標」公眾號原創乾貨,第一時間送達上一篇,我們講述了attention
  • Transformer+self-attention超詳解(亦個人心得)
    最近剛開始閱讀transformer文獻感覺有一些晦澀,尤其是關於其中Q、K、V的理解,故在這裡記錄自己的閱讀心得,供於分享交流一、self-attention
  • 超詳細圖解Self-Attention的那些事兒
    至此Self-Attention中最核心的內容已經講解完畢,關於Transformer的更多細節可以參考我的這篇回答:最後再補充一點,對self-attention來說,它跟每一個input vector都做attention,所以沒有考慮到input sequence的順序。
  • 推薦算法AutoInt模型:基於multi-head self-attention的特徵高階交叉
    因此,能否通過Transformer模型的核心結構multi-head self-attention模塊,實現對特徵的顯式的高階交叉呢?AutoInt模型通過巧妙的模型設計實現了自動特徵交叉,它通過對多層multi-head self-attention模塊的堆疊,並結合在圖像領域表現驚豔的Residual Network,實現了對輸入特徵進行低階以及高階交叉信息的提取。        下面直接進入正題,來看一下AutoInt模型的原理。
  • 如何理解attention中的Q,K,V?
    config):        self.query = nn.Linear(config.hidden_size, self.all_head_size) # 輸入768, 輸出768        self.key = nn.Linear(config.hidden_size, self.all_head_size) # 輸入768, 輸出768        self.value
  • 機器翻譯的Attention機制
    __init__() self.batch_sz = batch_sz self.dec_units = dec_units self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim) self.gru = tf.keras.layers.GRU(self.dec_units,
  • 自然語言處理中的自注意力機制(Self-Attention Mechanism)
    提出了多頭注意力(Multi-headed Attention)機制方法,在編碼器和解碼器中大量的使用了多頭自注意力機制(Multi-headed self-attention)。3. 在 WMT2014 語料中的英德和英法任務上取得了先進結果,並且訓練速度比主流模型更快。
  • bert之我見-attention
    後續討論attention模型,就只需要搞清楚這三個是啥,這個模型你就理解了一大半了(額,其實我倒是感覺很多文章裡反而沒在各種應用,包括self attention,裡面把這三個角色分別是什麼說清楚)。TransformerTransformer就是BERT發明的一大功臣,這裡面,實際上就是使用了self-attetion,即自注意力機制。
  • 《Attention is All You Need》文獻總結
    Transformer中所有的time step數據都是通過self-attention進行計算得到的,並且每個time step計算時可互不幹擾,從而實現了並行計算。在理解Transformer模型結構之前,我們先對Transformer中用到的self-attention機制和multi-head attention進行敘述。
  • 一文讀懂Attention機制
    soft attention 是一個帶權求和的過程,求和集合是輸入向量的集合,對應權重是 alignment function 產出的 attention weight。hard / soft attention 中,soft attention 是更常用的(後文提及的所有 attention 都在這個範疇),因為它可導,可直接嵌入到模型中進行訓練。
  • 關於attention機制的一些細節的思考
    之前看過的一些attention機制,除了self attention之外,基於rnn或者cnn的attention在處理文本問題的時候基本上是embedding之後經過了rnn或者cnn結構的映射之後得到了映射後的向量V,然後attention是針對於V進行注意力weights的計算,問題來了,能不能直接在embedding上進行score的計算?