Attention 机制,又称为注意力机制,顾名思义,是一种能让模型对重要信息重点关注并充分学习吸收的技术。通俗的讲就是把注意力集中放在重要的点上,而忽略其他不重要的因素。根据应用场景的不同,Attention 分为空间注意力和时间注意力,前者用于图像处理,后者用于自然语言处理。
Attention 本质
Attention(注意力)机制如果浅层的理解,跟他的名字非常匹配。他的核心逻辑就是「从关注全部到关注重点」。
Attention 机制很像人类看图片的逻辑,当我们看一张图片的时候,我们并没有看清图片的全部内容,而是将注意力集中在了图片的焦点上。大家看一下下面这张图:
我们一定会看清「锦江饭店」4 个字,如下图:
但是我相信没人会意识到「锦江饭店」上面还有一串「电话号码」,也不会意识到「喜运来大酒家」,如下图:
所以,当我们看一张图片的时候,其实是这样的:
上面所说的,我们的视觉系统就是一种 Attention机制,将有限的注意力集中在重点信息上,从而节省资源,快速获得最有效的信息。
Attention 机制最早是在计算机视觉里应用的,随后在 NLP 领域也开始应用了,真正发扬光大是在 NLP 领域,因为 2018 年 BERT 和 GPT 的效果出奇的好,进而走红。而 Transformer 和 Attention 这些核心开始被大家重点关注。
如果用图来表达 Attention 的位置大致是下面的样子:
Attention 优点
之所以要引入 Attention 机制,主要是 3 个原因:
- 参数少
- 速度快
- 效果好
参数少
模型复杂度跟 CNN、RNN 相比,复杂度更小,参数也更少。所以对算力的要求也就更小。
速度快
Attention 解决了 RNN 不能并行计算的问题。Attention 机制每一步计算不依赖于上一步的计算结果,因此可以和 CNN 一样并行处理。即它可以并行加速计算。
效果好
在 Attention 机制引入之前,有一个问题大家一直很苦恼:长距离的信息会被弱化,就好像记忆能力弱的人,记不住过去的事情是一样的。
Attention 是挑重点,就算文本比较长,也能从中间抓住重点,不丢失重要的信息。
由于每个目标词是直接与句子中所有词分别计算相关度(attention)的,所以解决了传统的 RNN 模型中长距离依赖的问题。
通过 attention,可以将两个距离较远的词之间的距离拉近为 1 直接计算词的相关度,而传统的 RNN 模型中,随着距离的增加,词之间的相关度会被削弱。
Attention 原理
在 Attention 机制中,有 Query、Key 和 Value 三个重要的概念,它们共同作用来帮助模型专注于输入序列中与当前输出最相关的部分。
Query (查询):表示要关注或检索的目标信息。Query 自身网络通常是一个线性变换层(全连接层),它将输入序列中的每个词嵌入向量映射到一个新的向量空间。
Key (键):表示要与 Query 进行匹配或比较的信息来源。在文本处理中,你可以理解为每个 token 对应一个 key,Key 自身网络通常也是一个线性变换层(全连接层),它将输入序列中的每个词嵌入向量映射到一个新的向量空间。
Value (值):表示与 Query 和 Key 匹配的具体信息。在文本处理中,它和 key 网络处理一样,value 网络通常也是一个线性变换层,它将输入序列中的每个词嵌入向量映射到一个新的向量空间。
Attention 工作流程
Attention 机制的工作流程如下:
- 将输入序列中的每个词嵌入向量映射为 Query、Key 和 Value 向量。
- 计算每个 Query 与所有 Key 的点积,并使用 softmax 函数对结果进行归一化。得到的归一化结果就是每个 Query 对应的 Attention 分数。
- 将每个 Value 乘以与其对应的 Attention 分数,然后将所有乘积相加。得到的最终结果就是 Attention 机制的输出。
如上流程说明可能云里雾里,直接上图:
以中文常用的预训练模型 bert-case-chinese 为例,打印其内部一层 transformer 结构中 attention 模块,具体如下:
(attention): BertAttention(
(self): BertSelfAttention(
(query): Linear(in_features=768, out_features=768, bias=True)
(key): Linear(in_features=768, out_features=768, bias=True)
(value): Linear(in_features=768, out_features=768, bias=True)
(dropout): Dropout(p=0.1, inplace=False)
)
(output): BertSelfOutput(
(dense): Linear(in_features=768, out_features=768, bias=True)
(LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
(dropout): Dropout(p=0.1, inplace=False)
)
)
可以看出 bert-case-chinese 内部的 attention 采用 self-attention 自注意力机制,query, key, value 这些是三个线性层,分别将输入隐藏维度(768)投影为每个词语的单独查询、键和值向量。这些向量用于计算词语之间的注意力分数。