网站建设佰金手指科杰二六,手机网站主页推荐,脱发严重是什么原因引起的,网站建设定金合同范本目录
#x1f354; 注意力机制原理
1.1 注意力机制示意图
1.2 Attention计算过程
1.3 Attention计算逻辑
1.4 有无Attention模型对比
1.4.1 无Attention机制的模型
1.4.2 有Attention机制的模型
#x1f354; Self-attention演变过程
2.1 Self-attention介绍
2.2 S… 目录 注意力机制原理
1.1 注意力机制示意图
1.2 Attention计算过程
1.3 Attention计算逻辑
1.4 有无Attention模型对比
1.4.1 无Attention机制的模型
1.4.2 有Attention机制的模型 Self-attention演变过程
2.1 Self-attention介绍
2.2 Self-attention和Attention使用方法
2.3 Self attention机制的代码实现
2.3.1 Self-attetion实现步骤
2.3.2 代码解析 学习目标 知道注意力机制的工作流程 理解三个阶段过程 理解attention和self-attention之间的不同点 理解attention和self-attention的应用场景 注意力机制原理
1.1 注意力机制示意图
Attention机制的工作原理并不复杂我们可以用下面这张图做一个总结 1.2 Attention计算过程
阶段一: query 和 key 进行相似度计算得到一个query 和 key 相关性的分值阶段二: 将这个分值进行归一化(softmax)得到一个注意力的分布阶段三: 使用注意力分布和 value 进行计算得到一个融合注意力的更好的 value 值
为了更好的说明上面的情况, 我们通过注意力来做一个机器翻译(NMT) 的任务机器翻译中我们会使用 seq2seq 的架构每个时间步从词典里生成一个翻译的结果。就像下面这张图一样. 在没有注意力之前我们每次都是根据 Encoder 部分的输出结果来进行生成提出注意力后就是想在生成翻译结果时并不是看 Encoder 中所有的输出结果而是先来看看想生成的这部分和哪些单词可能关系会比较大关系大的我多借鉴些关系小的少借鉴些。就是这样一个想法我们看看该如何操作。
这里为了生成单词我们把 Decoder 部分输入后得到的向量作为 query把 Encoder 部分每个单词的向量作为 key。首先我们先把 query 和 每一个单词进行点乘scorequery⋅key得到相关性的分值。有了这些分值后我们对这些分值做一个softmax 得到一个注意力的分布。有了这个注意力我们就可以用它和 Encoder 的输出值 (value) 进行相乘得到一个加权求和后的值这个值就包含注意力的表示我们用它来预测要生成的词。
这个过程我们可以看看一个动图的事例理解一下: 动图演示 1.3 Attention计算逻辑
当然Attention 并不是只有这一种计算方式后来还有很多人找到了各种各样的计算注意力的方法, 比如我们上面介绍的三种计算规则, 但是从本质上它们都遵循着这个三步走的逻辑:
query 和 key 进行相似度计算得到一个query 和 key 相关性的分值将这个分值进行归一化(softmax)得到一个注意力的分布使用注意力分布和 value 进行计算得到一个融合注意力的更好的 value 值
1.4 有无Attention模型对比
1.4.1 无Attention机制的模型 文本处理领域的Encoder-Decoder框架可以这么直观地去理解可以把它看作适合处理由一个句子或篇章生成另外一个句子或篇章的通用处理模型。对于句子对我们的目标是给定输入句子Source期待通过Encoder-Decoder框架来生成目标句子Target。Source和Target可以是同一种语言也可以是两种不同的语言。而Source和Target分别由各自的单词序列构成 encoder顾名思义就是对输入句子Source进行编码将输入句子通过非线性变换转化为中间语义表示C 对于解码器Decoder来说其任务是根据句子Source的中间语义表示C和之前已经生成的历史信息,y_1, y_2…y_i-1来生成i时刻要生成的单词y_i 上述图中展示的Encoder-Decoder框架是没有体现出“注意力模型”的所以可以把它看作是注意力不集中的分心模型。为什么说它注意力不集中呢请观察下目标句子Target中每个单词的生成过程如下 其中f是Decoder的非线性变换函数。从这里可以看出在生成目标句子的单词时不论生成哪个单词它们使用的输入句子Source的语义编码C都是一样的没有任何区别。 每个yi都依次这么产生那么看起来就是整个系统根据输入句子Source生成了目标句子Target。如果Source是中文句子Target是英文句子那么这就是解决机器翻译问题的Encoder-Decoder框架如果Source是一篇文章Target是概括性的几句描述语句那么这是文本摘要的Encoder-Decoder框架如果Source是一句问句Target是一句回答那么这是问答系统或者对话机器人的Encoder-Decoder框架。由此可见在文本处理领域Encoder-Decoder的应用领域相当广泛。 问题点是: 语义编码C是由句子Source的每个单词经过Encoder 编码产生的这意味着不论是生成哪个单词还是其实句子Source中任意单词对生成某个目标单词yi来说影响力都是相同的这是为何说这个模型没有体现出注意力的缘由。这类似于人类看到眼前的画面但是眼中却没有注意焦点一样.
1.4.2 有Attention机制的模型 如果拿机器翻译来解释这个分心模型的Encoder-Decoder框架更好理解比如输入的是英文句子Tom chase JerryEncoder-Decoder框架逐步生成中文单词“汤姆”“追逐”“杰瑞”。在翻译“杰瑞”这个中文单词的时候分心模型里面的每个英文单词对于翻译目标单词“杰瑞”贡献是相同的很明显这里不太合理显然“Jerry”对于翻译成“杰瑞”更重要但是分心模型是无法体现这一点的这就是为何说它没有引入注意力的原因。 没有引入注意力的模型在输入句子比较短的时候问题不大但是如果输入句子比较长此时所有语义完全通过一个中间语义向量来表示单词自身的信息已经消失可想而知会丢失很多细节信息这也是为何要引入注意力模型的重要原因。 上面的例子中如果引入Attention模型的话应该在翻译“杰瑞”的时候体现出英文单词对于翻译当前中文单词不同的影响程度比如给出类似下面一个概率分布值Tom,0.3(Chase,0.2) (Jerry,0.5).每个英文单词的概率代表了翻译当前单词“杰瑞”时注意力分配模型分配给不同英文单词的注意力大小。这对于正确翻译目标语单词肯定是有帮助的因为引入了新的信息。 同理目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。这意味着在生成每个单词的时候原先都是相同的中间语义表示C会被替换成根据当前生成单词而不断变化的。理解Attention模型的关键就是这里即由固定的中间语义表示C换成了根据当前输出单词来调整成加入注意力模型的变化的。增加了注意力模型的Encoder-Decoder框架理解起来如下图所示: 即生成目标句子单词的过程成了下面的形式 而每个Ci可能对应着不同的源语句子单词的注意力分配概率分布比如对于上面的英汉翻译来说其对应的信息可能如下: f2函数代表Encoder对输入英文单词的某种变换函数比如如果Encoder是用的RNN模型的话这个f2函数的结果往往是某个时刻输入后隐层节点的状态值g代表Encoder根据单词的中间表示合成整个句子中间语义表示的变换函数一般的做法中g函数就是对构成元素加权求和即下列公式 Lx代表输入句子source的长度, a_ij代表在Target输出第i个单词时source输入句子中的第j个单词的注意力分配系数, 而hj则是source输入句子中第j个单词的语义编码, 假设Ci下标i就是上面例子所说的汤姆, 那么Lx就是3, h1f(Tom), h2f(Chase),h3f(jerry)分别输入句子每个单词的语义编码, 对应的注意力模型权值则分别是0.6, 0.2, 0.2, 所以g函数本质上就是加权求和函数, 如果形象表示的话, 翻译中文单词汤姆的时候, 数学公式对应的中间语义表示Ci的形成过程类似下图: Self-attention演变过程
2.1 Self-attention介绍
Self-attention就本质上是一种特殊的attention。这种应用在transformer中最重要的结构之一。前面我们介绍了attention机制它能够帮我们找到子序列和全局的attention的关系也就是找到权重值wi。Self-attention向对于attention的变化其实就是寻找权重值的wi过程不同。下面我们来看看self-attention的运算过程。 为了能够产生输出的向量yi self-attention其实是对所有的输入做了一个加权平均的操作这个公式和上面的attention是一致的。 j代表整个序列的长度并且j个权重的相加之和等于1。值得一提的是这里的 wij并不是一个需要神经网络学习的参数它是来源于xi和xj的之间的计算的结果这里wij的计算发生了变化)。它们之间最简单的一种计算方式就是使用点积的方式。 xi和xj是一对输入和输出。对于下一个输出的向量yi1我们有一个全新的输入序列和一个不同的权重值。 这个点积的输出的取值范围在负无穷和正无穷之间所以我们要使用一个softmax把它映射到 [01]之间并且要确保它们对于整个序列而言的和为1。 以上这些就是self-attention最基本的操作.
2.2 Self-attention和Attention使用方法
根据他们之间的重要区别, 可以区分在不同任务中的使用方法:
在神经网络中通常来说你会有输入层input应用激活函数后的输出层output在RNN当中你会有状态state。如果attention (AT) 被应用在某一层的话它更多的是被应用在输出或者是状态层上而当我们使用self-attentionSA这种注意力的机制更多的实在关注input上。Attention (AT) 经常被应用在从编码器encoder转换到解码器decoder。比如说解码器的神经元会接受一些AT从编码层生成的输入信息。在这种情况下AT连接的是**两个不同的组件**component编码器和解码器。但是如果我们用**SA**它就不是关注的两个组件它只是在关注你应用的**那一个组件**。那这里他就不会去关注解码器了就比如说在Bert中使用的情况我们就没有解码器。SA可以在一个模型当中被多次的、独立的使用比如说在Transformer中使用了18次在Bert当中使用12次。但是AT在一个模型当中经常只是被使用一次并且起到连接两个组件的作用。SA比较擅长在一个序列当中寻找不同部分之间的关系。比如说在词法分析的过程中能够帮助去理解不同词之间的关系。AT却更擅长寻找两个序列之间的关系比如说在翻译任务当中原始的文本和翻译后的文本。这里也要注意在翻译任务重SA也很擅长比如说Transformer。AT可以连接两种不同的模态比如说图片和文字。SA更多的是被应用在同一种模态上但是如果一定要使用SA来做的话也可以将不同的模态组合成一个序列再使用SA。其实有时候大部分情况SA这种结构更加的general在很多任务作为降维、特征表示、特征交叉等功能尝试着应用很多时候效果都不错。
2.3 Self attention机制的代码实现
2.3.1 Self-attetion实现步骤
里我们实现的注意力机制是现在比较流行的点积相乘的注意力机制self-attention机制的实现步骤 第一步: 准备输入第二步: 初始化参数第三步: 获取keyquery和value第四步: 给input计算attention score第五步: 计算softmax第六步: 给value乘上score第七步: 给value加权求和获取output
2.3.2 代码解析
import torch
import torch.nn as nn
import torch.nn.functional as F class SelfAttention(nn.Module): def __init__(self, embed_size, heads): # 初始化Self-Attention模块 # param embed_size: 嵌入向量的大小 # param heads: 多头注意力机制中的头数 super(SelfAttention, self).__init__() self.embed_size embed_size self.heads heads self.head_dim embed_size // heads # 每个头的维度大小 assert ( self.head_dim * heads embed_size ), Embedding size needs to be divisible by heads # 初始化三个线性层分别用于生成key, query, value self.values nn.Linear(self.head_dim, embed_size, biasFalse) self.keys nn.Linear(self.head_dim, embed_size, biasFalse) self.queries nn.Linear(self.head_dim, embed_size, biasFalse) self.fc_out nn.Linear(embed_size, embed_size) # 输出层 def forward(self, inputs): # 前向传播 # param inputs: 输入的序列数据 # return: 注意力加权后的输出 batch_size inputs.shape[0] seq_len inputs.shape[1] # 获取keyquery和value # 首先将输入数据重塑为多头的形状然后分别通过三个线性层 inputs inputs.reshape(batch_size, seq_len, self.heads, self.head_dim) values self.values(inputs) keys self.keys(inputs) queries self.queries(inputs) # 计算attention score # 使用点积来计算每个query和所有key之间的相似度 energy torch.einsum(nqhd,nkhd-nhqk, [queries, keys]) # 计算softmax # 在最后一个维度即seq_len维度上应用softmax得到注意力权重 attention torch.softmax(energy / (self.embed_size ** (1 / 2)), dim3) # 给value乘上score # 使用注意力权重对value进行加权 weighted_values torch.einsum(nhql,nlhd-nqhd, [attention, values]) # 给value加权求和获取output # 将多头的结果重塑回原始的序列形状并通过输出层 output weighted_values.reshape(batch_size, seq_len, self.embed_size) output self.fc_out(output) return output if __name__ __main__: embed_size 8 # 嵌入向量的大小 heads 2 # 多头注意力机制中的头数 seq_len 5 # 序列长度 batch_size 3 # 批量大小 # 随机初始化输入数据 inputs torch.randn(batch_size, seq_len, embed_size) # 创建一个Self-Attention实例 attention SelfAttention(embed_size, heads) # 前向传播 output attention(inputs) print(output.shape) 若能为您的学习之旅添一丝光亮不胜荣幸 期待您的宝贵意见让我们共同进步共同成长