神经网络注意力机制图片处理及代码(二)

        本文主要用于记录笔者深度学习注意力机制部分的学习过程,如有不准确之处,欢迎各路大神指出!谢谢!

自注意力机制(Attention Is All You Need)

from attention.SelfAttention import ScaledDotProductAttention
import torch
 
input=torch.randn(50,49,512)
sa = ScaledDotProductAttention(d_model=512, d_k=512, d_v=512, h=8)
output=sa(input,input,input)
print(output.shape)
  • torch.randn()函数用于生成随机矩阵。例:
    torch.randn(2, 3, 4)
    tensor([[[-2.0315,  0.1029,  0.4129, -0.3980],
             [-0.5129, -0.4984, -0.5934,  0.6140],
             [-0.0393, -2.1767,  0.1968, -0.5267]],
    
            [[ 0.7545, -0.1527, -1.5746, -0.8272],
             [ 0.6985, -1.1397, -1.2289, -0.3513],
             [-1.1178,  0.1474, -0.7278, -1.1510]]])
    

    当参数有三个时,返回一个2行1列的张量,其中每个元素又是一个3行4列的张量。

        下面开始重点解释ScaledDotProductAttention(缩放点积注意力)。

def masked_softmax(X, valid_lens):
    if valid_lens is None:
        return nn.functional.softmax(X, dim=-1)
    else:
        shape = X.shape
        if valid_lens.dim() == 1:
            valid_lens = torch.repeat_interleave(valid_lens, shape[1])
        else:
            valid_lens = valid_lens.reshape(-1)
        X = d2l.sequence_mask(X.reshape(-1, shape[-1]), valid_lens,
                              value=-1e6)
        return nn.functional.softmax(X.reshape(shape), dim=-1)
  • softmax()函数的作用是将张量的每个元素缩放到(0,1)区间且和为1。
  • torch.repeat_interleave()函数的作用是重复张量的元素。例:
    >>> x = torch.tensor([1, 2, 3])
    >>> x.repeat_interleave(2)
    tensor([1, 1, 2, 2, 3, 3])
    # 传入多维张量,默认`展平`
    >>> y = torch.tensor([[1, 2], [3, 4]])
    >>> torch.repeat_interleave(y, 2)
    tensor([1, 1, 2, 2, 3, 3, 4, 4])
  • .reshape(-1)函数的作用是重新定义矩阵形状。例:
    z = np.array([[1, 2, 3, 4],
              [5, 6, 7, 8],
              [9, 10, 11, 12],
              [13, 14, 15, 16]])
    z.shape
    (4, 4)
    
    z.reshape(-1)
    array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16])
    
  • d2l.sequence_mask()函数的作用是给定一个矩阵A,一个张量B,根据张量B中的元素来屏蔽A中元素。

总结第一段代码的简单原理为:

        传入的张量(X)可能只有一部分是有用(有效长度即valid_lens)的,所以需要将没用的部分屏蔽(mask)掉,只对剩下的部分进行softmax计算。比如,传入一个长度为5的张量,我们仅需前两个数据,则经过softmax()函数之后,后三个数加起来是0,前两个数加起来是1。

class DotProductAttention(nn.Module):
    def __init__(self, dropout, **kwargs):
        super(DotProductAttention, self).__init__(**kwargs)
        self.dropout = nn.Dropout(dropout)
    def forward(self, queries, keys, values, valid_lens=None):
        d = queries.shape[-1]
        scores = torch.bmm(queries, keys.transpose(1,2)) / math.sqrt(d)
        self.attention_weights = masked_softmax(scores, valid_lens)
        return torch.bmm(self.dropout(self.attention_weights), values)
  • nn.Dropout()函数用于防止或减轻过拟合而使用的函数,一般用于全连接层。在训练过程的前向传播中,让每个神经元以一定概率p处于不激活的状态。
  • torch.bmm()函数用于两个矩阵的乘法。
  • transpose()函数用于交换矩阵的两个维度。
  • math.sqrt(x)函数用于返回 x 的平方根。使用公式计算注意力

总结这段代码的简单原理为:

        利用公式计算注意力分数(scores),使用masked_softmax()计算注意力权重,对注意力权重进行dropout计算后,最后返回注意力权重和values的乘积。

参考文章:

(12条消息) 神经网络学习小记录64——Pytorch 图像处理中注意力机制的解析与代码详解_Bubbliiiing的博客-CSDN博客

代码实现 缩放点积注意力 | scaled dot-product attention #51CTO博主之星评选#_LolitaAnn的技术博客_51CTO博客(13条消息) sequence_mask_取个名字真难呐的博客-CSDN博客_sequence_mask

你可能感兴趣的:(数字图像处理,神经网络,深度学习,计算机视觉)