前情提要:
前陣子,或許更早之前,筆者關於 MoE 的一些研究——如果稱得上是研究,而非民科的話——讓人不禁思考 Transformer 的知識到底存在哪裡?這個問題的價值不言而喻,用來打發時間也是個不錯的選擇。
可惜的是,目前我關於它的思考仍舊十分細碎,或許也稱不上有什麼新意,這裡只是做下暫且的梳理,一方面以作個人備忘,一方面也會考慮可讀性,希望能幫助看到此篇的人度過愉快的廁所時光。
矩陣乘法
最簡單的神經網路,或許就是矩陣 -> 啟用函式 -> 矩陣 -> 啟用函式
的堆疊了吧。
假如這個網路的輸入是個向量,那麼在每一個矩陣層,進行的計算無非是一個向量和一個矩陣的乘法。
即便以筆者匱乏的數學知識,也可以知道,向量和矩陣的乘法,可以看成是以向量為權重,對矩陣的所有行(或者列)進行加權求和。
從這個角度去理解的結果是什麼呢?我們可以輕鬆的把一個神經網路分為頭重腳輕的兩部分:權重生成器,和知識儲存器(其實就是個矩陣)。輸入經過好多好多層複雜的運算,為的就是把最後的一層混合起來。
(你或許想到了殘差連線這個反例,別急別急。)
那麼然後呢?這就有了一絲絲可解釋性了。假如我們可以評估知識儲存器裡的每個知識對於最終預測的影響,那麼我們就可以透過檢視權重,看看模型是否按照我們的理解在工作。
相關工作
好吧,口說無憑,還會被當成民科,這裡就擺出一篇相關論文:Backpack Language Models -- 23 ACL Outstanding Papers。
這篇文章的出發點是可解釋性。用我們剛才提出的視角,這篇文章的方法,完全可以看成是:權重生成器——一整個Transformer,和知識儲存器——一個矩陣。
背景知識:Transformer,或者說 decoder 的結構,我們可以看成是:
- embedding layer
- Transformer Blocks
- embedding layer (decoding layer)
這篇的文章呢,在這裡面插了兩層,變成了:
- embedding layer
- Transformer Blocks
- Attention Layer
- Backpack Layer
- embedding layer (decoding layer)
這插入的兩層被加粗了,名字是我隨便取的。
大家都知道, Transformer Blocks 的輸出是一個 token embedding 的序列。這裡假設有 N 個 token,每個 embedding 的維度是 d,那麼輸出就是個矩陣,維度是 N * d。
Attention Layer 做的工作,就是把這個矩陣拿過來,計算兩兩 token 之間的 k 個權重,最終得到一個 N * N * k 的矩陣。(為什麼是 k 個?怎麼得到 k 個權重?無視也行,完全不重要。做法很簡單,參考多頭注意力。)
通俗點理解,每個 token 都需要給出它對其它所有 token 的喜歡程度,而且還要用 k 個標準給出 k 個不同的分數。所以每個 token 的權重矩陣是 N * k 。
Backpack Layer 裡面,有一個預先準備好的矩陣。在這個矩陣裡,每個詞有 k 個向量。假設詞表大小是 V,那麼這個矩陣的大小就是 V * k * d——我們只需要用到一起出現的那些詞的向量,矩陣大小是 N * k * d。
對於一個 token,它根據權重,把 Backpack Layer 裡的那些向量混合,得到 token 最終的輸出向量。
繁瑣的細節終於解釋了,總結下!
Backpack Language model 裡,embedding layer + Tranformer Blocks + Attention Layer
可以看成是一個活生生的權重生成器——非常重量級的權重生成器。然後,Backpack Layer
裡儲存的向量,就是所謂的知識啦。
梳理下模型的計算過程:給定一個輸入的向量,經過 Transformer 的計算,得到它對於某些向量(知識)的喜愛程度,然後根據這個喜愛程度,把知識混合起來。
這麼訓練的模型呢,也就具備了一點點可解釋性。具體還是看論文吧。
殘差連線
筆者呢,前些時日,發了個想法。根據我們提出的權重生成器和知識儲存器這個角度,來理解殘差連線的作用。
殘差連線的直覺
如果有個神經網路,輸入是向量,輸出也是向量。通常來說(或者假定),沒有殘差的情況下,最後一次的計算是向量 x 與一個矩陣相乘 A。比如:
y = xA。
那麼直觀點來看,這個操作就是將 A 的各行進行混合。
也就是說,我們可以把神經網路拆成兩部分。第一部分根據輸入得到一個權重,第二部分根據這個權重把 A 的各行進行混合。
如果我們假定模型裡有知識,那麼我們只能認為知識儲存在了A矩陣裡。多麼悲觀。
可是有了殘差就不一樣了。在模型裡進行的每一次矩陣乘法(每一次權重矩陣的混合)的結果都會被傳入到下一層。也就意味著每一層的權重或多或少都貢獻了知識。
如何驗證,殘差是否是按照上面的假設發揮作用的呢?
一個很簡單的做法,就是移除掉模型,比如Transformer,最後一層的殘差。僅僅把向量與矩陣相乘的結果作為輸出。
大意就是,模型的能力應該會受到最後面的知識儲存器的限制。而殘差連線,巧妙的把每一層都當做了知識儲存器。怎麼驗證這一點呢?
就是移除掉模型,比如Transformer,最後一層的殘差。僅僅把向量與矩陣相乘的結果作為輸出。
沒錯,Backpack Language Models 就是個驗證。當它把 k 設定為 1 時,模型的效能特別差。不無是個例證。
未完待續
什麼,你問我你看完了這個收穫了什麼?嘛,總該不是完全沒有收穫吧。
寫累了,祝大家吃好喝好,下次再見。