学习记录-Attention

class Attention(nn.Module):
    def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
        super().__init__()
        self.num_heads = num_heads
        head_dim = dim // num_heads
        # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
        self.scale = qk_scale or head_dim ** -0.5

        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)#用于设置网络中的全连接层的,全连接层的输入和输出一般都设置成二维张量,形状通常为[batch_size,size]
        self.attn_drop = nn.Dropout(attn_drop)#随机将输入张量中部分元素设置为0,对于每次前向调用,被设置为0的元素都是随机的
        self.proj = nn.Linear(dim, dim)#dim=192
        self.proj_drop = nn.Dropout(proj_drop)

    def forward(self, x):
        B, N, C = x.shape#这里的B =? N=197?C=192?
        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
        q, k, v = qkv[0], qkv[1], qkv[2]   # make torchscript happy (cannot use tensor as tuple)

        attn = (q @ k.transpose(-2, -1)) * self.scale
        attn = attn.softmax(dim=-1)
        attn = self.attn_drop(attn)

        x = (attn @ v).transpose(1, 2).reshape(B, N, C)
        x = self.proj(x)
        x = self.proj_drop(x)
        return x

Transformer结构分析

1.输入

2.计算Q,K,V
在这里插入图片描述
3.处理多头
将最后一维(embedding_dim)拆成h份,需要保证embedding_dim能够被h整除。每个tensor的最后两个维度表示一个头,QKV各自都有h个头,接下来需要把这些头分别进行计算
在这里插入图片描述

4.计算
按顺序取出上图中一组QKV,计算
在这里插入图片描述
(1)计算得到各个字之间的关系(相似度).这里的d的维度是
(batch_size, h, seq_len, embedding_dim) * (batch_size, h, embedding_dim, seq_len)==>(batch_size, h, seq_len, seq_len)。QKV分别有 batch_size * h 个矩阵,可以认为是在一个(batch_size, h)的棋盘中,每个位置放置了一个大小为(seq_len, embedding_dim)的矩阵。这里的前两个维度不变只是把棋盘中对应位置的矩阵拿出来做矩阵乘法,并把结果再放回到棋盘中。

(2)用mask矩阵遮盖掉超出句子长度的部分。将句子中用来pading的字符全部替换成 inf, 这样 计算softmax的时候它们的值会为0,就不会参与到接下来与V的计算当中

(3) dk 是为了改变已经偏离的方差。我的理解是,由于矩阵转置后相乘会有很多内积运算,而内积运算将dk个数相加时会改变数据的分布。而这个分布的趋势是 mean=0,variance=dk。为了使方差回归到1,把所有结果都除上一个dk−−√,这样求平方时会抵消已有的方差dk

# 均值为0,方差为1
a = np.random.randn(2,3000)
b = np.random.randn(3000,2)
c = a.dot(b)

print(np.var(a))
print(np.mean(c))
print(np.var(c))

# 1.0262973662546435
# 25.625943965792157
# 1347.432397285718

To illustrate why the dot products get large, assume that the components of q and k are independent random variables with > mean 0 and variance 1. Then their dot product, q⋅k=∑dki=1qiki, has mean 0 and variance dk.
(4)计算各个词义所占的比例 d⋅v,按照权重融合了各个字的语义。最后将多个头的结果拼接成一个完成的embedding作为self-attendion的输出。

(batch_size, h, seq_len, seq_len) * batch_size, h, seq_len, embedding/h
部分代码如下:

# (batch, seq_len, h, embed/head) -> (batch, h, seq_len, embed/head)
q = self.qry(y).view(y.size(0), y.size(1), self.head, -1).transpose(1, 2)
k = self.key(x).view(x.size(0), x.size(1), self.head, -1).transpose(1, 2)
v = self.val(x).view(x.size(0), x.size(1), self.head, -1).transpose(1, 2)
d = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(k.size(-1))     # 相似度 (batch , h, seq, seq)
d = d.masked_fill(m, -float('inf'))     # 把所有为true的地方替换成inf,这里是遮盖掉句子内部的pad
a = F.softmax(d, dim=-1)            # (batch , h, seq, seq)

# (batch , h, seq_len, seq_len) * (batch, h, seq_len, embedding/h) 
# => (batch, h, seq_len, embedding/h) 
# => (batch, seq_len, h, embedding/h)
c = torch.matmul(a, v).transpose(1, 2)

# (batch, seq_len, embedding)
c = c.contiguous().view(c.size(0), c.size(1), -1)

参考资料

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在李宏毅的2020机器学习笔记中,有一个关于注意力机制(Attention)的部分。这部分内容主要介绍了生成模型(Generation)、注意力(Attention)、生成的技巧(Tips for Generation)以及指针网络(Pointer Network)。在生成模型中,主要讲述了如何生成一个有结构的对象。接下来介绍了注意力机制,包括一些有趣的技术,比如图片生成句子等。在生成的技巧部分,提到了一些新的技术以及可能遇到的问题和偏差,并给出了相应的解决方案。最后,稍微提到了强化学习。其中还提到了在输出"machine"这个单词时,只需要关注"机器"这个部分,而不必考虑输入中的"学习"这个部分。这样可以得到更好的结果。另外,还提到了关于产生"ei"的方法,其中有研究应用了连续动态模型自注意力(Self-attention)来学习位置编码的方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [2020李宏毅机器学习笔记-Condition Generation by RNN&Attention](https://blog.csdn.net/zn961018/article/details/117593813)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [李宏毅机器学习学习笔记:Self-attention](https://blog.csdn.net/weixin_44455827/article/details/128094176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值