从头理解self-attention机制
注意力機制中較為重要的是self-attention機制,直接做了個小白能看懂的總結,也便于自己復習。
簡介
self-attention機制就是想實現(xiàn)一連串的特征編碼,兩兩之間的互相注意。有一串特征編碼,x1, x2, …, xn,這里x1 x2 …都是一個特征向量,即讓每個特征向量都關注到所有的特征向量(包括其自己),然后轉(zhuǎn)變成一個更深層次的向量。
最原始的做法就是,兩兩之間作點積運算,然后生成一個n ?? n的矩陣,其中 i 行 j 列表示 xi 和 xj 之間的相似度。然后我們用這個相似度矩陣,再對 x 做加權平均,就得到一個y1, y2, …, yn,這個就是self-attention的輸出。
舉個簡單的🌰,比如三個特征向量 x1 = [0.1, 0.5], x2 = [0.3, 0.4], x3 = [0.8, 0],然后兩兩之間做點積運算,得到一個矩陣如下:
0.26 0.23 0.08
0.23 0.25 0.24
0.08 0.24 0.64
然后用這個矩陣對 x1, x2, x3 做加權平均,就是該權重矩陣的第 i 行單獨拿出來,就是 yi 的加權值。計算方法就是:
y1 = 0.26 ?? x1 + 0.23 ?? x2 + 0.08 ?? x3
y2 = 0.23 ?? x1 + 0.25 ?? x2 + 0.24 ?? x3
y3 = 0.08 ?? x1 + 0.24 ?? x2 + 0.64 ?? x3
主要的操作
歸一化
首先,加權值應當要歸一化,即一行權重值加起來應該是1,否則 y 在數(shù)值上會變得不穩(wěn)定(變得很大或者變得很小),所以權重矩陣要按行做歸一化。歸一化的方法就是Softmax,因為softmax更好求導,數(shù)值上相比于hard max也更穩(wěn)定。
假設原先的計算方法是:Y = (X X^T) X
那么加入歸一化后就是:Y = Softmax(X X^T) X
數(shù)值穩(wěn)定
X X^T 這個權重矩陣也有問題,一般來說,一個特征向量中,每一個元素都是一個期望為0,方差為1的隨機變量(為了數(shù)值穩(wěn)定,特征向量每層都要做歸一化,就是為了保證這個性質(zhì)),我們希望后續(xù)運算過程中,所有的中間變量都可以保持期望為0,方差為1。
期望為0,方差為1的原因:假設方差很多,數(shù)值為出現(xiàn)很大的數(shù)字,比如100,這樣求導的梯度也會變得很大,模型更新的幅度也會很大,就很不穩(wěn)定了。甚至會出現(xiàn)梯度爆炸(就是更新的數(shù)值變成無窮大)或者梯度消失(更新數(shù)值為0,就是更新不動了)
但是點積運算會打破這一性質(zhì)(所有的中間變量都可以保持期望為0,方差為1),例如,假設x1是一個64維的向量,x2也是個64維向量,兩者點積后的結果,期望還是0,方差已經(jīng)不是1了,方差變成了根號64=8。
見如下概率論公式:D(XY)=D(X)D(Y) - (E(X)E(Y))
d個隨機變量相乘后相加,就是多個隨機變量運算后的方差計算公式。應該除以根號d_k,才能把方差控制在1,d_k是特征向量的維度,所以公式就變成了:
Y = (X X^T / sqrt(d_k)) X
線性變換
這里運算都是X,太單一了,所以作者就讓三個X分別做了三個線性變換,K、Q、V都是從 X 變換過來的線性變換的權重矩陣,根源都是同一個,所以其實就是自己跟自己做運算,分別是:
Q = W^Q X
K = W^K X
V = W^V X
這里線性變換就是nn.Linear(d_k, d_k),不改變維度,只是做了一個線性投影。
把線性變換后的結果再去做attention運算:
Y = (Q K^T / sqrt(d_k)) V
一些總結
1. self-attention是線性運算嗎?
答:不是。前面全是線性運算,非線性來自于歸一化softmax。
2. self-attention的時間復雜度?
就看這個算法做了多少次原子運算。
例如:
兩個向量點積,就是對應的元素乘起來然后累加(n次乘法+n次加法),復雜度是O(n)。
兩個n??n矩陣相乘,結果有n??n個元素,每個元素是由n次乘法+n次加法得來的,所以時間復雜度是O(n^3).
所以,self-attention的時間復雜度如下:
1.每行歸一化,一行softmax的時間復雜度是o(n),那么n行 就是o(n2)
2.往里面看,權重矩陣是看成一個矩陣乘法X X^T,X是nd_k維,所以是O(n??n??d)。過程:矩陣乘法,n??d d??n,結果n??n,每個元素d次
3.和V相乘,權重矩陣是n??n對吧,這個V是n??d,是O(n??n??d)。
所以,最后相加,總時間復雜度是O(n??n??d)。
3.根據(jù)公式寫出代碼
import numpy as np
import math
def self_attention(X):n, d = X.shape[:2]# 假設W_q W_k W_v是三個線性變換的權重矩陣W_q = np.random.rand(n * n)W_k = np.random.rand(n * n)W_v = np.random.rand(n * n)# 你來填 d個隨機變量Q = np.matmul(W_q,X)K = np.matmul(W_k,X)V = np.matmul(W_v,X)W = np.matmul(Q,np.transpose(K))/math.sqrt(d)# -*- coding: utf-8 -*-def softmax(X):# reshape后面加個1就是為了讓他可以跟x_exp相除# 比如說一個3 * 3的矩陣,可以跟3 * 1的矩陣相除的# 相除的時候,3 * 1的矩陣會擴展成3 * 3的,就是把列復制3份x_row_max = X.max(axis=1).reshape(list(X.shape)[:-1]+[1]) #按行找最大值X = X - x_row_max# 取最大值防溢出x_exp = np.exp(X)x_exp_row_sum = x_exp.sum(axis=1).reshape(list(X.shape)[:-1]+[1])softmax = x_exp / x_exp_row_sum #歸一化return softmax# Y=softmax(Q K^T/sqrt(d))*VY = np.matmul(softmax(W),V)return Y
總結
以上是生活随笔為你收集整理的从头理解self-attention机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 08年大众斯柯达价值多少钱?
- 下一篇: 【目标检测】yolo系列:从yolov1