当前位置:   article > 正文

【minGPT】注意力模块_自注意力机制模块

自注意力机制模块

1 理论理解

1.1 注意力机制(Attention)

注意力机制很像人类看图片的逻辑,当我们看一张图片的时候,我们并没有看图片的全部内容,而是将注意力集中在了图片的焦点上。用上了注意力机制,信息(如下面的图片)就不在单纯是信息本身,而是附加了焦点。

1.2 注意力机制的实现

运用注意力机制处理信息就是将信息和关注的维度点乘,或者说将信息投影到关注的维度。比如一件商品有质量,价格,颜色,外形,生产商,发货地点等信息,但是你特别关注商品的价格,那么所有商品的所有信息投影到你的需求上,基本只有价格影响你买还是不买。

1.3 自注意力机制

自注意力机制是为了找到信息内部联系的手段。比如随便一句话:

美国国务卿布林肯将于2月5日至6日访问中国,这是担任国务卿之后首次访华,也是拜登政府上台两年多来,访华级别最高的美国官员。

指的是美国国务卿布林肯,与句子中的其他信息关联就不大。为了找到这种联系,引入了自注意力机制。做法就是将信息映射到不同的维度,然后投影后的信息做点乘(投影)。

做个形象化的比喻,你在广东被人叫靓仔,在广西被人叫叼毛,本质上你还是你,包含你的肉体和灵魂。只是你在不同的空间,时间,以及叫法不同。为了找出这种本质,先把你扔到广东被人叫靓仔,然后把你扔到广西被人叫叼毛,然后把两个空间的你做点乘。

1.4 多头自注意力机制

我们都说人是复杂的,很难用好人,或者坏人来描述。所以要从不同的方面去解构,而且不能只看你一个人怎么看你,还要看很多人怎么看你。类比到多头自注意力机制就是通过多个人观察你,每个人观察的角度不同,关注的点也不同,然后汇总,得到一个比较完整的你。

1.5 因果自注意力

因为GPT是生成模型,是利用前面的信息生成后面的信息的,也就是后面的信息开始是不知道的。但是通过已有的信息我们可以推测未知的信息。

2 代码分析

  1. class CausalSelfAttention(nn.Module):
  2. """
  3. A vanilla multi-head masked self-attention layer with a projection at the end.
  4. It is possible to use torch.nn.MultiheadAttention here but I am including an
  5. explicit implementation here to show that there is nothing too scary here.
  6. """
  7. def __init__(self, config):
  8. super().__init__()
  9. assert config.n_embd % config.n_head == 0
  10. # key, query, value projections for all heads, but in a batch
  11. self.c_attn = nn.Linear(config.n_embd, 3 * config.n_embd)
  12. # output projection
  13. self.c_proj = nn.Linear(config.n_embd, config.n_embd)
  14. # regularization
  15. self.attn_dropout = nn.Dropout(config.attn_pdrop)
  16. self.resid_dropout = nn.Dropout(config.resid_pdrop)
  17. # causal mask to ensure that attention is only applied to the left in the input sequence
  18. self.register_buffer("bias", torch.tril(torch.ones(config.block_size, config.block_size))
  19. .view(1, 1, config.block_size, config.block_size))
  20. self.n_head = config.n_head
  21. self.n_embd = config.n_embd
  22. def forward(self, x):
  23. B, T, C = x.size() # batch size, sequence length, embedding dimensionality (n_embd)
  24. # calculate query, key, values for all heads in batch and move head forward to be the batch dim
  25.         #同一个信息映射到不同的空间
  26. q, k ,v = self.c_attn(x).split(self.n_embd, dim=2)
  27. k = k.view(B, T, self.n_head, C // self.n_head).transpose(1, 2) # (B, nh, T, hs)
  28. q = q.view(B, T, self.n_head, C // self.n_head).transpose(1, 2) # (B, nh, T, hs)
  29. v = v.view(B, T, self.n_head, C // self.n_head).transpose(1, 2) # (B, nh, T, hs)
  30. # causal self-attention; Self-attend: (B, nh, T, hs) x (B, nh, hs, T) -> (B, nh, T, T)
  31. att = (q @ k.transpose(-2, -1)) * (1.0 / math.sqrt(k.size(-1)))
  32. att = att.masked_fill(self.bias[:,:,:T,:T] == 0, float('-inf'))
  33. att = F.softmax(att, dim=-1)
  34. att = self.attn_dropout(att)
  35. y = att @ v # (B, nh, T, T) x (B, nh, T, hs) -> (B, nh, T, hs)
  36. y = y.transpose(1, 2).contiguous().view(B, T, C) # re-assemble all head outputs side by side
  37. # output projection
  38. y = self.resid_dropout(self.c_proj(y))
  39. return y

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/337446
推荐阅读
相关标签
  

闽ICP备14008679号