网站建立安全连接失败快飞建站

当前位置: 首页 > news >正文

网站建立安全连接失败,快飞建站,麻阳住房和城乡建设局网站,怎样做网络推广链接目录 一、论文题目 二、背景与动机 三、卖点与创新 四、解决的问题 五、具体实现细节

  1. Transformer 架构的主要组件

  2. 注意力、自注意力#xff08;Self-Attention#xff09;到多头注意力#xff08;Multi-Head Attention#xff09; 注意力到底是做什么的Self-Attention到多头注意力Multi-Head Attention 注意力到底是做什么的一个例子。 自注意力 多头注意力 

  3. 位置编码Positional Encoding

  4. 编码器和解码器层Encoder Decoder Layers 编码器 解码器 六、一些好的资料 一、论文题目 Attention Is All You Need 二、背景与动机 在 Transformer 问世之前循环神经网络RNN和其变体如长短期记忆网络LSTM和门控循环单元GRU是处理序列数据的主流技术。这些模型通过递归地处理序列的每个元素来捕捉序列之间的依赖关系例如在机器翻译或文本生成任务中。然而RNN 有一个明显的缺点无法并行化序列中的步骤处理因为每个步骤都依赖于前一个步骤的输出。 三、卖点与创新 Transformer 模型的主要创新之处在于其独特的注意力机制——自注意力Self-Attention。这种机制允许模型在处理序列的每个元素时考虑到序列中的所有元素因此能够直接捕捉远距离的依赖关系。自注意力的这一特点使得 Transformer 模型在处理长序列时效果显著。 此外Transformer 模型还引入了以下几个关键的新颖概念 多头注意力Multi-Head Attention不只一次地计算自注意力而是多次并行地计算每一次都从不同的角度捕捉序列中的信息然后将所有的信息合并起来提供更全面的理解。 位置编码Positional Encoding由于模型缺乏递归结构和卷积层因此无法自然地利用输入序列的顺序信息。位置编码通过向输入添加额外的信息来解决这个问题使得模型能够考虑到序列的顺序。 层次化结构Transformer 通过堆叠多个注意力和前馈网络层来构建深度模型这使得它能够学习复杂的表示。
    四、解决的问题 Transformer 主要用来解决机器翻译等任务中之前 RNN 在处理长序列时效率低下的问题。由于其并行化的自注意力机制Transformer 可以显著加快训练速度。 五、具体实现细节 Transformer 的核心是基于注意力的编码器-解码器架构。编码器由一系列相同的层组成每一层都有两个主要的子层多头注意力层和简单的前馈神经网络。解码器也有类似的结构但在每一层中包含两个注意力层其中一个为Masked Multi-Head Attention用于在掩盖后续输入另一个为Muti-Head Attention层用于关注编码器的输出。 0. Transformer 架构的主要组件 自注意力Self-Attention允许模型在序列中的任何位置加权其他位置。多头注意力Multi-Head Attention将自注意力的输出拆分为多个头分别处理然后再合并。位置编码Positional Encoding在输入中添加位置信息因为 Transformer 没有递归和卷积结构去自然捕捉序列的顺序。编码器和解码器层Encoder Decoder LayersTransformer 模型的主体。前馈神经网络Feed-Forward Neural Network编码器和解码器层中的一个组成部分。最终的线性和 Softmax 层将解码器输出转换为预测。

  5. 注意力、自注意力Self-Attention到多头注意力Multi-Head Attention 一下内容引自Attention Is All You Need (Transformer) 论文精读 - 知乎,推荐。 注意力到底是做什么的一个例子。 其实“注意力”这个名字取得非常不易于理解。这个机制应该叫做“全局信息查询”。做一次“注意力”计算其实就跟去数据库了做了一次查询一样。假设我们现在有这样一个以人名为key键以年龄为value值的数据库 {张三: 18,张三: 20,李四: 22,张伟: 19 } 现在我们有一个query查询问所有叫“张三”的人的年龄平均值是多少。让我们写程序的话我们会把字符串“张三”和所有key做比较找出所有“张三”的value把这些年龄值相加取一个平均数。这个平均数是(1820)/219。 但是很多时候我们的查询并不是那么明确。比如我们可能想查询一下所有姓张的人的年龄平均值。这次我们不是去比较key 张三,而是比较key[0] 张。这个平均数应该是(182019)/319。 或许我们的查询会更模糊一点模糊到无法用简单的判断语句来完成。因此最通用的方法是把query和key各建模成一个向量。之后对query和key之间算一个相似度比如向量内积以这个相似度为权重算value的加权和。这样不管多么抽象的查询我们都可以把query, key建模成向量用向量相似度代替查询的判断语句用加权和代替直接取值再求平均值。“注意力”其实指的就是这里的权重。 把这种新方法套入刚刚那个例子里。我们先把所有key建模成向量可能可以得到这样的一个新数据库 {[1, 2, 0]: 18, # 张三[1, 2, 0]: 20, # 张三 [0, 0, 2]: 22, # 李四[1, 4, 0]: 19 # 张伟 } 假设key[0]1表示姓张。我们的查询“所有姓张的人的年龄平均值”就可以表示成向量[1, 0, 0]。用这个query和所有key算出的权重是 dot([1, 0, 0], [1, 2, 0]) 1 dot([1, 0, 0], [1, 2, 0]) 1 dot([1, 0, 0], [0, 0, 2]) 0 dot([1, 0, 0], [1, 4, 0]) 1之后我们该用这些权重算平均值了。注意算平均值时权重的和应该是1。因此我们可以用softmax把这些权重归一化一下再算value的加权和。 softmax([1, 1, 0, 1]) [13, 13, 0, 13] dot([13, 13, 0, 13], [18, 20, 22, 19]) 19 这样我们就用向量运算代替了判断语句完成了数据库的全局信息查询。那三个1/3就是query对每个key的注意力。 刚刚完成的计算差不多就是Transformer里的注意力这种计算在论文里叫做放缩点乘注意力Scaled Dot-Product Attention。它的公式是 我们先来看看在刚刚那个例子里究竟是什么。比较好理解其实就是key向量的数组也就是 K [[1, 2, 0], [1, 2, 0], [0, 0, 2], [1, 4, 0]] 同样就是value向量的数组。而在我们刚刚那个例子里value都是实数。实数其实也就是可以看成长度为1的向量。因此那个例子的应该是 V [[18], [20], [22], [19]] 在刚刚那个例子里我们只做了一次查询。因此准确来说我们的操作应该写成。 其中query 就是[1, 0, 0]了。 实际上我们可以一次做多组query。把所有打包成矩阵就得到了公式 等等这个是什么意思就是query和key向量的长度。由于query和key要做点乘这两种向量的长度必须一致。value向量的长度倒是可以不一致论文里把value向量的长度叫做。在我们这个例子里3,1。 为什么要用一个和成比例的项来放缩呢这是因为softmax在绝对值较大的区域梯度较小梯度下降的速度比较慢。因此我们要让被softmax的点乘数值尽可能小。而一般在较大时也就是向量较长时点乘的数值会比较大。除以一个和相关的量能够防止点乘的值过大。 刚才也提到其实是在算query和key的相似度。而算相似度并不只有求点乘这一种方式。另一种常用的注意力函数叫做加性注意力它用一个单层神经网络来计算两个向量的相似度。相比之下点乘注意力算起来快一些。出于性能上的考量论文使用了点乘注意力。 自注意力 以上注意力机制中通常涉及两个不同的序列一个是查询序列比如在机器翻译中的目标语言、另一个是键-值序列比如源语言。模型在生成查询序列的每个元素时会参考键-值序列来决定聚焦于哪些元素。 而在自注意力中查询、键和值都来自于同一个序列。这意味着模型在处理序列的每个元素时是在自身序列的上下文中进行的而不是在另一个序列的上下文中。自注意力的这种特性使其特别适用于捕捉序列内部的长距离依赖关系。 换句话说自注意力机制不依赖于源序列和目标序列之间的关系它可以在输入序列内部建立元素之间的关联。 自注意力通常通过以下步骤实现 对于序列中的每个元素比如一个句子中的每个单词模型通过可学习的线性变换生成三个不同的向量查询向量Query、键向量Key和值向量Value。自注意力计算每个查询向量与所有键向量的兼容性通常是通过点积得到的从而生成一个注意力分数。应用 softmax 函数到注意力分数上得到一个概率分布表明每个位置对当前位置的重要性。这些权重随后用于加权对应的值向量加权和就形成了该位置的输出向量。 多头注意力  多头注意力机制是自注意力的一个扩展它允许模型在不同的表示子空间中同时学习信息。多头注意力的工作原理 在单头自注意力中我们为序列中的每个元素生成一组查询Q、键K和值V向量。在多头注意力中我们将这个过程重复多次每个“头”一次每次使用不同的、可学习的线性变换。 对于每个头我们独立地进行自注意力计算。这意味着对于每个头我们根据该头的查询、键和值来计算注意力分数并使用这些分数来加权值向量得到该头的输出。 一旦所有头的自注意力计算完成将每个头产生的输出向量拼接起来并对其应用另一个可学习的线性变换这样就生成了最终的多头注意力输出。 代码示例  import torch import torch.nn as nn import torch.nn.functional as Fclass SelfAttention(nn.Module):def init(self, embed_size, heads):super(SelfAttention, self).init()self.embed_size embed_sizeself.heads heads # head的数量self.head_dim embed_size // headsassert (self.head_dim * heads embed_size), Embed size needs to be divisible by headsself.values nn.Linear(self.head_dim, self.head_dim, biasFalse)self.keys nn.Linear(self.head_dim, self.head_dim, biasFalse)self.queries nn.Linear(self.head_dim, self.head_dim, biasFalse)self.fc_out nn.Linear(heads * self.head_dim, embed_size)def forward(self, values, keys, query, mask):N query.shape[0]value_len, key_len, query_len values.shape[1], keys.shape[1], query.shape[1]# Split the embedding into self.heads different piecesvalues values.reshape(N, value_len, self.heads, self.head_dim)keys keys.reshape(N, key_len, self.heads, self.head_dim)queries query.reshape(N, query_len, self.heads, self.head_dim)values self.values(values)keys self.keys(keys)queries self.queries(queries)# Self-attentionenergy torch.einsum(nqhd,nkhd-nhqk, [queries, keys]) # Query-Key dot productif mask is not None:energy energy.masked_fill(mask 0, float(-1e20))attention torch.softmax(energy / (self.embed_size ** (12)), dim3)out torch.einsum(nhql,nlhd-nqhd, [attention, values]).reshape(N, query_len, self.heads * self.head_dim)out self.fc_out(out)return out 注torch.einsum用法torch.einsum用法-CSDN博客 再详细一点可好torch.einsum(nqhd,nkhd-nhqk, [queries, keys])的等价代码如下 import torch# 假设 queries 的形状为 (batch_size, num_queries, hidden_dim)

    假设 keys 的形状为 (batch_size, num_keys, hidden_dim)# 使用等价代码实现

    batch_size, num_queries, hidden_dim queries.size() num_keys keys.size(1)# 将 queries 和 keys 进行扩展以匹配计算的维度 expanded_queries queries.unsqueeze(2).expand(batch_size, num_queries, num_keys, hidden_dim) expanded_keys keys.unsqueeze(1).expand(batch_size, num_queries, num_keys, hidden_dim)# 逐元素相乘得到内积结果 dot_product torch.mul(expanded_queries, expanded_keys)# 将最后两个维度进行交换得到结果 result dot_product.permute(0, 2, 1, 3)# result 的形状为 (batch_size, num_keys, num_queries, hidden_dim)

  6. 位置编码Positional Encoding 位置编码Positional Encoding的作用是为模型提供关于单词在序列中位置的信息。由于 Transformer 的自注意力机制并不区分序列中不同位置的元素即它本身不像循环神经网络RNN那样具有处理序列的固有顺序性所以需要一种方法来保证模型能够利用单词的顺序信息。 位置编码通过向输入嵌入Embeddings添加额外的信息来解决这个问题。这使得模型能够根据单词在序列中的位置以及单词的实际含义来进行计算和学习。位置编码是以一种特定的模式添加的它对每个位置上的嵌入向量进行修改使得不同位置的嵌入向量能够反映出它们的位置关系。 在原始的 Transformer 论文中位置编码使用正弦和余弦函数的固定频率来生成。对于每个维度 (d) 位置编码 (PE) 采用以下公式 其中 (pos) 是位置索引。(i) 是维度索引。() 是模型中单个词向量的维度。 直觉上这种编码方法为每个维度提供了一个独特的“波长”使得模型对于不同位置的词可以有区分性的理解。使用正弦和余弦函数是因为它们相对于位置的偏移具有周期性并且能够让模型学习到相对位置信息。 位置编码通常与词嵌入向量相加结果即作为 Transformer 模型的输入。这种做法保证了模型在处理单词时同时考虑了单词的含义和它们在序列中的位置。由于位置编码和词嵌入是相加的因此它们必须具有相同的维度。 代码如下 class PositionalEncoding(nn.Module):def init(self, embed_size, max_len, device):super(PositionalEncoding, self).init()self.encoding torch.zeros(max_len, embed_size).to(device)for pos in range(max_len):for i in range(0, embed_size, 2):self.encoding[pos, i] math.sin(pos / (10000 ** ((2 * i)/embed_size)))self.encoding[pos, i 1] math.cos(pos / (10000 ** ((2 * (i 1))/embed_size)))def forward(self, x):return x self.encoding[:x.size(0)]

  7. 编码器和解码器层Encoder Decoder Layers 编码器 Transformer 编码器的结构由多个相同的层layer堆叠而成每一层都有两个主要子模块以及一个残差连接跟随每个子模块最后是层归一化Layer Normalization。每个编码器层包含以下部分 自注意力Self-Attention子层 - 该层允许编码器在生成每个单词的表示时考虑输入序列中的所有位置。每个位置的输出是对整个序列的自注意力分数加权和。残差连接和层归一化 - 自注意力子层的输出与其输入相加残差连接接着应用层归一化。前馈网络Feed-Forward Network - 一个由两个线性变换组成的网络中间有一个 ReLU 激活函数。这个前馈网络是逐位置应用的也就是说每个位置的表示都会通过相同的前馈网络但是不同位置之间是独立的。残差连接和层归一化 - 前馈网络的输出与其输入相加残差连接接着应用层归一化。 简易代码如下 class EncoderLayer(nn.Module):def init(self, embed_size, heads, forward_expansion, dropout, device):super(EncoderLayer, self).init()self.attention SelfAttention(embed_size, heads)self.norm1 nn.LayerNorm(embed_size)self.norm2 nn.LayerNorm(embed_size)self.feed_forward nn.Sequential(nn.Linear(embed_size, forward_expansion * embed_size),nn.ReLU(),nn.Linear(forward_expansion * embed_size, embed_size))self.dropout nn.Dropout(dropout)def forward(self, x, mask):attention self.attention(x, x, x, mask)x self.dropout(self.norm1(attention x))forward self.feed_forward(x)out self.dropout(self.norm2(forward x))return out 解码器 Transformer 的解码器架构设计用来将编码器的输出转换成最终的输出序列比如在机器翻译中将编码的源语言句子转换成目标语言。解码器由多个相同的层堆叠而成每层包含以下三个主要部分 Masked Self-Attention Layer: 与编码器中的自注意力层类似但使用了掩码mask来防止对未来位置的信息进行注意力计算即在生成第 i 个单词时解码器只能看到第 1 到 i 个单词。 Encoder-Decoder Attention Layer: 这个层使得解码器能够关注编码器的输出。解码器的查询Q来自于前面的 masked self-attention 层的输出而键K和值V来自于编码器的输出。 Feed-Forward Neural Network: 与编码器中的前馈神经网络相同。 每个子层都有一个残差连接并且之后跟着一个层归一化layer normalization。最终解码器的输出传递给一个线性层和一个 softmax 层来生成输出序列。 以下是使用 PyTorch 实现的 Transformer 解码器的简化代码 import torch import torch.nn as nn import torch.nn.functional as Fclass TransformerDecoderLayer(nn.Module):def init(self, embed_size, heads, forward_expansion, dropout, device):super(TransformerDecoderLayer, self).init()self.self_attention SelfAttention(embed_size, heads)self.norm1 nn.LayerNorm(embed_size)self.encoder_decoder_attention SelfAttention(embed_size, heads)self.norm2 nn.LayerNorm(embed_size)self.feed_forward nn.Sequential(nn.Linear(embed_size, forward_expansion * embed_size),nn.ReLU(),nn.Linear(forward_expansion * embed_size, embed_size))self.norm3 nn.LayerNorm(embed_size)self.dropout nn.Dropout(dropout)def forward(self, x, value, key, src_mask, trg_mask):# Masked self attentionattention self.self_attention(x, x, x, trg_mask)query self.dropout(self.norm1(attention x))# Encoder-decoder attentionattention self.encoder_decoder_attention(query, key, value, src_mask)query self.dropout(self.norm2(attention query))# Feed forwardout self.dropout(self.norm3(self.feed_forward(query) query))return outclass TransformerDecoder(nn.Module):def init(self, target_vocab_size, embed_size, num_layers, heads, forward_expansion, dropout, device, max_length):super(TransformerDecoder, self).init()self.device deviceself.word_embedding nn.Embedding(target_vocab_size, embed_size)self.position_embedding nn.Embedding(max_length, embed_size)self.layers nn.ModuleList([TransformerDecoderLayer(embed_size, heads, forward_expansion, dropout, device)for _ in range(num_layers)])self.fc_out nn.Linear(embed_size, target_vocab_size)self.dropout nn.Dropout(dropout)def forward(self, x, enc_out, src_mask, trg_mask):N, seq_length x.shapepositions torch.arange(0, seq_length).expand(N, seq_length).to(self.device)x self.dropout(self.word_embedding(x) self.position_embedding(positions))for layer in self.layers:x layer(x, enc_out, enc_out, src_mask, trg_mask)out self.fc_out(x)return out 注在解码器中在输出第t1个单词时模型不应该提前知道t1时刻之后的信息。因此应该只保留t时刻之前的信息遮住后面的输入。这可以通过添加掩码实现。添加掩码的一个不严谨的示例如下表所示 输入输出(y1, –, –, –)y2(y1, y2, –, –)y3(y1, y2, y3, –)y4 这就是为什么解码器的多头自注意力层前面有一个masked。在论文中mask是通过令注意力公式的softmax的输入为−∞来实现的softmax的输入为−∞注意力权重就几乎为0被遮住的输出也几乎全部为0。每个mask都是一个上三角矩阵。 注transformer训练时是并行的并行输出所有时刻的预测结果计算损失。而推理时是串行的需要每次把前i个单词输入预测第i1个然后把预测出来的第i1个单词加入输入预测后续内容。 六、一些好的资料 Attention Is All You Need (Transformer) 论文精读 - 知乎Attention Is All You Need (Transformer) 是当今深度学习初学者必读的一篇论文。但是这篇工作当时主要是用于解决机器翻译问题有一定的写作背景对没有相关背景知识的初学者来说十分难读懂。在这篇文章里我…https://zhuanlan.zhihu.com/p/569527564详细Transformer完整版_transformer论文-CSDN博客文章浏览阅读7k次点赞7次收藏41次。原文链接https://blog.csdn.net/longxinchen_ml/article/details/86533005 作者 龙心尘 时间2019年1月 出处https://blog.csdn.net/longxinchen_ml/article/details/_transformer论文https://blog.csdn.net/qq_43703185/article/details/120287945