5分鐘理解transformer模型位置編碼

2021-10-23 10:52:00 字數 2662 閱讀 7281

bert模型是自然語言處理方面里程碑式的進步,其核心是transformer層, 而transformer採用自注意力編碼器摒棄了迴圈網路,迴圈網路天生的順序資訊在自注意力編碼器中沒有了,而語言往往是順序不同意思相差很大。所以transformer的作者設計了一種三角函式位置編碼方式,為每個不同位置的token單獨生成乙個位置向量(或者位置嵌入,即position embedding,縮寫為pe)。下面的公式是位置編碼的公式,但是**及網上其他文章對公式解釋不是很清楚,所以我在此採用例子來幫助初學者理解。

式中pos為token在序列中的位置號碼,它的取值是0到序列最大長度max_que_length-1之間的整數。比如「[cls] 我 愛 中 華 [sep]」是6個token組成的序列,[cls]的pos值為0,「我」的pos值為1,「愛」的pos為2,「中」為3,「華」為4,'[sep]'為5 。bert base最大長度max_que_length是512,pos取值還能一直到511。當然如果序列真實長度小於最大長度時,後面的位置號沒有意義,最終會被mask掉。

dmodel是位置向量的維度,與整個模型的隱藏狀態維度值相同,這解釋了為什麼起dmodel這個名字,這個維度在bert base模型裡設定為768。

i 是從0到dmodel/2-1之間的整數值,即0,1,2,...383。

2i  是指向量維度中偶數維,即第0維,第2維,第4維,直到第766維。

2i+1 是維度中奇數維,即第1維,第3維,第5維,直到第767維。

pe是乙個矩陣,行數是最大的序列長度max_que_length,列數是dmodel,即它的形狀為[max_que_length,dmodel]

pe(pos,2i)是pe矩陣中第pos行,第2i列的數值,是個標量。這裡是在第偶數列上的值,偶數列用正玄函式計算。

pe(pos,2i+1) 是pe矩陣中第pos行,第2i+1列的數值,是個標量。這裡是在第奇數列上的值,奇數列用餘玄函式計算。

仍然以序列「[cls] 我 愛 中 華 [sep]」為例,現在計算序列中"我"的位置向量,這個向量有768維,我考慮前面4維的值和最後2維做為例子,其他維度則省略:

"我"在序列中位置pos的值是1,當i=0時,2i表示第0維,2i+1表示第1維,dmodel=768,為簡潔,此處小數點後只取2位

pe(1,0)= sin(1/(10000)^(0/768)) = sin(1/1) = sin(1) = 0.84

pe(1,1) = cos(1/(10000)^(0/768)) = cos(1/1)=cos(1) = 0.54

再看當i=1時的第2維和第3維

pe(1,2) = sin(1/(10000^(2/768))) = sin(1/(10000^(1/384)))=sin(1/1.02)=0.83

pe(1,3) = cos(1/(10000^(2/768))) = cos(1/1.02) = 0.56

再看最後兩維的情況,這時i=383:

pe(1,766) = sin(1/(10000^(766/768))) = sin(1/9763.00) = 0.00

pe(1,767) = cos(1/(10000^(766/768))) = cos(1/9763.00) = 1.00

那token"我"的位置向量大概樣子是

[0.84,0.54,。。。,0.00,1.00]

再看看當位置號pos不斷增大時,某一維比如第0維的值是怎麼變化的。因為三角函式是關於2倍圓周率pi的週期函式,所以把數值轉為pi的倍數

p(1,0)=sin(1)=sin(0.31pi)

p(2,0)=sin(2)=sin(0.64pi)

p(3,0)=sin(3)=sin(0.96pi)

p(6,0)=sin(6)=sin(1.91pi)

p(7,0)=sin(7)=sin(2.23pi)=sin(0.23pi)

p(8,0)=sin(8)=sin(2.54pi)=sin(0.54pi)

由此可看出,由於三角函式是週期函式,隨著位置號的增加,相同維度的值有週期性變化的特點。

transformer為什麼設計這樣的編碼方式來生成位置向量呢? 因為三角函式有個性質

sin(a+b) = sin(a) * cos(b) + cos(a) * sin(b)

cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b)

因此可以推導出,兩個位置向量的點積是乙個與他們兩個位置差值(即相對位置)有關,而與絕對位置無關。這個性質使得在計算注意力權重的時候(兩個向量做點積),使得相對位置對注意力發生影響,而絕對位置變化不會對注意力有任何影響,這更符合常理。

比如」我愛中華「這句話,」華「與」中「相對位置為1,華與中的相關性程度取決於相對位置值1。而如果這句話前面還有其他字元,那華和中兩個字的絕對位置會變化,這個變化不會影響到中華這兩個字的相關程度。

但是這裡似乎有個缺陷,就是這個相對位置沒有正負之分,比如"華"在"中"的後面,對於"中"字,"華"相對位置值應該是1,而"愛"在"中"的前面,相對位置仍然是1,這就沒法區分到底是前面的還是後面的。

transformer的位置向量還有一種生成方式是可訓練位置向量。即隨機初始化乙個向量,然後由模型自動訓練出最可能的向量。transformer的作者指出這種可訓練向量方式的效果與正玄餘玄編碼方式的效果差不多。在bert的**中採用的是可訓練向量方式。

5分鐘理解onecache hash演算法

onecahce中的hash演算法有兩種 onecache自帶演算法 twemproxy的ketama演算法 可以實現和twemproxy的直接切換。hash函式通過配置檔案中的root節點的hash屬性配置。如果需要用twemproxy的ketama演算法,則配置twemproxy mode 1。...

5分鐘理解Focal Loss與GHM

focal loss的引入主要是為了解決難易樣本數量不平衡 注意,有區別於正負樣本數量不平衡 的問題,實際可以使用的範圍非常廣泛,為了方便解釋,還是拿目標檢測的應用場景來說明 單階段的目標檢測器通常會產生高達100k的候選目標,只有極少數是正樣本,正負樣本數量非常不平衡。我們在計算分類的時候常用的損...

5分鐘弄懂Docker

儘管之前久聞docker的大名了,但是天資愚鈍,對其到底是個啥東西一直摸不清,最近花了一段時間整理了一下,算是整理出一點頭緒來。官網的介紹是這樣的 那麼應用容器長什麼樣子呢,乙個做好的應用容器長得就好像乙個裝好了一組特定應用的虛擬機器一樣。比如我現在想用mysql那我就找個裝好mysql的容器,執行...