自己注意とコード手書きの紹介

自己注意


セルフアテンションアーキテクチャ

自己注意が機能する方法は、ベクトルの行を入力し、ベクトルの行を出力することです。

出力ベクトルは、すべての入力ベクトルの情報を考慮します。

図1

  • セルフアテンションは何回でも重ね合わせることができ、
    ここに画像の説明を挿入
    完全接続層 (FC) とセルフアテンションは互換的に使用できます。
  1. セルフアテンションはシーケンス全体の情報を処理します
  2. 特定拠点からのお問い合わせ対応を中心とした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}b2b3b4也是考虑了 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}k2k3k4内積を実行して注意を引く 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} を取得します。v1v2v3v4

  • 次に、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} をb2b3b

マトリックス角度

各入力ベクトルは qi 、 ki 、 viq^{i} 、k^{i}、v^{i}のセットを生成します。qkv

ここに画像の説明を挿入

したがって、私たちはそれぞれaia^{i}します。ある私はwqw^{q}を掛けたままにしておきますwq行列の場合、行列乗算を行うことで Q 行列を取得できます。Q 行列の各列はそれぞれ入力aia^{i}あるiqiq^{i}q私は

ここに画像の説明を挿入
同様に、各グループki 、 vik^{i} 、 v^{i}kvi は行列を使用して計算することもできます。
ここに画像の説明を挿入
各注目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 wkwv はQ、K、V を取得します。
  • 次に、Q に K の転置を乗算して行列 A を取得し、ソフトマックス処理後、A ' A^{'}'を左に V で乗算して出力を取得します。
  • したがって、自己注意で学習する唯一のパラメータは、ネットワーク トレインが必要な部分である W 行列です。

コード例

この例は次の手順に分かれています。

  1. 入る準備ができています
  2. 重みを初期化する
  3. キー、クエリ、および値の表現をエクスポートする
  4. 注意スコアの計算
  5. ソフトマックスを計算する
  6. 注意スコアに値を乗算します
  7. 重み付けされた値を合計して出力を取得します

入力を想定すると:

    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}wkwq 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)

参考

おすすめ

転載: blog.csdn.net/qq_41661809/article/details/124735234