更新時(shí)間:2022年02月12日15時(shí)54分 來源:傳智教育 瀏覽次數(shù):
我們觀察事物時(shí),之所以能夠快速判斷一種事物(當(dāng)然允許判斷是錯(cuò)誤的),是因?yàn)槲覀兇竽X能夠很快把注意力放在事物最具有辨識度的部分從而作出判斷,而并非是從頭到尾的觀察一遍事物后,才能有判斷結(jié)果,正是基于這樣的理論,就產(chǎn)生了注意力機(jī)制。
它需要三個(gè)指定的輸入Q(query),K(key),V(value),然后通過計(jì)算公式得到注意力的結(jié)果,這個(gè)結(jié)果代表query在key和value作用下的注意力表示.當(dāng)輸入的Q=K=V時(shí),稱作自注意力計(jì)算規(guī)則。
|| ·將Q,K進(jìn)行縱軸拼接,做一次線性變化,再使用softmax處理獲得結(jié)果最后與V做張量乘法。
|| ·將Q,K進(jìn)行縱軸拼接,做一次線性變化后再使用tanh函數(shù)激活,然后再進(jìn)行內(nèi)部求和,最后使用softmax處理獲得結(jié)果再與V做張量乘法.
|| ·將Q與K的轉(zhuǎn)置做點(diǎn)積運(yùn)算,然后除以一個(gè)縮放系數(shù)再使用softmax處理獲得結(jié)果最后與V做張量乘法。
說明:當(dāng)注意力權(quán)重矩陣和V都是三維張量且第一維代表為batch條數(shù)時(shí), 則做bmm運(yùn)算.bmm是一種特殊的張量乘法運(yùn)算。
# 如果參數(shù)1形狀是(b × n × m), 參數(shù)2形狀是(b × m × p), 則輸出為(b × n × p) >>> input = torch.randn(10, 3, 4) >>> mat2 = torch.randn(10, 4, 5) >>> res = torch.bmm(input, mat2) >>> res.size() torch.Size([10, 3, 5])
在解碼器端的注意力機(jī)制:能夠根據(jù)模型目標(biāo)有效的聚焦編碼器的輸出結(jié)果,當(dāng)其作為解碼器的輸入時(shí)提升效果,改善以往編碼器輸出是單一定長張量,無法存儲過多信息的情況。
在編碼器端的注意力機(jī)制:主要解決表征問題,相當(dāng)于特征提取過程,得到輸入的注意力表示。般使用自注意力(self-attention)。
第一步:根據(jù)注意力計(jì)算規(guī)則,對Q,K,V進(jìn)行相應(yīng)的計(jì)算
第二步:根據(jù)第一步采用的計(jì)算方法,如果是拼接方法,則需要將Q與第二步的計(jì)算結(jié)果再進(jìn)行拼接,如果是轉(zhuǎn)置點(diǎn)積一般是自注意力,Q與V相同,則不需要進(jìn)行與Q的拼接
第三步:最后為了使整個(gè)attention機(jī)制按照指定尺寸輸出,使用線性層作用在第二步的結(jié)果上做個(gè)線性變換,得到最終對Q的注意力表示
常見注意力機(jī)制的代碼分析:
import torch import torch.nn as nn import torch.nn.functional as F class Attn(nn.Module): def __init__(self, query_size, key_size, value_size1, value_size2, output_size): """初始化函數(shù)中的參數(shù)有5個(gè), query_size代表query的最后一維大小 key_size代表key的最后一維大小, value_size1代表value的導(dǎo)數(shù)第二維大小, value = (1, value_size1, value_size2) value_size2代表value的倒數(shù)第一維大小, output_size輸出的最后一維大小""" super(Attn, self).__init__() # 將以下參數(shù)傳入類中 self.query_size = query_size self.key_size = key_size self.value_size1 = value_size1 self.value_size2 = value_size2 self.output_size = output_size # 初始化注意力機(jī)制實(shí)現(xiàn)第一步中需要的線性層. self.attn = nn.Linear(self.query_size + self.key_size, value_size1) # 初始化注意力機(jī)制實(shí)現(xiàn)第三步中需要的線性層. self.attn_combine = nn.Linear(self.query_size + value_size2, output_size) def forward(self, Q, K, V): """forward函數(shù)的輸入?yún)?shù)有三個(gè), 分別是Q, K, V, 根據(jù)模型訓(xùn)練常識, 輸入給Attion機(jī)制的 張量一般情況都是三維張量, 因此這里也假設(shè)Q, K, V都是三維張量""" # 第一步, 按照計(jì)算規(guī)則進(jìn)行計(jì)算, # 我們采用常見的第一種計(jì)算規(guī)則 # 將Q,K進(jìn)行縱軸拼接, 做一次線性變化, 最后使用softmax處理獲得結(jié)果 attn_weights = F.softmax( self.attn(torch.cat((Q[0], K[0]), 1)), dim=1) # 然后進(jìn)行第一步的后半部分, 將得到的權(quán)重矩陣與V做矩陣乘法計(jì)算, # 當(dāng)二者都是三維張量且第一維代表為batch條數(shù)時(shí), 則做bmm運(yùn)算 attn_applied = torch.bmm(attn_weights.unsqueeze(0), V) # 之后進(jìn)行第二步, 通過取[0]是用來降維, 根據(jù)第一步采用的計(jì)算方法, # 需要將Q與第一步的計(jì)算結(jié)果再進(jìn)行拼接 output = torch.cat((Q[0], attn_applied[0]), 1) # 最后是第三步, 使用線性層作用在第三步的結(jié)果上做一個(gè)線性變換并擴(kuò)展維度,得到輸出 # 因?yàn)橐WC輸出也是三維張量, 因此使用unsqueeze(0)擴(kuò)展維度 output = self.attn_combine(output).unsqueeze(0) return output, attn_weights
調(diào)用:
query_size = 32 key_size = 32 value_size1 = 32 value_size2 = 64 output_size = 64 attn = Attn(query_size, key_size, value_size1, value_size2, output_size) Q = torch.randn(1,1,32) K = torch.randn(1,1,32) V = torch.randn(1,32,64) out = attn(Q, K ,V) print(out[0]) print(out[1])
輸出效果:
tensor([[[ 0.4477, -0.0500, -0.2277, -0.3168, -8.4096, -0.5982, 0.1548, -8.8771, -8.0951. 8.1833. 8.3128. 8.1260, 8.4420. 8.8495. -0.7774, -0.0995, 0.2629, 0.4957, 1.0922, 0.1428, 0.3024. -0.2646, -0.0265, 0.0632, 0.3951, 0.1583, 0.1130, 0.5500, -0.1887, -0.2816, -0.3800, -0.5741, 0.1342, 0.0244, -0.2217, 0.1544, 0.1865, -0.2019, 0.4090, -0.4762, 0.3677, -0.2553, -0.5199, 0.2290, -0.4407, 0.0663, -8.0182, -8.2168, 0.0913, -0.2340, 0.1924, -0.3687, 0.1508, 0.3618, -0.0113, 0.2864. -0.1929, -0.6821, 0.0951, 0.1335, 0.3560, -0.3215 ,0.6461, 0.1532]]],grad_fn=<UnsqueezeBackward0>) tensor([[0.0395, 0.0342, 0.0200, 0.0471, 0.0177, 0.0209, 0.0244, 0.0465, 0.0346, 0.0378, 0.0282, 0.0214, 0.0135, 0.0419, 0.0926, 0.0123, 0.0177, 0.0187, 0.0166, 0.8225, 0.0234, 0.0284, 0.0151, 0.0239, 0.0132, 0.0439, 0.0507, 0.0419, 8.0352, 8.0392, 8.0546, 0.0224]], grad_fn=<SoftmaxBackward>)
北京校區(qū)