自己注意
セルフアテンションアーキテクチャ
自己注意が機能する方法は、ベクトルの行を入力し、ベクトルの行を出力することです。
出力ベクトルは、すべての入力ベクトルの情報を考慮します。
- セルフアテンションは何回でも重ね合わせることができ、
完全接続層 (FC) とセルフアテンションは互換的に使用できます。
- セルフアテンションはシーケンス全体の情報を処理します
- 特定拠点からのお問い合わせ対応を中心としたFCのネットワーク
自己注意のプロセス
-
そのアーキテクチャの 1 つは次のようなもので、出力はbbの行になります。b 是 a a aが計算されて出力されます。
-
b 1 b^{1}b1是考虑了 a 1 , a 2 , a 3 , a 4 a^{1},a^{2},a^{3},a^{4} ある1、ある2、ある3、ある4以降に生成されます
-
b 2 、 b 3 、 b 4 b^{2}、b^{3}、b^{4}b2、b3、b4也是考虑了 a 1 , a 2 , a 3 , a 4 a^{1},a^{2},a^{3},a^{4} ある1、ある2、ある3、ある図4に示すように、それらの計算原理は同じである。
2 つの入力ベクトルの相関を計算します。
-
2 つの一般的な計算方法:ドット積と加算
-
このうち、最初の方法では、まずこれら 2 つのベクトルに W を掛けます (これら 2 つの w は異なり、一方はweight_q、もう一方はweight_k)、それぞれ q、kq、k が得られます。q 、kを計算し、内積を実行してスコアα i , j \alpha _{i,j}ある私、 jai と ajの計算を示しますa_{i} と a_{j}ある私はそして_j関連性のあるもの。
-
然后 a 1 a^{1} ある1 分别和 a 2 , a 3 , a 4 a^{2},a^{3},a^{4} ある2、ある3、ある4類似度を計算します。a 1 a^{1}ある1的 q 1 q^{1} q1分别和 a 2 , a 3 , a 4 a^{2},a^{3},a^{4} ある2、ある3、あるk 2 、 k 3 、 k 4 の 4 k^{2},k^{3},k ^ {4}k2、k3、k4内積を実行して注意を引く scorcea 1 , 2 a_{1,2}ある1、2 _ _、a 1 、3 a_{1,3}ある1、3 _ _、a 1 、4 a_{1,4}ある1、4 _ _, 実際の運用ではa 1 a^{1}も計算されますある自分との類似点が1 つあります。
-
接下来将 a 1 , 1 , a 1 , 2 a_{1,1},a_{1,2} ある1、1 _ _、ある1、2 _ _、a 1 、3 a_{1,3}ある1、3 _ _、a 1 、4 a_{1,4}ある1、4 _ _、ソフトマックス層の後に1 , 1 ' a^{'}_{1,1} を取得しますある1、1 _ _「 a 1 , 2 ' a^{'}_{1,2}ある1、2 _ _「…
-
次に1 a^{1}を入力しますある1到 a 4 a^{4} ある4の各ベクトルはW v W^{v}Wv は新しいベクトルを取得し、それぞれv 1 、 v 2 、 v 3 、 v 4 v^{1}、v^{2}、v^{3}、v^{4} を取得します。v1、v2、v3、v4
-
次に、v 1 v^{1}v1からv 4 v^{4}v4 では、各ベクトルに注意スコアが乗算され、合計されてb 1 b^{1}b1
b 1 = ∑ i α 1 , i ′ vib^{1} = \sum_{i}\alpha_{1,i}^{'}v^{i}b1=私∑ある1 、私「v私 -
同理, a 2 , a 3 , a 4 a^{2},a^{3},a^{4} ある2、ある3、ある4も同じ操作を行ってb 2 、 b 3 、 b 4 b^{2},b^{3},b^{4} をb2、b3、b4.
マトリックス角度
各入力ベクトルは qi 、 ki 、 viq^{i} 、k^{i}、v^{i}のセットを生成します。q私、k私、v私
したがって、私たちはそれぞれaia^{i}します。ある私はwqw^{q}を掛けたままにしておきますwq行列の場合、行列乗算を行うことで Q 行列を取得できます。Q 行列の各列はそれぞれ入力aia^{i}あるiのqiq^{i}q私は。
同様に、各グループki 、 vik^{i} 、 v^{i}k私、vi は行列を使用して計算することもできます。
各注目ai 、 j a_{i,j}ある私、 ji 番目の入力のqiq^{i}を表しますqiと j 番目の入力kjk^{j}kjの内積.
次に、これらの 4 つのステップは、行列とベクトルを乗算することで取得できます。
さらに、すべてのアテンションを計算し、A ' A^{'}あ一方
b1 b^{1}b1はviv^{i}を使用することです。vi左乘 A ′ A^{'} あ'取得、
レビュー
図(15)
- I は自己注意の入力であり、自己注意の入力はベクトルの行であり、行列の列としてまとめられます。
- 入力は 3 つの行列wq 、 wk 、 wvw^{q} 、w^{k} 、 w^{v} で乗算されます。wq 、wk、wv はQ、K、V を取得します。
- 次に、Q に K の転置を乗算して行列 A を取得し、ソフトマックス処理後、A ' A^{'}あ'を左に V で乗算して出力を取得します。
- したがって、自己注意で学習する唯一のパラメータは、ネットワーク トレインが必要な部分である W 行列です。
コード例
この例は次の手順に分かれています。
- 入る準備ができています
- 重みを初期化する
- キー、クエリ、および値の表現をエクスポートする
- 注意スコアの計算
- ソフトマックスを計算する
- 注意スコアに値を乗算します
- 重み付けされた値を合計して出力を取得します
入力を想定すると:
Input 1: [1, 0, 1, 0]
Input 2: [0, 2, 0, 2]
Input 3: [1, 1, 1, 1]
初期化パラメータ
入力は 3 つの 4 次元ベクトルであるため、図 (15) に左から W を掛ける必要があり、W の次元は (4,3) に設定されます。
wk 、 wq 、 wvw^{k} 、w^{q}、w^{v}wk、wq 、wvはそれぞれ w_key、w_query、w_value です。
x = [
[1,0,1,0], # 输入1
[0,2,0,2], #输入2
[1,1,1,1], #输入3
]
x = torch.tensor(x,dtype=torch.float32)
# 初始化权重
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]
]
# 转化成tensor数据类型
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)
QKVを見る
querys = torch.tensor(np.dot(x,w_query),dtype=torch.float32)
keys = torch.tensor(np.dot(x,w_key) ,dtype=torch.float32)
注意を計算する
# get attention scorce
attention_scores = torch.tensor(np.dot(querys,keys.T))
ソフトマックス処理
# 计算soft-max
attention_scores_softmax = torch.tensor( softmax(attention_scores,dim=-1) )
注意スコアに値を乗算します
weight_values = values[:,None] * attention_scores_softmax.T[:,:,None]
重み付けされた値を合計して出力を取得します
outputs = weight_values.sum(dim=0)
テストコード
import torch
import numpy as np
from torch.nn.functional import softmax
def preData():
#
x = [
[1,0,1,0], # 输入1
[0,2,0,2], #输入2
[1,1,1,1], #输入3
]
x = torch.tensor(x,dtype=torch.float32)
# 初始化权重
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]
]
# 转化成tensor数据类型
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)
# get K, Q,V
keys = torch.tensor(np.dot(x,w_key) ,dtype=torch.float32)
querys = torch.tensor(np.dot(x,w_query),dtype=torch.float32)
values = torch.tensor(np.dot(x,w_value),dtype=torch.float32)
# get attention scorce
attention_scores = torch.tensor(np.dot(querys,keys.T))
print(attention_scores)
# 计算soft-max
attention_scores_softmax = torch.tensor( softmax(attention_scores,dim=-1) )
print(values.shape)
weight_values = values[:,None] * attention_scores_softmax.T[:,:,None]
outputs = weight_values.sum(dim=0)
return outputs
if __name__ == "__main__" :
b = preData()
print(b)