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

备案网站出售怎么编辑网站源代码

备案网站出售,怎么编辑网站源代码,以下区域不属于官方网站,工信部网站备案举报Transformer 1. 注意力机制 在语言建模中#xff0c;注意力(attention)是一个关键机制#xff0c;用于在给定上下文中访问相关信息以进行预测。注意力机制允许模型根据输入上下文中的重要信息来加权关注不同的部分#xff0c;并根据其重要性来决定对不同部分的关注程度。 … Transformer 1. 注意力机制 在语言建模中注意力(attention)是一个关键机制用于在给定上下文中访问相关信息以进行预测。注意力机制允许模型根据输入上下文中的重要信息来加权关注不同的部分并根据其重要性来决定对不同部分的关注程度。 例如对于一个给定的输入句子语言模型可以使用注意力机制来确定在生成下一个单词时应该关注句子中的哪些部分。当模型预测下一个单词时它可以根据输入句子中不同位置的单词的重要性来调整注意力权重。这意味着模型可以更有针对性地关注与当前预测相关的上下文信息而不是简单地平均考虑整个句子。 通过使用注意力机制语言模型可以更好地捕捉输入上下文中的关联和重要信息从而提高预测的准确性。注意力使模型能够动态地根据不同输入示例的需要来聚焦不同的信息从而提高了语言建模的效果。 上图示例中是一个预测下一个字母是A还是B的游戏规则是如果全是A则下一个字母是A只要有一个是B则下一个字母是B注意力在这里的作用就是可以访问之前的所有位置信息。 循环神经网络(RNN)在处理长期依赖性和保持上下文方面存在一些困难。由于RNN的隐藏状态是通过时间步骤递归传递的较早的输入在经过一系列的时间步骤后会逐渐消失而只有较近的输入对当前预测有较大的影响。对于较长的上下文依赖性RNN可能无法有效地记住所有位置的信息。当需要跨越较长的时间步骤进行预测时RNN可能会遇到困难因为它们在传递信息时可能会丢失重要的上下文。虽然RNN本身可能在处理简化的例子时能够记住上下文并进行预测但在实践中特别是对于更复杂的问题和长期依赖性这变得更加困难。然而可以通过手动调整权重或使用更复杂的RNN变体例如长短时记忆网络(LSTM)或门控循环单元(GRU)来改善RNN的上下文记忆能力。这些变体通过引入额外的机制来帮助模型更好地捕捉长期依赖性并记住重要的上下文信息但本质上不如注意力机制直接有效。 1.1. Bahdanau 注意力 提出注意力机制的论文 Neural Machine Translation by Jointly Learning to Align and Translate Bahdanau注意力是一种用于序列到序列(seq2seq)模型的注意力机制由Bahdanau等人在2014年提出。它旨在解决神经机器翻译任务中的上下文对齐和长距离依赖性建模的问题。 传统的seq2seq模型使用编码器-解码器结构其中编码器将输入序列编码为固定长度的上下文向量然后解码器使用该上下文向量生成输出序列。然而这种固定长度的上下文向量无法有效地捕捉输入序列的不同位置对生成每个输出的贡献程度。 图中计算公式如下 s i f ( s i − 1 , y i − 1 , c i ) c i ∑ j 1 T x α i j h j α i j exp ⁡ ( e i j ) ∑ k 1 T x exp ⁡ ( e i k ) e i j a ( s i − 1 , h j ) \begin{aligned} s_i f(s_{i-1}, y_{i-1}, c_i) \\ c_i \sum_{j1}^{T_x} \alpha_{ij} h_j \\ \alpha_{ij} \frac{\exp(e_ij)}{\sum_{k1}^{T_x} \exp(e_ik)} \\ e_{ij} a(s_{i-1}, h_j) \end{aligned} si​ci​αij​eij​​f(si−1​,yi−1​,ci​)j1∑Tx​​αij​hj​∑k1Tx​​exp(ei​k)exp(ei​j)​a(si−1​,hj​)​ Bahdanau注意力机制通过引入一个可学习的注意力权重来解决这个问题。具体而言它在解码器的每个时间步骤上计算一个注意力分布该分布决定了编码器输出中不同位置的重要性。这个注意力分布是通过将解码器的当前隐藏状态与编码器的所有隐藏状态进行比较来计算的。计算注意力分布的常见方法是使用一个前馈神经网络该网络接受解码器隐藏状态和编码器隐藏状态作为输入并输出一个标量分数。这些分数经过softmax函数处理得到注意力权重表示了每个编码器隐藏状态对当前解码器步骤的重要性。使用Bahdanau注意力机制解码器可以根据输入序列中不同位置的重要性加权关注并在生成每个输出时利用加权的上下文信息。这样模型能够更好地处理长距离依赖性和上下文对齐提高了翻译质量和其它序列生成任务的性能。 Bahdanau注意力机制的提出对于注意力机制的研究产生了重要影响并为后续的改进和变体奠定了基础。 Badhanau 注意力 Pytorch 实现 import torch import torch.nn as nn import torch.nn.functional as Fclass BahdanauAttention(nn.Module):def __init__(self, hidden_size):super(BahdanauAttention, self).__init__()self.hidden_size hidden_sizeself.W nn.Linear(hidden_size, hidden_size, biasFalse)self.U nn.Linear(hidden_size, hidden_size, biasFalse)self.v nn.Linear(hidden_size, 1, biasFalse)def forward(self, encoder_outputs, decoder_hidden):decoder_hidden decoder_hidden.unsqueeze(1) # (batch_size, 1, hidden_size)encoder_outputs self.W(encoder_outputs) # (batch_size, seq_len, hidden_size)attention_scores self.v(torch.tanh(encoder_outputs self.U(decoder_hidden))) # (batch_size, seq_len, 1)attention_weights F.softmax(attention_scores, dim1) # (batch_size, seq_len, 1)context_vector torch.sum(attention_weights * encoder_outputs, dim1) # (batch_size, hidden_size)return context_vector, attention_weights# 创建注意力对象 attention BahdanauAttention(hidden_size256)# 模拟输入数据 encoder_outputs torch.randn(32, 10, 256) # (batch_size, seq_len, hidden_size) decoder_hidden torch.randn(32, 256) # (batch_size, hidden_size)# 前向传播 context_vector, attention_weights attention(encoder_outputs, decoder_hidden)# 打印输出结果 print(Context vector shape:, context_vector.shape) # (32, 256) print(Attention weights shape:, attention_weights.shape) # (32, 10, 1)1.2. 缩放点积注意力 注意力机制的变体 Effective Approaches to Attention-based Neural Machine Translation 在Loung提出的Global Attention中计算如下 a t ( s ) align ( h t , h ˉ s ) exp ⁡ ( score ( h t , h ˉ s ) ) ∑ s ′ exp ⁡ ( score ( h t , h ˉ s ′ ) ) \begin{aligned} a_t(s) \text{align}(h_t, \bar{h}_s) \\ \frac{\exp(\text{score} (h_t, \bar{h}_s))}{\sum_{s^{\prime}} \exp(\text{score} (h_t, \bar{h}_{s^{\prime}}))} \end{aligned} at​(s)​align(ht​,hˉs​)∑s′​exp(score(ht​,hˉs′​))exp(score(ht​,hˉs​))​​ score的计算方式有三种 score ( h t , h ˉ s ) { h t T h ˉ x dot h t T W a h ˉ x general v a T tanh ⁡ ( W a [ h t T ; h ˉ x ] ) concat \text{score}(h_t, \bar{h}_s) \begin{cases} h_t^T \bar{h}_x \text{dot} \\ h_t^T W_a \bar{h}_x \text{general} \\ v_a^T \tanh (W_a [h_t^T; \bar{h}_x ]) \text{concat} \end{cases} score(ht​,hˉs​)⎩ ⎨ ⎧​htT​hˉx​htT​Wa​hˉx​vaT​tanh(Wa​[htT​;hˉx​])​dotgeneralconcat​ 其中 W a W_a Wa​ 和 v a v_a va​ 都是可学习的参数特别地general 也称为缩放点积(scaled dot product)注意力等价于 ( W k h t ) T ( W q h ˉ x ) (W_k h_t)^T (W_q \bar{h}_x) (Wk​ht​)T(Wq​hˉx​) dot使用点乘计算的好处是模型简单没有额外的参数。点乘的方法要求编码器的隐状态和解码器的隐状态维度相同并强制它们在同一个空间中。general是点乘方法的一个扩展由于不同语言的隐状态空间可能会存在区别强行将它们约束在同一个空间中可能并不合适。general方法的本质是在编码器隐状态和解码器隐状态之间做一个线性转换然后计算点乘。concat是将编码器隐状态和解码器隐状态进行拼接得到的向量。 Luong 注意力 Pytorch 实现 import torch import torch.nn as nn import torch.nn.functional as Fclass LuongAttention(nn.Module):def __init__(self, hidden_size, attention_typedot):super(LuongAttention, self).__init__()self.hidden_size hidden_sizeself.attention_type attention_typeif attention_type dot:self.dot Trueelif attention_type general:self.W nn.Linear(hidden_size, hidden_size, biasFalse)self.dot Falseelif attention_type concat:self.W nn.Linear(hidden_size * 2, hidden_size, biasFalse)self.v nn.Linear(hidden_size, 1, biasFalse)self.dot Falseelse:raise ValueError(Invalid attention type.)def forward(self, encoder_outputs, decoder_hidden):decoder_hidden decoder_hidden.unsqueeze(1) # (batch_size, 1, hidden_size)if self.attention_type dot:attention_scores torch.bmm(encoder_outputs, decoder_hidden.transpose(1, 2)) # (batch_size, seq_len, 1)elif self.attention_type general:attention_scores torch.bmm(self.W(encoder_outputs), decoder_hidden.transpose(1, 2)) # (batch_size, seq_len, 1)elif self.attention_type concat:decoder_hidden decoder_hidden.expand(-1, encoder_outputs.size(1), -1) # (batch_size, seq_len, hidden_size)concat_inputs torch.cat((encoder_outputs, decoder_hidden), dim2) # (batch_size, seq_len, hidden_size * 2)attention_scores self.v(torch.tanh(self.W(concat_inputs))) # (batch_size, seq_len, 1)else:raise ValueError(Invalid attention type.)attention_weights F.softmax(attention_scores, dim1) # (batch_size, seq_len, 1)context_vector torch.sum(attention_weights * encoder_outputs, dim1) # (batch_size, hidden_size)return context_vector, attention_weights# 创建注意力对象 attention LuongAttention(hidden_size256, attention_typedot)# 模拟输入数据 encoder_outputs torch.randn(32, 10, 256) # (batch_size, seq_len, hidden_size) decoder_hidden torch.randn(32, 256) # (batch_size, hidden_size)# 前向传播 context_vector, attention_weights attention(encoder_outputs, decoder_hidden)# 打印输出结果 print(Context vector shape:, context_vector.shape) # (32, 256) print(Attention weights shape:, attention_weights.shape) # (32, 10, 1)1.3. 自注意力 自注意力及其可视化 Attention Is All You Need The Illustrated Transformer 自注意力(Self-Attention)是一种注意力机制的变体它引入了自我关注的概念。在传统的注意力机制中通过计算查询(query)和键(key)之间的相关性来为每个查询分配权重然后使用这些权重对值(value)进行加权求和。而在自注意力中每个单词既是查询又是键因此可以同时计算它与序列中其他单词之间的相关性得分。 通过将每个单词作为查询和键自注意力能够捕捉到单词与其他单词之间的相互关系。它可以计算每个单词与整个序列中其他单词的相关性得分并根据这些得分分配注意力权重。这样每个单词都可以考虑到序列中所有其他单词的信息而不仅仅是前面的单词。自注意力的优点在于它能够捕捉到单词之间的长距离依赖关系因为每个单词都可以直接与其他单词进行交互。这使得自注意力在处理自然语言处理任务时非常强大特别是对于需要考虑上下文信息的任务如机器翻译和文本摘要。 自注意力计算公式如下 Attention ( Q , K , V ) softmax ( Q K T d k ) V \text{Attention}(Q, K, V) \text{softmax} \left( \frac{Q K^T}{\sqrt{d_k}} \right) V Attention(Q,K,V)softmax(dk​ ​QKT​)V Q E W Q , K E W K , V E W V Q E W^Q, K E W^K, V E W^V QEWQ,KEWK,VEWV 使用 d k \sqrt{d_k} dk​ ​进行归一化有助于控制softmax的范围尺度使其更平缓。在自注意力中使用softmax函数来将注意力权重进行归一化以确保它们的总和为1。这样可以使得每个位置的注意力权重表示其在整个序列中的相对重要性。然而当注意力权重的值分布不平衡时即某些权重远大于其他权重时softmax函数可能会产生一个非常尖锐的峰值(peaked)。这意味着少数位置会集中获得大部分的注意力而其他位置则得到很少的注意力。 为了避免这种情况增加一个缩放因子 d k \sqrt{d_k} dk​ ​(value-dependent scaling factor)将注意力权重进行归一化。 d k \sqrt{d_k} dk​ ​是根据值(value)的信息来调整注意力权重的尺度。通过与值相关联 d k \sqrt{d_k} dk​ ​可以帮助控制softmax函数的尺度使得注意力权重更平缓地分布。通过引入 d k \sqrt{d_k} dk​ ​进行归一化可以减轻softmax函数产生尖锐峰值的问题。这有助于确保每个位置获得适当的关注并更好地平衡注意力分配。 时间复杂度分析 1.4. 多头自注意力 多头自注意力及其可视化 Attention Is All You Need The Illustrated Transformer 尽管自注意力理论上可以学习关注多个词元(token)但在实践中softmax分布往往会变得尖锐。具体来说在自注意力机制中通过应用softmax函数来计算注意力权重以确保它们的总和为1。这样可以使得每个位置的注意力权重表示其在整个输入序列中的相对重要性。然而当注意力权重的值分布不平衡时即某些权重远大于其他权重时softmax函数可能会产生一个非常尖锐的分布。这意味着少数位置会集中获得大部分的注意力而其他位置则得到很少的注意力。这种尖锐的分布可能导致问题其中只有少数位置被有效地关注而其他位置的信息被忽略或弱化。这可能会限制模型的表达能力并导致注意力分配的不平衡。 在单个层级内部使用多个自注意力头部也可以提供帮助。这就是多头自注意力(Multi-Head Self-Attention)。在自注意力机制中可以在单个层级内使用多个自注意力头部。每个头部都可以学习不同的关注模式和特征表示。通过引入多个头部模型可以同时从不同的表示空间中学习并捕捉输入序列中更丰富的关系和结构。每个头部都有自己的参数矩阵用于计算注意力权重和值的加权和。这样可以使每个头部能够独立地学习和表示不同的关注模式。多个头部的输出可以通过连接或拼接的方式进行合并形成单个层级的最终输出。在单个层级内使用多个自注意力头部可以增加模型的表达能力并允许模型在更细粒度的层面上进行特征提取和关注。这有助于模型更好地捕捉输入序列中的多样性和复杂性提高模型的性能和表示能力。 尽管单个层级内的自注意力机制本身已经有助于模型的表达能力但通过使用多个自注意力头部可以在单个层级内进一步增强模型的学习能力和表示能力。 多头自注意力计算公式如下 MultiHead ( Q , K , V ) Concat ( head 1 , ⋯ , head h ) W O where  head i Attention ( Q W i Q , K W i K , V W i V ) \begin{aligned} \text{MultiHead}(Q, K, V) \text{Concat}(\text{head}_1, \cdots, \text{head}_h) W^O \\ \text{where } \text{head}_i \text{Attention}(Q W_i^Q, K W_i^K, V W_i^V) \end{aligned} MultiHead(Q,K,V)where headi​​Concat(head1​,⋯,headh​)WOAttention(QWiQ​,KWiK​,VWiV​)​ 多头自注意力的 Pytorch 实现 import torch import torch.nn as nnclass MultiHeadAttention(nn.Module):def __init__(self, d_model, num_heads):super(MultiHeadAttention, self).__init__()self.num_heads num_headsself.d_model d_modelself.head_dim d_model // num_headsself.query_linear nn.Linear(d_model, d_model)self.key_linear nn.Linear(d_model, d_model)self.value_linear nn.Linear(d_model, d_model)self.output_linear nn.Linear(d_model, d_model)def forward(self, query, key, value):batch_size query.size(0)# Linear transformations for query, key, and valuequery self.query_linear(query)key self.key_linear(key)value self.value_linear(value)# Reshape query, key, and value for multi-head attentionquery query.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2)key key.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2)value value.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2)# Compute attention scoresscores torch.matmul(query, key.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.head_dim, dtypetorch.float32))attention_weights torch.softmax(scores, dim-1)# Apply attention weights to valueattended_values torch.matmul(attention_weights, value)# Concatenate and reshape attended valuesattended_values attended_values.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)# Linear transformation for outputoutput self.output_linear(attended_values)return output# Create input tensors batch_size 2 seq_length 5 d_model 64 num_heads 4query torch.randn(batch_size, seq_length, d_model) key torch.randn(batch_size, seq_length, d_model) value torch.randn(batch_size, seq_length, d_model)# Create multi-head attention module multihead_attention MultiHeadAttention(d_model, num_heads)# Compute multi-head attention output multihead_attention(query, key, value)print(output.shape) # Output shape: (batch_size, seq_length, d_model)2. 位置编码 由于自注意力机制是基于元素之间的相对位置来计算注意力权重的无法隐式地捕捉序列中的顺序信息。因此在使用自注意力之前需要添加位置编码如果没有位置编码会导致模型无法区分不同位置上的元素。位置编码的引入确保了模型在计算注意力时考虑到了位置信息。 从直觉上我们可以使用绝对编码即将每个序列位置编码为整数并将其添加到词嵌入向量中来作为位置信息但这导致一些问题 无法体现相对位置关系使用位置索引无法很好地表示词与词之间的相对位置关系。例如索引3和4表示的只是绝对位置无法直接反映它们之间相邻的位置关系。缺乏泛化能力仅使用位置索引作为输入模型很难从有限的训练数据中推广到不同长度的输入序列。因为序列长度的变化会导致位置索引的数值分布发生剧烈变化模型难以学习长度不变的位置模式。数值不稳定性对于很长的序列,使用大的位置索引数值会导致梯度计算时的数值不稳定和underflow/overflow等问题。信息瓶颈将位置信息直接编码为一个标量索引其携带的位置信息有限限制了模型对位置的表达能力。而将其编码为向量可以提供更高维的位置信息表示。缺乏结构归纳偏置直接使用索引则缺乏结构化的归纳偏置(Inductive Bias)。合理的位置编码函数设计(如基于三角函数的编码)可以为模型引入一些有益的归纳偏置,帮助模型更容易学习一些位置模式和结构。 2.1. 正弦位置编码 正弦位置编码及其可视化 Attention Is All You Need The Illustrated Transformer 正弦位置编码(sinusoidal positional embedding)是Transformer模型中使用的一种位置编码方式。对于一个长度为 t t t的序列,生成一个 d d d维的位置编码向量。其中第 i i i个位置的第 j j j维编码计算公式为: P E ( p o s , 2 i ) sin ⁡ ( p o s / 1000 0 2 i / d ) P E ( p o s , 2 i 1 ) cos ⁡ ( p o s / 1000 0 2 i / d ) \begin{aligned} PE_{(pos,2i)} \sin(pos/10000^{2i/d}) \\ PE_{(pos,2i1)} \cos(pos/10000^{2i/d}) \end{aligned} PE(pos,2i)​PE(pos,2i1)​​sin(pos/100002i/d)cos(pos/100002i/d)​ 其中pos表示词的位置索引从0开始计数。 正弦位置编码的优点 编码结构偶数维度使用sin函数编码奇数维度使用cos函数编码编码向量的每个维度对应一个不同的sin/cos周期项。这种结构能自然地表示绝对位置和相对位置信息。相对位置关系两个不同位置的embeddings之间的关系能通过三角函数的周期性很好地体现它们的相对位置关系即距离越近的两个词其位置向量将越相似。相对位置信息是距离近的两个位置由于使用相近的sin/cos值其位置向量也会较为相近。绝对位置关系每个位置对应一个唯一的向量表示可以较为明确地编码绝对位置索引信息。绝对位置信息是每个位置pos对应一个唯一的向量表示[sin(x), cos(y), …]。长度无关与直接使用位置索引不同正弦/余弦编码可以处理任意长度的序列避免了可能的数值溢出等问题。长距离关系使用不同频率的三角函数可以在有限维度下恰当地编码任意长距离的位置关系。 2.1. 学习的位置编码 相关论文 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 学习的位置嵌入(Positional Embeddings)是另一种常用的位置编码方式其思路是将位置信息直接作为需要学习的参数来获取。具体来说为每个可能的位置索引(如0,1,2,…,max_len)分别分配一个可学习的嵌入向量用来表示该位置的位置编码。所有这些嵌入向量通常被存储在一个位置嵌入矩阵(Positional Embedding Matrix)之中。在输入序列经过单词嵌入之后将对应位置的位置嵌入向量直接相加到单词嵌入上充当输入到模型的综合表示。单词嵌入和位置嵌入作为整个模型的一部分参数在训练过程中通过反向传播算法一同学习得到合适的向量表示。 学习的位置嵌入的优点 与固定的编码函数(如正弦/余弦编码)不同学习的位置嵌入方式完全由数据驱动可以学习到最优的位置编码表示表现力更强。它不需要设计特定的编码函数直接使用学习的向量表示即可易于使用和实现。 学习的位置嵌入的缺点 学习的位置嵌入需要大量的可学习参数(嵌入向量数×嵌入维度)对较长序列来说计算代价高。此外每个位置使用单独的向量难以建模位置之间的一些结构关系。 2.3. 相对位置编码 相关论文 Self-Attention with Relative Position Representations Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer 相对位置编码是一种基于自注意力结构的编码方式典型应用是T5模型它允许模型自动学习位置表示而不是直接使用固定的位置嵌入。与传统的位置编码相比T5相对位置编码更加灵活和高效。在T5相对位置编码中每个位置的表示都是相对于其他位置的。具体来说每个位置的表示由两部分组成一部分是该位置相对于起始位置的偏移量另一部分是该位置相对于其他位置的相对位置关系。这种表示方式使得模型可以更好地理解序列中的元素是如何排列的从而提高了模型的性能。 具体来说T5模型在自注意力机制中引入了相对位置嵌入用于表示元素之间的相对位置关系。这些嵌入被添加到原始的输入嵌入中以在注意力计算中引入位置信息。通过这种方式模型可以在处理序列数据时充分利用位置信息提高模型的性能。 2.4. 旋转位置编码 相关论文 RoFormer: Enhanced Transformer with Rotary Position Embedding 旋转位置编码(Rotary Position Embedding, RoPE)是一种新型的位置编码方法。在RoPE中每个位置被编码为一个复数这个复数的模长为1角度与位置成正比。具体来说如果我们把词的位置表示为p那么我们可以得到一个复数的位置编码ei⋅p其中i是虚数单位。 RoPE通过绝对位置编码的方式实现相对位置编码综合了绝对位置编码和相对位置编码的优点。主要就是对attention中的q, k向量注入了绝对位置信息然后用更新的qk向量做attention中的内积就会引入相对位置信息。RoPE不是像传统的位置编码那样将位置信息和词的嵌入向量直接相加。这样RoPE可以在不增加模型大小的情况下提供丰富的位置信息。 2.5. ALiBi位置编码 相关论文 Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation ALiBi(Attention with Linear Biases)位置编码是一种在自注意力模型中使用的位置编码方法。它的目标是在自注意力机制中引入位置信息使模型能够理解单词之间的相对位置。具体来说ALiBi通过向自注意力机制的每个输入添加一个线性偏置项来实现这一目标。这个线性偏置项是基于输入的位置计算的因此可以反映出输入之间的相对位置信息。 ALiBi位置编码的特点在于在网络中的任何位置都不添加位置嵌入。唯一的修改是在查询-键点积之后添加了一个静态的、非可学习的偏置项。这个偏置项的作用是为了在计算注意力分数时引入一些偏置从而影响模型对不同位置的关注程度。这种修改可以帮助模型更好地处理输入序列中的位置信息而无需额外学习位置嵌入参数。 softmax ( q i K T m ⋅ [ − ( i − 1 ) , ⋯ , − 2 , − 1 , 0 ] ) \text{softmax} \left(q_i K^T m \cdot [-(i-1), \cdots, -2, -1, 0] \right) softmax(qi​KTm⋅[−(i−1),⋯,−2,−1,0]) 3. Transformer 尽管LSTM在处理序列数据方面表现出色但在处理长序列时仍存在一些限制。Transformer架构的引入旨在解决这些限制并在自然语言处理和其他序列建模任务中取得突破。 以下是Transformer相对于LSTM的一些优点和特点 并行计算在LSTM中处理序列数据是顺序进行的每个时间步的计算依赖于前一个时间步的输出。这限制了并行计算的能力导致训练和推理速度较慢。相比之下Transformer使用自注意力机制使得所有位置的输入都可以同时进行计算实现了更好的并行化从而加速了训练和推理过程。长期依赖性建模虽然LSTM引入了门控机制来处理长期依赖性但对于非常长的序列这仍然可能存在挑战。Transformer 中的自注意力机制允许每个位置直接关注所有其他位置的信息无论其距离有多远。这使得Transformer能够更好地建模长期依赖性捕捉全局上下文关系。位置编码在LSTM中序列的顺序信息是通过时间步骤的顺序隐含地编码的。相比之下Transformer显式地引入了位置编码将序列的位置信息注入到输入中。这样Transformer能够更好地处理序列中不同位置的关系并减少位置顺序的敏感性。扩展性和泛化性Transformer架构可以很容易地扩展到更大的模型和更长的序列而不会受到梯度消失或梯度爆炸等问题的限制。它可以通过增加层和头(multi-head attention)来增加模型的容量使其适应更复杂的任务和更大规模的数据。注意力机制Transformer引入了自注意力机制使得模型能够根据输入序列中的相关性自适应地分配注意力。这使得模型能够更好地理解和捕捉输入序列中的重要信息并在不同位置之间建立相关性。 总的来说Transformer相比LSTM有着很好的并行性、长距建模能力和很好的扩展性。 3.1. Transformer架构 Transfomer 原始论文 Attention Is All You Need 自注意力机制(Self-Attention)是Transformer模型中最核心的部分之一完整的Transformer还包括其他部分 前馈层(FeedForward)在Transformer中前馈层与自注意力层交替排列使得Transformer能够从不同的子层中捕捉不同级别的特征自注意力捕捉远程依赖关系前馈层对每个单词进行建模。通过这种方式编码和解码序列最终得到建模目标任务所需的表示。 FFN ( x ) max ⁡ ( 0 , x W 1 b 1 ) W 2 b 2 \text{FFN}(x) \max(0, x W_1 b_1) W_2 b2 FFN(x)max(0,xW1​b1​)W2​b2 残差连接(Residual Connections)一层的输入直接加到它的输出上残差连接是深度学习模型中常用的一种技巧目的是帮助更好地训练深层神经网络。这种设计的好处是可以更好地保留输入的原始信息避免在很深的网络中完全压缩或丢失。同时残差连接也有利于梯度传播缓解了深层网络的梯度消失问题从而使深度模型更容易训练。这一机制有助于加深网络、缓解梯度问题是提高模型性能的有力手段。 层归一化(Layer Normalization)是一种用于控制深度神经网络中不同层的尺度的技术。在深度神经网络中每个层都包含很多神经元或节点这些节点的输入和输出可以具有不同的尺度。这可能导致训练过程中的梯度消失或梯度爆炸等问题这对于网络的稳定性和收敛性是不利的。为了解决这个问题层归一化引入了一种正则化方法用于对每个层的输入进行归一化处理。具体而言对于每个层的输入向量层归一化将其均值和方差计算出来并使用这些统计量对输入进行中心化和缩放以使其具有零均值和单位方差。这样可以增加网络层之间的稳定性有助于更好地传播梯度并加速训练。与批归一化(Batch Normalization)不同层归一化是针对每个样本单独进行归一化而不是对整个批次进行归一化。这使得层归一化在小批量训练或单样本推理时更有效。 原始的Transformer论文提出的是一个编码器-解码器模型。编码器用于将输入序列编码为一系列上下文向量而解码器则根据编码器的输出和之前生成的标记来生成目标序列。编码器即是上面的介绍解码器通过将三角形因果注意力掩码应用于编码器的注意力层可以限制注意力只能关注前面的标记而不会泄露未来的信息。这意味着在解码器阶段每个位置的标记只能依赖于较早的标记模型在生成序列时遵循自左向右的顺序。 Transformer 的 Pytorch 实现 import math import copy import torch import torch.nn as nn import torch.nn.functional as F from torch.autograd import Variableclass PositionalEncoder(nn.Module):def __init__(self, d_model, max_seq_len80):super().__init__()self.d_model d_modelpe torch.zeros(max_seq_len, d_model)for pos in range(max_seq_len):for i in range(0, d_model, 2):pe[pos, i] math.sin(pos / (10000 ** ((2 * i) / d_model)))pe[pos, i 1] math.cos(pos / (10000 ** ((2 * (i 1)) / d_model)))pe pe.unsqueeze(0)self.register_buffer(pe, pe)def forward(self, x):x x * math.sqrt(self.d_model)seq_len x.size(1)x x Variable(self.pe[:, :seq_len], requires_gradFalse)return xclass MultiHeadAttention(nn.Module):def __init__(self, heads, d_model, dropout0.1):super().__init__()self.d_model d_modelself.d_k d_model // headsself.h headsself.q_linear nn.Linear(d_model, d_model)self.k_linear nn.Linear(d_model, d_model)self.v_linear nn.Linear(d_model, d_model)self.dropout nn.Dropout(dropout)self.out nn.Linear(d_model, d_model)def attention(self, q, k, v, d_k, maskNone, dropoutNone):scores torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(d_k)# 掩盖掉那些为了填补长度增加的单元使其通过 softmax 计算后为 0if mask is not None:mask mask.unsqueeze(1)scores scores.masked_fill(mask 0, -1e9)scores F.softmax(scores, dim-1)if dropout is not None:scores dropout(scores)output torch.matmul(scores, v)return outputdef forward(self, q, k, v, maskNone):bs q.size(0)# 进行线性操作划分为成 h 个头q self.q_linear(q).view(bs, -1, self.h, self.d_k) k self.k_linear(k).view(bs, -1, self.h, self.d_k) v self.v_linear(v).view(bs, -1, self.h, self.d_k)# 矩阵转置q q.transpose(1,2) k k.transpose(1,2) v v.transpose(1,2)# 计算 attentionscores self.attention(q, k, v, self.d_k, mask, self.dropout)# 连接多个头并输入到最后的线性层concat scores.transpose(1,2).contiguous().view(bs, -1, self.d_model)output self.out(concat) return outputclass FeedForward(nn.Module):def __init__(self, d_model, d_ff2048, dropout0.1):super().__init__()# d_ff 默认设置为 2048self.linear_1 nn.Linear(d_model, d_ff)self.dropout nn.Dropout(dropout)self.linear_2 nn.Linear(d_ff, d_model)def forward(self, x):x self.dropout(F.relu(self.linear_1(x)))x self.linear_2(x)return xclass NormLayer(nn.Module):def __init__(self, d_model, eps1e-6):super().__init__()self.size d_model# 层归一化包含两个可以学习的参数self.alpha nn.Parameter(torch.ones(self.size))self.bias nn.Parameter(torch.ones(self.size))self.eps epsdef forward(self, x):norm self.alpha * (x - x.mean(dim-1, keepdimTrue)) / (x.std(dim-1, keepdimTrue) self.eps) self.biasreturn normclass EncoderLayer(nn.Module):def __init__(self, d_model, heads, dropout0.1):super().__init__()self.norm_1 NormLayer(d_model)self.norm_2 NormLayer(d_model)self.attn MultiHeadAttention(heads, d_model, dropout)self.ff FeedForward(d_model, dropoutdropout)self.dropout_1 nn.Dropout(dropout)self.dropout_2 nn.Dropout(dropout)def forward(self, x, mask):x2 self.norm_1(x)x x self.dropout_1(self.attn(x2, x2, x2, mask))x2 self.norm_2(x)x x self.dropout_2(self.ff(x2))return xclass Encoder(nn.Module):def __init__(self, vocab_size, d_model, N, heads, dropout):super().__init__()self.N Nself.embed nn.Embedding(vocab_size, d_model)self.pe PositionalEncoder(d_model)self.layers nn.ModuleList([copy.deepcopy(EncoderLayer(d_model, heads, dropout)) for _ in range(N)])self.norm NormLayer(d_model)def forward(self, src, mask):x self.embed(src)x self.pe(x)for i in range(self.N):x self.layers[i](x, mask)return self.norm(x)class DecoderLayer(nn.Module):def __init__(self, d_model, heads, dropout0.1):super().__init__()self.norm_1 NormLayer(d_model)self.norm_2 NormLayer(d_model)self.norm_3 NormLayer(d_model)self.dropout_1 nn.Dropout(dropout)self.dropout_2 nn.Dropout(dropout)self.dropout_3 nn.Dropout(dropout)self.attn_1 MultiHeadAttention(heads, d_model, dropout)self.attn_2 MultiHeadAttention(heads, d_model, dropout)self.ff FeedForward(d_model, dropoutdropout)def forward(self, x, e_outputs, src_mask, trg_mask):x2 self.norm_1(x)x x self.dropout_1(self.attn_1(x2, x2, x2, trg_mask))x2 self.norm_2(x)x x self.dropout_2(self.attn_2(x2, e_outputs, e_outputs, src_mask))x2 self.norm_3(x)x x self.dropout_3(self.ff(x2))return xclass Decoder(nn.Module):def __init__(self, vocab_size, d_model, N, heads, dropout) - None:super().__init__()self.N Nself.embed nn.Embedding(vocab_size, d_model)self.pe PositionalEncoder(d_model)self.layers nn.ModuleList([copy.deepcopy(DecoderLayer(d_model, heads, dropout)) for _ in range(N)])self.norm NormLayer(d_model)def forward(self, trg, e_outputs, src_mask, trg_mask):x self.embed(trg)x self.pe(x)for i in range(self.N):x self.layers[i](x, e_outputs, src_mask, trg_mask)return self.norm(x)class Transformer(nn.Module):def __init__(self, src_vocab, trg_vocab, d_model, N, heads, dropout):super().__init__()self.encoder Encoder(src_vocab, d_model, N, heads, dropout) self.decoder Decoder(trg_vocab, d_model, N, heads, dropout) self.out nn.Linear(d_model, trg_vocab)def forward(self, src, trg, src_mask, trg_mask):e_outputs self.encoder(src, src_mask)d_output self.decoder(trg, e_outputs, src_mask, trg_mask) output self.out(d_output)return outputvocab_size 100 d_model 6 N 3 heads 2 dropout 0.1 transformer Transformer(vocab_size, vocab_size, d_model, N, heads, dropout) x torch.tensor([[1, 2], [2, 3]]) mask torch.tensor([[1, 1], [1, 1]]) output transformer(x, x, mask, mask) print(output.shape)3.2. Transformer延伸 扩展定律 大模型的扩展定律(Scaling Laws)指的是描述随着模型规模如参数数量、数据量、计算量等变化而产生的性能变化规律的数学或经验关系。这些定律对于理解和预测模型性能、优化资源配置、指导模型设计和训练策略具有重要意义。 相关论文Scaling Laws for Neural Language Models Transformer运行时 Transformer运行时(Runtime)一般是指Transformer模型在实际应用和执行过程中所涉及的计算时间和资源消耗。理解Transformer模型的运行时特性对于优化模型性能、提高计算效率以及在资源受限的环境中部署模型至关重要。 尽管大多数参数和浮点运算(FLOPs)集中在前馈层中Transformer模型仍然受到自注意力机制的二次复杂度的限制。已经提出了许多方法来处理这个问题。 稀疏注意力(Sparse Attention)仅计算部分元素之间的相似度从而减少计算量。 低秩近似(Low-Rank Approximation)使用低秩矩阵来近似注意力矩阵降低计算复杂度。 分块自注意力(Blocked Self-Attention / Local Attention)将序列分成若干块每个块内进行自注意力计算以减少计算量。 线性时间注意力(Linear-Time Attention)设计新的注意力机制使其计算复杂度从二次降到线性。 这些方法的目标都是在保证模型性能的前提下降低自注意力机制的计算复杂度从而提高 Transformer 模型在处理长序列时的效率。 相关论文Efficient Transformers: A Survey Performers Performers是一种改进的Transformer模型旨在解决传统Transformer模型中自注意力机制计算复杂度高的问题。具体来说Performers提出了一种名为线性注意力的方法将自注意力的计算复杂度从二次降低到线性从而显著提高了模型的效率。 Performers使用核技巧(kernel trick)来近似标准的自注意力机制。具体来说它们利用随机特征映射(random feature mapping)将注意力计算转化为线性操作。这种方法的核心思想是通过特征映射将输入数据映射到一个高维空间使得点积注意力可以通过线性计算来近似。由于计算复杂度降低Performers 在处理长序列时所需的内存也显著减少。这使得它们在实际应用中更加实用特别是在内存受限的环境中。 Performers的核心方法基于随机特征映射和核技巧。具体步骤是 特征映射输入序列通过特征映射函数映射到高维空间。常用的特征映射方法包括高斯核和其他类型的核函数。 线性化注意力使用映射后的特征计算线性注意力而不是直接计算原始输入的点积注意力。通过这种线性化操作可以将复杂度从二次降低到线性。 近似注意力矩阵Performers 通过特征映射和线性化操作近似计算注意力矩阵从而保持了模型性能同时显著提高了计算效率。 相关论文Rethinking Attention with Performers Longformer Longformer是一种改进的Transformer模型专门设计用于处理长序列输入。它通过引入稀疏注意力机制(Sparse Attention)有效地解决了传统Transformer模型中的计算瓶颈问题使得处理长文本和序列数据变得更加高效。 Longformer使用稀疏注意力机制将注意力计算限制在局部范围内而不是全局范围。这种方法显著降低了计算复杂度。稀疏注意力包括局部窗口注意力(Local Window Attention)和全局注意力(Global Attention)后者仅在少数重要位置进行全局计算。Longformer 通过稀疏注意力机制将复杂度降低为线性使其可以处理更长的序列。Longformer允许在序列中的特定位置设置全局注意力这些位置可以是任务相关的关键位置如段落开头、标题或特定标记位置。这种灵活性使得模型在处理不同任务时具有更好的适应性。通过滑动窗口机制Longformer可以处理任意长度的序列而不需要分割输入序列。这种机制保证了模型在处理长文本时的连续性和完整性。 相关论文Longformer: The Long-Document Transformer 4. 解码策略 Transformer通常由编码器和解码器两部分组成。编码器将输入序列转换为隐藏表示解码器则根据这些隐藏表示生成输出序列。在文本生成任务中Transformer解码器自回归地生成每个词即每次生成一个词并将其作为输入用于生成下一个词直到生成结束标记。生成任务中的解码(decoding)过程是从模型中生成文本的关键步骤。 以下是一些常见的解码方法 贪心搜索(Greedy Search)每一步选择概率最高的词作为输出。优点简单快速。缺点可能会错过全局最优解导致生成的文本质量不高。束搜索(Beam Search)保留多个束宽(beam width)候选序列每一步扩展这些序列并选择概率最高的几个继续。优点比贪心搜索有更好的全局搜索能力生成文本质量较高。缺点计算量较大仍然可能错过最佳序列。采样(Sampling)根据概率分布随机选择下一个词。随机采样(Random Sampling)直接根据模型输出的概率分布进行采样。温度采样(Temperature Sampling)调整概率分布的平滑度温度参数T用于控制采样的随机性。较高的T增强多样性较低的T增强确定性。Top-k采样每一步只从概率最高的k个词中进行采样排除概率较低的词。优点平衡生成多样性和质量。Top-p采样又称核采样Nucleus Sampling每一步从使累积概率达到阈值p的词集合中进行采样。优点自适应地选择候选词集合兼顾多样性和生成质量。 基本的解码步骤 初始化给定输入序列如翻译任务中的源语言句子并通过编码器生成隐藏表示。初始化解码器输入通常是特殊的开始标记 s。自回归生成将解码器输入通过解码器生成输出词的概率分布。根据选定的解码方法如贪心搜索、束搜索、采样等生成下一个词。将生成的词追加到解码器输入序列并重复此过程直到生成结束标记或达到最大长度。
http://www.zqtcl.cn/news/319759/

相关文章:

  • 阿里云 建设网站北京百度竞价托管公司
  • 怎么样做长久的电影网站安卓手机应用市场
  • 网站建设账户搭建济南网络优化哪家专业
  • 宜兴城乡建设局网站wordpress调用logo
  • 让他人建设网站需要提供的材料女生读电子商务好就业吗
  • 北大荒建设集团网站国内开源代码网站
  • 高端企业网站要多少钱中企动力z云邮箱登录
  • 网站建设视频教程百度云那种自行提取卡密的网站怎么做
  • 网站外链建设与维护网站建设客户调研表
  • 海南省建设银行官方网站招聘营销的主要目的有哪些
  • flask 简易网站开发网站建设和空间
  • 怀化建设网站wordpress静态化插件
  • 网站上的中英文切换是怎么做的大连网站制作优选ls15227
  • 网站开发工作安排广告设计公司有哪些
  • 无人机公司网站建设用什么软件做网站最简单
  • 企业微信app下载安装电脑版淄博网站优化价格
  • 做一个电影网站需要多少钱在线代理服务器网站
  • 怎样制作微信网站办网络宽带多少钱
  • ios开发者账号有什么用嘉兴网站关键词优化
  • 怎样在外贸网站做业务简付后wordpress
  • html网页制作源代码成品长沙 网站优化
  • 长沙做网站哪里好百度招聘 网站开发
  • 创建网站服务器银川建设厅网站
  • 海口建设局网站代运营网站建设
  • 网站建设环境搭建心得体会微信开发者模式
  • 网站点击率多少正常落地页网站
  • 做淘宝店铺有哪些好的网站东莞网站制作建设收费
  • Wordpress 实名认证太原网站搜索优化
  • 大良网站建设dwxw网站可以自己做
  • 自己怎么建网站佛山哪家网站建设比较好