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

十大网站建设公司排名微商城是怎么做的

十大网站建设公司排名,微商城是怎么做的,wordpress批量添加标签数据库,做期权关注哪个网站文章目录 1. 前言2. Transformer结构训练过程1. 输入嵌入和位置编码2. 编码器层2.1 单头的注意力机制(便于理解)2.2 多头的注意力机制(Transformer真实使用的)2.3 残差连接和层归一化2.4 前馈神经网络#xff08;FFN#xff09;2.5 残差连接和层归一化2.6 总结 3. 解码器层 推… 文章目录 1. 前言2. Transformer结构训练过程1. 输入嵌入和位置编码2. 编码器层2.1 单头的注意力机制(便于理解)2.2 多头的注意力机制(Transformer真实使用的)2.3 残差连接和层归一化2.4 前馈神经网络FFN2.5 残差连接和层归一化2.6 总结 3. 解码器层 推理过程1. 初始化2. 编码器3. 解码器逐步生成4. 输出生成 3. 训练过程的代码4. 推理过程的代码5. 何为“多头”6. Mask如何给上去的7. 为何要位置编码8. 为什么说Transformer可以并行化计算NLP任务9. MultiheadAttention的Pytorch官方代码10. 何为QKV11. 为何不是BN12. RNN的梯度消失是指什么RNN的梯度消失和其他模型的梯度消失有本质差别如何降低RNN的梯度消失 1. 前言 这个教程不错推荐观看 https://www.bilibili.com/video/BV1Di4y1c7Zm/?spm_id_from333.337.search-card.all.clickvd_source484293edcf94a55e368ecf2e0d1fbfce 来看一下Transformer结构。 2. Transformer结构 表达Transformer模型从训练到推理的过程。 训练过程 1. 输入嵌入和位置编码 给定输入序列 X [ x 1 , x 2 , … , x n ] X [x_1, x_2, \ldots, x_n] X[x1​,x2​,…,xn​] 和目标序列 Y [ y 1 , y 2 , … , y m ] Y [y_1, y_2, \ldots, y_m] Y[y1​,y2​,…,ym​]首先将它们转换为嵌入向量 E x [ E ( x 1 ) , E ( x 2 ) , … , E ( x n ) ] E_x [E(x_1), E(x_2), \ldots, E(x_n)] Ex​[E(x1​),E(x2​),…,E(xn​)] E y [ E ( y 1 ) , E ( y 2 ) , … , E ( y m ) ] E_y [E(y_1), E(y_2), \ldots, E(y_m)] Ey​[E(y1​),E(y2​),…,E(ym​)] 然后加上位置编码 位置编码Positional Encoding用于表示序列中每个词的位置信息帮助模型捕捉序列的顺序关系。Transformer使用了一种基于正弦和余弦函数的位置编码方式。 位置编码的具体公式如下 对于输入序列中的第 i i i 个位置和第 j j j 个维度位置编码为 P ( i , 2 j ) sin ⁡ ( i 1000 0 2 j / d model ) P(i, 2j) \sin\left(\frac{i}{10000^{2j/d_{\text{model}}}}\right) P(i,2j)sin(100002j/dmodel​i​) P ( i , 2 j 1 ) cos ⁡ ( i 1000 0 2 j / d model ) P(i, 2j1) \cos\left(\frac{i}{10000^{2j/d_{\text{model}}}}\right) P(i,2j1)cos(100002j/dmodel​i​) 其中 d model d_{\text{model}} dmodel​ 是嵌入向量的维度。 将位置编码加到输入序列和目标序列的嵌入向量中 P E x i E ( x i ) P ( i ) PE_{x_i} E(x_i) P(i) PExi​​E(xi​)P(i) P E y i E ( y i ) P ( i ) PE_{y_i} E(y_i) P(i) PEyi​​E(yi​)P(i) 好好理解位置编码第 i i i 个位置和第 j j j 个维度的数值是固定的编码加到嵌入向量 2. 编码器层 2.1 单头的注意力机制(便于理解) 编码器中的每一层包括一个多头自注意力机制和一个前馈神经网络 Attention ( Q , K , V ) softmax ( Q K T d k ) V \text{Attention}(Q, K, V) \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)softmax(dk​ ​QKT​)V 对于每个编码器层我们有 Self-Attention Attention ( P E x , P E x , P E x ) \text{Self-Attention} \text{Attention}(PE_x, PE_x, PE_x) Self-AttentionAttention(PEx​,PEx​,PEx​) 在Transformer中编码器和解码器都使用了自注意力机制Self-Attention Mechanism。在编码器中查询Query、键Key和值Value矩阵都来自于输入的嵌入加上位置编码 Q K V P E x Q K V PE_x QKVPEx​ 在解码器中自注意力机制和编码器-解码器注意力机制都用到了类似的计算方式区别在于解码器的自注意力机制是带掩码的以防止每个时间步看到未来的信息。 2.2 多头的注意力机制(Transformer真实使用的) 在多头自注意力机制中我们首先将嵌入向量投影到多个子空间然后在每个子空间上计算注意力。每个头的注意力计算公式如下 Attention ( Q , K , V ) softmax ( Q K T d k ) V \text{Attention}(Q, K, V) \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)softmax(dk​ ​QKT​)V 对于多头注意力机制我们有 MultiHead ( Q , K , V ) Concat ( head 1 , head 2 , … , head h ) W O \text{MultiHead}(Q, K, V) \text{Concat}(\text{head}_1, \text{head}_2, \ldots, \text{head}_h)W^O MultiHead(Q,K,V)Concat(head1​,head2​,…,headh​)WO 其中 head i Attention ( Q W i Q , K W i K , V W i V ) \text{head}_i \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) headi​Attention(QWiQ​,KWiK​,VWiV​) 这里的 W i Q , W i K , W i V W_i^Q, W_i^K, W_i^V WiQ​,WiK​,WiV​ 是将输入投影到 i i i 头的参数矩阵 W O W^O WO 是输出的线性变换矩阵。 对于每个编码器层我们有 Self-Attention MultiHead ( P E x , P E x , P E x ) \text{Self-Attention} \text{MultiHead}(PE_x, PE_x, PE_x) Self-AttentionMultiHead(PEx​,PEx​,PEx​) 在Transformer中编码器和解码器都使用了自注意力机制Self-Attention Mechanism。在编码器中查询Query、键Key和值Value矩阵都来自于输入的嵌入加上位置编码 Q K V P E x Q K V PE_x QKVPEx​ 所以编码器层的自注意力机制具体为 Self-Attention MultiHead ( P E x , P E x , P E x ) \text{Self-Attention} \text{MultiHead}(PE_x, PE_x, PE_x) Self-AttentionMultiHead(PEx​,PEx​,PEx​) 2.3 残差连接和层归一化 残差连接和层归一化 LayerOutput LayerNorm ( x MultiHead ( P E x , P E x , P E x ) ) \text{LayerOutput} \text{LayerNorm}(x \text{MultiHead}(PE_x, PE_x, PE_x)) LayerOutputLayerNorm(xMultiHead(PEx​,PEx​,PEx​)) 2.4 前馈神经网络FFN 前馈神经网络公式FFN FFN ( x ) ReLU ( x W 1 b 1 ) W 2 b 2 \text{FFN}(x) \text{ReLU}(xW_1 b_1)W_2 b_2 FFN(x)ReLU(xW1​b1​)W2​b2​ 2.5 残差连接和层归一化 LayerOutput LayerNorm ( LayerOutput FFN ( LayerOutput ) ) \text{LayerOutput} \text{LayerNorm}(\text{LayerOutput} \text{FFN}(\text{LayerOutput})) LayerOutputLayerNorm(LayerOutputFFN(LayerOutput)) 2.6 总结 整个编码器层在Transformer中可能是有多个的。 经过 L L L 层编码器我们得到编码器的输出 H EncoderLayers ( P E x ) H \text{EncoderLayers}(PE_x) HEncoderLayers(PEx​) 3. 解码器层 多头注意力机制 MultiHead ( Q , K , V ) Concat ( head 1 , head 2 , … , head h ) W O \text{MultiHead}(Q, K, V) \text{Concat}(\text{head}_1, \text{head}_2, \ldots, \text{head}_h)W^O MultiHead(Q,K,V)Concat(head1​,head2​,…,headh​)WO 其中每个头的计算为 head i Attention ( Q W i Q , K W i K , V W i V ) \text{head}_i \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) headi​Attention(QWiQ​,KWiK​,VWiV​) 带掩码的自注意力机制 Masked-Attention ( Q , K , V ) softmax ( Q K T M d k ) V \text{Masked-Attention}(Q, K, V) \text{softmax}\left(\frac{QK^T M}{\sqrt{d_k}}\right)V Masked-Attention(Q,K,V)softmax(dk​ ​QKTM​)V 其中 M M M 是掩码矩阵掩盖未来时间步。 注意了与编码器的交互里在这里Q是解码器的输出编码器的输出作为K和V。 Attention ( Q , K , V ) softmax ( Q K T d k ) V \text{Attention}(Q, K, V) \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)softmax(dk​ ​QKT​)V 前馈神经网络 FFN ( x ) ReLU ( x W 1 b 1 ) W 2 b 2 \text{FFN}(x) \text{ReLU}(xW_1 b_1)W_2 b_2 FFN(x)ReLU(xW1​b1​)W2​b2​ 残差连接和层归一化 LayerOutput LayerNorm ( x FFN ( MultiHead ( P E y , P E y , P E y ) P E y ) ) \text{LayerOutput} \text{LayerNorm}(x \text{FFN}(\text{MultiHead}(PE_y, PE_y, PE_y) PE_y)) LayerOutputLayerNorm(xFFN(MultiHead(PEy​,PEy​,PEy​)PEy​)) 经过 L L L 层解码器我们得到解码器的输出 D DecoderLayers ( P E y ) D \text{DecoderLayers}(PE_y) DDecoderLayers(PEy​) 通过线性变换和Softmax层生成最终的词概率分布 Logits D ⋅ W o b o \text{Logits} D \cdot W_o b_o LogitsD⋅Wo​bo​ OutputProbabilities softmax ( Logits ) \text{OutputProbabilities} \text{softmax}(\text{Logits}) OutputProbabilitiessoftmax(Logits) 推理过程 1. 初始化 初始化输入序列 X [ x 1 , x 2 , … , x n ] X [x_1, x_2, \ldots, x_n] X[x1​,x2​,…,xn​]目标序列开始标记为 Y [ sos ] Y [\text{sos}] Y[sos]。 2. 编码器 编码器部分同训练过程 H EncoderLayers ( P E x ) H \text{EncoderLayers}(PE_x) HEncoderLayers(PEx​) 3. 解码器逐步生成 带掩码的多头自注意力机制 Masked-MultiHead-Attention ( Q , K , V ) MultiHead ( Q , K , V ) \text{Masked-MultiHead-Attention}(Q, K, V) \text{MultiHead}(Q, K, V) Masked-MultiHead-Attention(Q,K,V)MultiHead(Q,K,V) 编码器-解码器多头注意力机制 Enc-Dec-MultiHead-Attention ( Q , K , V ) MultiHead ( Q , K , V ) \text{Enc-Dec-MultiHead-Attention}(Q, K, V) \text{MultiHead}(Q, K, V) Enc-Dec-MultiHead-Attention(Q,K,V)MultiHead(Q,K,V) 残差连接和层归一化 LayerOutput LayerNorm ( x Masked-MultiHead-Attention ( P E y ) P E y ) \text{LayerOutput} \text{LayerNorm}(x \text{Masked-MultiHead-Attention}(PE_y) PE_y) LayerOutputLayerNorm(xMasked-MultiHead-Attention(PEy​)PEy​) 然后经过前馈神经网络 LayerOutput LayerNorm ( LayerOutput FFN ( LayerOutput Enc-Dec-MultiHead-Attention ( P E y , H , H ) ) ) \text{LayerOutput} \text{LayerNorm}(\text{LayerOutput} \text{FFN}(\text{LayerOutput} \text{Enc-Dec-MultiHead-Attention}(PE_y, H, H))) LayerOutputLayerNorm(LayerOutputFFN(LayerOutputEnc-Dec-MultiHead-Attention(PEy​,H,H))) 经过 L L L 层解码器我们得到解码器的输出 D DecoderLayers ( P E y , H ) D \text{DecoderLayers}(PE_y, H) DDecoderLayers(PEy​,H) 4. 输出生成 通过线性变换和Softmax层生成最终的词概率分布 Logits D ⋅ W o b o \text{Logits} D \cdot W_o b_o LogitsD⋅Wo​bo​ OutputProbabilities softmax ( Logits ) \text{OutputProbabilities} \text{softmax}(\text{Logits}) OutputProbabilitiessoftmax(Logits) 3. 训练过程的代码 不算batch的概念进去 import numpy as np# 设置随机种子以确保可重复性 np.random.seed(42)# 模拟输入序列和目标序列 input_seq_len 5 target_seq_len 5 d_model 4 # 嵌入维度input_seq np.random.randint(0, 10, (input_seq_len,)) target_seq np.random.randint(0, 10, (target_seq_len,))# 模拟嵌入矩阵 embedding_matrix np.random.rand(10, d_model) # 词汇表大小为10# 输入嵌入 input_embeddings embedding_matrix[input_seq] target_embeddings embedding_matrix[target_seq]# 位置编码 def get_positional_encoding(seq_len, d_model):pos_enc np.zeros((seq_len, d_model))for pos in range(seq_len):for i in range(d_model):if i % 2 0:pos_enc[pos, i] np.sin(pos / (10000 ** (2 * i / d_model)))else:pos_enc[pos, i] np.cos(pos / (10000 ** (2 * (i - 1) / d_model)))return pos_encinput_pos_enc get_positional_encoding(input_seq_len, d_model) target_pos_enc get_positional_encoding(target_seq_len, d_model)# 添加位置编码到嵌入 input_embeddings input_pos_enc target_embeddings target_pos_enc# 编码器层自注意力机制和前馈神经网络 def self_attention(Q, K, V):d_k Q.shape[-1]scores np.dot(Q, K.T) / np.sqrt(d_k)attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)return np.dot(attention_weights, V)def feed_forward(x):W1 np.random.rand(d_model, d_model)b1 np.random.rand(d_model)W2 np.random.rand(d_model, d_model)b2 np.random.rand(d_model)return np.dot(np.maximum(0, np.dot(x, W1) b1), W2) b2# 单个编码器层 def encoder_layer(x):attn_output self_attention(x, x, x)attn_output x # 残差连接norm_output attn_output / np.linalg.norm(attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output)ff_output norm_output # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 编码器 encoder_output input_embeddings for _ in range(2): # 使用2层编码器encoder_output encoder_layer(encoder_output)# 解码器层带掩码的自注意力机制、编码器-解码器注意力机制和前馈神经网络 def masked_self_attention(Q, K, V):mask np.triu(np.ones((Q.shape[0], K.shape[0])), k1) # 上三角掩码d_k Q.shape[-1]scores np.dot(Q, K.T) / np.sqrt(d_k)scores - mask * 1e9 # 应用掩码attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)return np.dot(attention_weights, V)# 单个解码器层 def decoder_layer(x, enc_output):masked_attn_output masked_self_attention(x, x, x)masked_attn_output x # 残差连接norm_output1 masked_attn_output / np.linalg.norm(masked_attn_output, axis-1, keepdimsTrue)enc_dec_attn_output self_attention(norm_output1, enc_output, enc_output)enc_dec_attn_output norm_output1 # 残差连接norm_output2 enc_dec_attn_output / np.linalg.norm(enc_dec_attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output2)ff_output norm_output2 # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 解码器 decoder_output target_embeddings for _ in range(2): # 使用2层解码器decoder_output decoder_layer(decoder_output, encoder_output)# 线性变换和Softmax层 output_vocab_size 10 linear_transform np.random.rand(d_model, output_vocab_size) logits np.dot(decoder_output, linear_transform) output_probs np.exp(logits) / np.sum(np.exp(logits), axis-1, keepdimsTrue)# 输出结果 print(Input Sequence:, input_seq) print(Target Sequence (shifted):, target_seq) print(Output Probabilities:\n, output_probs) 多头注意力机制 import numpy as np# 设置随机种子以确保可重复性 np.random.seed(42)# 模拟输入序列和目标序列 input_seq_len 5 target_seq_len 5 d_model 4 # 嵌入维度 num_heads 2 # 注意力头的数量input_seq np.random.randint(0, 10, (input_seq_len,)) target_seq np.random.randint(0, 10, (target_seq_len,))# 模拟嵌入矩阵 embedding_matrix np.random.rand(10, d_model) # 词汇表大小为10# 输入嵌入 input_embeddings embedding_matrix[input_seq] target_embeddings embedding_matrix[target_seq]# 位置编码 def get_positional_encoding(seq_len, d_model):pos_enc np.zeros((seq_len, d_model))for pos in range(seq_len):for i in range(d_model):if i % 2 0:pos_enc[pos, i] np.sin(pos / (10000 ** (2 * i / d_model)))else:pos_enc[pos, i] np.cos(pos / (10000 ** (2 * (i - 1) / d_model)))return pos_encinput_pos_enc get_positional_encoding(input_seq_len, d_model) target_pos_enc get_positional_encoding(target_seq_len, d_model)# 添加位置编码到嵌入 input_embeddings input_pos_enc target_embeddings target_pos_enc# 多头注意力机制 def multi_head_attention(Q, K, V, num_heads):d_k Q.shape[-1] // num_headsall_heads []for i in range(num_heads):# 分头处理Q_head Q[:, i * d_k:(i 1) * d_k]K_head K[:, i * d_k:(i 1) * d_k]V_head V[:, i * d_k:(i 1) * d_k]# 计算单头注意力scores np.dot(Q_head, K_head.T) / np.sqrt(d_k)attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)head_output np.dot(attention_weights, V_head)all_heads.append(head_output)# 拼接所有头的输出multi_head_output np.concatenate(all_heads, axis-1)return multi_head_outputdef feed_forward(x):W1 np.random.rand(d_model, d_model)b1 np.random.rand(d_model)W2 np.random.rand(d_model, d_model)b2 np.random.rand(d_model)return np.dot(np.maximum(0, np.dot(x, W1) b1), W2) b2# 单个编码器层 def encoder_layer(x, num_heads):attn_output multi_head_attention(x, x, x, num_heads)attn_output x # 残差连接norm_output attn_output / np.linalg.norm(attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output)ff_output norm_output # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 编码器 encoder_output input_embeddings for _ in range(2): # 使用2层编码器encoder_output encoder_layer(encoder_output, num_heads)# 带掩码的多头注意力机制 def masked_multi_head_attention(Q, K, V, num_heads):mask np.triu(np.ones((Q.shape[0], K.shape[0])), k1) # 上三角掩码d_k Q.shape[-1] // num_headsall_heads []for i in range(num_heads):# 分头处理Q_head Q[:, i * d_k:(i 1) * d_k]K_head K[:, i * d_k:(i 1) * d_k]V_head V[:, i * d_k:(i 1) * d_k]# 计算单头带掩码注意力scores np.dot(Q_head, K_head.T) / np.sqrt(d_k)scores - mask * 1e9 # 应用掩码attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)head_output np.dot(attention_weights, V_head)all_heads.append(head_output)# 拼接所有头的输出multi_head_output np.concatenate(all_heads, axis-1)return multi_head_output# 单个解码器层 def decoder_layer(x, enc_output, num_heads):masked_attn_output masked_multi_head_attention(x, x, x, num_heads)masked_attn_output x # 残差连接norm_output1 masked_attn_output / np.linalg.norm(masked_attn_output, axis-1, keepdimsTrue)enc_dec_attn_output multi_head_attention(norm_output1, enc_output, enc_output, num_heads)enc_dec_attn_output norm_output1 # 残差连接norm_output2 enc_dec_attn_output / np.linalg.norm(enc_dec_attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output2)ff_output norm_output2 # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 解码器 decoder_output target_embeddings for _ in range(2): # 使用2层解码器decoder_output decoder_layer(decoder_output, encoder_output, num_heads)# 线性变换和Softmax层 output_vocab_size 10 linear_transform np.random.rand(d_model, output_vocab_size) logits np.dot(decoder_output, linear_transform) output_probs np.exp(logits) / np.sum(np.exp(logits), axis-1, keepdimsTrue)# 输出结果 print(Input Sequence:, input_seq) print(Target Sequence (shifted):, target_seq) print(Output Probabilities:\n, output_probs) 4. 推理过程的代码 不算batch的概念进去 import numpy as np# 设置随机种子以确保可重复性 np.random.seed(42)# 模拟输入序列 input_seq_len 5 d_model 4 # 嵌入维度 vocab_size 10 max_seq_len 10 # 生成序列的最大长度input_seq np.random.randint(0, vocab_size, (input_seq_len,))# 模拟嵌入矩阵 embedding_matrix np.random.rand(vocab_size, d_model)# 输入嵌入 input_embeddings embedding_matrix[input_seq]# 位置编码 def get_positional_encoding(seq_len, d_model):pos_enc np.zeros((seq_len, d_model))for pos in range(seq_len):for i in range(d_model):if i % 2 0:pos_enc[pos, i] np.sin(pos / (10000 ** (2 * i / d_model)))else:pos_enc[pos, i] np.cos(pos / (10000 ** (2 * (i - 1) / d_model)))return pos_encinput_pos_enc get_positional_encoding(input_seq_len, d_model) input_embeddings input_pos_enc# 编码器层自注意力机制和前馈神经网络 def self_attention(Q, K, V):d_k Q.shape[-1]scores np.dot(Q, K.T) / np.sqrt(d_k)attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)return np.dot(attention_weights, V)def feed_forward(x):W1 np.random.rand(d_model, d_model)b1 np.random.rand(d_model)W2 np.random.rand(d_model, d_model)b2 np.random.rand(d_model)return np.dot(np.maximum(0, np.dot(x, W1) b1), W2) b2# 单个编码器层 def encoder_layer(x):attn_output self_attention(x, x, x)attn_output x # 残差连接norm_output attn_output / np.linalg.norm(attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output)ff_output norm_output # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 编码器 encoder_output input_embeddings for _ in range(2): # 使用2层编码器encoder_output encoder_layer(encoder_output)# 解码器层带掩码的自注意力机制、编码器-解码器注意力机制和前馈神经网络 def masked_self_attention(Q, K, V):mask np.triu(np.ones((Q.shape[0], K.shape[0])), k1) # 上三角掩码d_k Q.shape[-1]scores np.dot(Q, K.T) / np.sqrt(d_k)scores - mask * 1e9 # 应用掩码attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)return np.dot(attention_weights, V)# 单个解码器层 def decoder_layer(x, enc_output):masked_attn_output masked_self_attention(x, x, x)masked_attn_output x # 残差连接norm_output1 masked_attn_output / np.linalg.norm(masked_attn_output, axis-1, keepdimsTrue)enc_dec_attn_output self_attention(norm_output1, enc_output, enc_output)enc_dec_attn_output norm_output1 # 残差连接norm_output2 enc_dec_attn_output / np.linalg.norm(enc_dec_attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output2)ff_output norm_output2 # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 生成序列 def generate_sequence(encoder_output, start_token, vocab_size, max_seq_len):generated_seq [start_token]for _ in range(max_seq_len - 1):target_embeddings embedding_matrix[generated_seq]target_pos_enc get_positional_encoding(len(generated_seq), d_model)target_embeddings target_pos_encdecoder_output target_embeddingsfor _ in range(2): # 使用2层解码器decoder_output decoder_layer(decoder_output, encoder_output)logits np.dot(decoder_output[-1], np.random.rand(d_model, vocab_size)) # 只看最后一个时间步next_token np.argmax(logits) # 选取概率最高的词generated_seq.append(next_token)if next_token 2: # 假设2是eos结束标记breakreturn generated_seq# 生成翻译序列 start_token 1 # 假设1是sos开始标记 translated_sequence generate_sequence(encoder_output, start_token, vocab_size, max_seq_len) print(Translated Sequence:, translated_sequence) 加入多头注意力 import numpy as np# 设置随机种子以确保可重复性 np.random.seed(42)# 模拟输入序列 input_seq_len 5 d_model 4 # 嵌入维度 num_heads 2 # 注意力头的数量 vocab_size 10 max_seq_len 10 # 生成序列的最大长度input_seq np.random.randint(0, vocab_size, (input_seq_len,))# 模拟嵌入矩阵 embedding_matrix np.random.rand(vocab_size, d_model)# 输入嵌入 input_embeddings embedding_matrix[input_seq]# 位置编码 def get_positional_encoding(seq_len, d_model):pos_enc np.zeros((seq_len, d_model))for pos in range(seq_len):for i in range(d_model):if i % 2 0:pos_enc[pos, i] np.sin(pos / (10000 ** (2 * i / d_model)))else:pos_enc[pos, i] np.cos(pos / (10000 ** (2 * (i - 1) / d_model)))return pos_encinput_pos_enc get_positional_encoding(input_seq_len, d_model) input_embeddings input_pos_enc# 多头注意力机制 def multi_head_attention(Q, K, V, num_heads):d_k Q.shape[-1] // num_headsall_heads []for i in range(num_heads):# 分头处理Q_head Q[:, i * d_k:(i 1) * d_k]K_head K[:, i * d_k:(i 1) * d_k]V_head V[:, i * d_k:(i 1) * d_k]# 计算单头注意力scores np.dot(Q_head, K_head.T) / np.sqrt(d_k)attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)head_output np.dot(attention_weights, V_head)all_heads.append(head_output)# 拼接所有头的输出multi_head_output np.concatenate(all_heads, axis-1)return multi_head_outputdef feed_forward(x):W1 np.random.rand(d_model, d_model)b1 np.random.rand(d_model)W2 np.random.rand(d_model, d_model)b2 np.random.rand(d_model)return np.dot(np.maximum(0, np.dot(x, W1) b1), W2) b2# 单个编码器层 def encoder_layer(x, num_heads):attn_output multi_head_attention(x, x, x, num_heads)attn_output x # 残差连接norm_output attn_output / np.linalg.norm(attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output)ff_output norm_output # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 编码器 encoder_output input_embeddings for _ in range(2): # 使用2层编码器encoder_output encoder_layer(encoder_output, num_heads)# 带掩码的多头注意力机制 def masked_multi_head_attention(Q, K, V, num_heads):mask np.triu(np.ones((Q.shape[0], K.shape[0])), k1) # 上三角掩码d_k Q.shape[-1] // num_headsall_heads []for i in range(num_heads):# 分头处理Q_head Q[:, i * d_k:(i 1) * d_k]K_head K[:, i * d_k:(i 1) * d_k]V_head V[:, i * d_k:(i 1) * d_k]# 计算单头带掩码注意力scores np.dot(Q_head, K_head.T) / np.sqrt(d_k)scores - mask * 1e9 # 应用掩码attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)head_output np.dot(attention_weights, V_head)all_heads.append(head_output)# 拼接所有头的输出multi_head_output np.concatenate(all_heads, axis-1)return multi_head_output# 单个解码器层 def decoder_layer(x, enc_output, num_heads):masked_attn_output masked_multi_head_attention(x, x, x, num_heads)masked_attn_output x # 残差连接norm_output1 masked_attn_output / np.linalg.norm(masked_attn_output, axis-1, keepdimsTrue)enc_dec_attn_output multi_head_attention(norm_output1, enc_output, enc_output, num_heads)enc_dec_attn_output norm_output1 # 残差连接norm_output2 enc_dec_attn_output / np.linalg.norm(enc_dec_attn_output, axis-1, keepdimsTrue)ff_output feed_forward(norm_output2)ff_output norm_output2 # 残差连接return ff_output / np.linalg.norm(ff_output, axis-1, keepdimsTrue)# 生成序列 def generate_sequence(encoder_output, start_token, vocab_size, max_seq_len, num_heads):generated_seq [start_token]for _ in range(max_seq_len - 1):target_embeddings embedding_matrix[generated_seq]target_pos_enc get_positional_encoding(len(generated_seq), d_model)target_embeddings target_pos_encdecoder_output target_embeddingsfor _ in range(2): # 使用2层解码器decoder_output decoder_layer(decoder_output, encoder_output, num_heads)logits np.dot(decoder_output[-1], np.random.rand(d_model, vocab_size)) # 只看最后一个时间步next_token np.argmax(logits) # 选取概率最高的词generated_seq.append(next_token)if next_token 2: # 假设2是eos结束标记breakreturn generated_seq# 生成翻译序列 start_token 1 # 假设1是sos开始标记 translated_sequence generate_sequence(encoder_output, start_token, vocab_size, max_seq_len, num_heads) print(Translated Sequence:, translated_sequence) 5. 何为“多头” 多头注意力机制允许模型在不同的表示子空间中同时关注不同的位置。 通过将输入的查询、键和值矩阵拆分为多个头模型能够并行地学习多组注意力权重每组都专注于不同的表示子空间。这有助于模型更好地捕获输入序列中的复杂关系。 举个例子来说Transformer编码器模型里面设置特征维度如果是768头是12头那么每个头去管理768/1264个特征 让我们结合公式和代码来理解多头注意力机制是如何工作的 首先我们定义了多头注意力机制的函数其输入包括查询矩阵 ( Q )键矩阵 ( K )值矩阵 ( V )以及头的数量num_heads。 在函数内部我们计算每个头的维度 ( d_k )这是根据查询矩阵的最后一个维度除以头的数量得到的。 接下来我们循环遍历每个头。在每个头中我们将查询、键和值矩阵分别切片成 ( num_heads ) 个部分然后分别用于计算单独的注意力权重。 注意力权重的计算公式是根据公式中的 scores Q K T d k \text{scores} \frac{QK^T}{\sqrt{d_k}} scoresdk​ ​QKT​ 进行计算的。在代码中我们计算每个头的分数矩阵并应用了缩放因子 ( \sqrt{d_k} )。然后我们使用 softmax 函数将分数转换为注意力权重。 每个头的注意力权重被用来加权值矩阵然后进行加权求和得到头的输出。 最后我们将所有头的输出连接起来形成多头注意力机制的最终输出。连接是在最后一个维度上进行的确保了每个头的输出都被保持在同一位置。 在多头注意力机制中将所有头的输出连接起来时通常是在最后一个维度上进行连接也就是说特征是横着连接的。假设每个头的输出维度为 d k d_k dk​头的数量为 n u m _ h e a d s num\_heads num_heads那么每个头的输出将是一个形状为 ( batch_size , seq_length , d k ) (\text{batch\_size}, \text{seq\_length}, d_k) (batch_size,seq_length,dk​) 的张量。连接所有头的输出时我们将它们在最后一个维度上拼接起来形成一个形状为 ( batch_size , seq_length , d k × n u m _ h e a d s ) (\text{batch\_size}, \text{seq\_length}, d_k \times num\_heads) (batch_size,seq_length,dk​×num_heads) 的张量。 代码 # 多头注意力机制 def multi_head_attention(Q, K, V, num_heads):d_k Q.shape[-1] // num_headsall_heads []for i in range(num_heads):# 分头处理Q_head Q[:, i * d_k:(i 1) * d_k]K_head K[:, i * d_k:(i 1) * d_k]V_head V[:, i * d_k:(i 1) * d_k]# 计算单头注意力scores np.dot(Q_head, K_head.T) / np.sqrt(d_k)attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)head_output np.dot(attention_weights, V_head)all_heads.append(head_output)# 拼接所有头的输出multi_head_output np.concatenate(all_heads, axis-1)return multi_head_output6. Mask如何给上去的 mask是上三角掩码给入的时候是scores - mask * 1e9 # 应用掩码代码如下 # 带掩码的多头注意力机制 def masked_multi_head_attention(Q, K, V, num_heads):mask np.triu(np.ones((Q.shape[0], K.shape[0])), k1) # 上三角掩码d_k Q.shape[-1] // num_headsall_heads []for i in range(num_heads):# 分头处理Q_head Q[:, i * d_k:(i 1) * d_k]K_head K[:, i * d_k:(i 1) * d_k]V_head V[:, i * d_k:(i 1) * d_k]# 计算单头带掩码注意力scores np.dot(Q_head, K_head.T) / np.sqrt(d_k)scores - mask * 1e9 # 应用掩码attention_weights np.exp(scores) / np.sum(np.exp(scores), axis-1, keepdimsTrue)head_output np.dot(attention_weights, V_head)all_heads.append(head_output)# 拼接所有头的输出multi_head_output np.concatenate(all_heads, axis-1)return multi_head_output 7. 为何要位置编码 位置编码采用了一种基于正弦和余弦函数的方式这种方式能够确保不同位置的编码之间有一定的区分度且能够保持一定的周期性这有助于模型更好地捕捉序列中的长程依赖关系。 因此位置编码的作用可以总结为 提供序列中每个词汇的位置信息帮助模型理解序列的顺序关系。通过学习位置编码模型可以更好地捕捉序列中的长程依赖关系提高模型性能。 8. 为什么说Transformer可以并行化计算NLP任务 在RNN中每个时间步的输出都依赖于前一个时间步的输出因此无法并行计算。假设我们有一个RNN模型其隐藏状态 h t h_t ht​的计算公式如下所示 h t f ( h t − 1 , x t ) h_t f(h_{t-1}, x_t) ht​f(ht−1​,xt​) 其中 f f f是RNN的激活函数 h t h_t ht​是时间步 t t t的隐藏状态 x t x_t xt​是输入序列中时间步 t t t的输入。这些参数只有一套训练的时候只有计算时间步 t t t之后才能继续计算时间步 t 1 t1 t1。 相比之下在Transformer中Transformer模型中的自注意力机制通常会使用mask来确保在计算注意力权重时不会考虑到未来的信息从而使得计算可以并行进行。这个mask通常被称为attention mask。 在Transformer中为了实现自注意力机制的并行计算常用的方法是在计算注意力权重时引入一个mask矩阵将未来的信息屏蔽掉。这样在计算每个词与其他词之间的注意力时模型只会考虑到当前词及其之前的词而不会受到未来词的影响。 具体来说当计算注意力权重时可以将未来的位置的注意力权重设为负无穷大 − ∞ -\infty −∞这样经过softmax函数后未来位置的注意力权重就会变为0。这个操作可以通过在softmax函数之前对注意力分数进行mask实现。 形式上假设我们有一个注意力分数矩阵 S S S其中 S i j S_{ij} Sij​表示第 i i i个词对第 j j j个词的注意力分数。为了屏蔽未来位置我们可以构造一个mask矩阵 M M M其中 M i j M_{ij} Mij​表示第 i i i个词是否可以注意到第 j j j个词。那么在计算注意力权重时我们可以将 S S S和 M M M相加然后应用softmax函数 Attention ( Q , K , V ) softmax ( Q K T d k M ) V \text{Attention}(Q,K,V) \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}} M\right)V Attention(Q,K,V)softmax(dk​ ​QKT​M)V 通过引入这样的maskTransformer可以在并行计算每个词与其他词之间的关系时确保不会考虑到未来的信息从而实现并行化处理NLP任务的能力。 9. MultiheadAttention的Pytorch官方代码 MultiheadAttention https://pytorch.org/docs/stable/generated/torch.nn.MultiheadAttention.html 代码中嵌入层向量还需要经过q_proj_weight 、k_proj_weight 、v_proj_weight 后才给入到注意力计算而本文的代码为了简单方便描述过程直接计算了下面是官网代码片段 10. 何为QKV QKV即是注意力机制重点是“注意力”通过这种计算可以讲更任务更重心的位置放在更关键的位置上。QK的组合是一种注意力选择选择V中的重要特征。 QKV 注意力机制是通过计算查询Query与键Key之间的相似度来衡量不同单词之间的关联程度进而确定每个单词对于其他单词的重要性从而实现更精准的信息提取和编码。具体来说QKV 注意力机制的有效性源自于以下几个方面 投影矩阵的作用首先通过投影矩阵将原始的词向量映射到 Q、K、V 空间。这个映射过程有助于模型学习到不同维度上的语义信息并且使得后续计算更具有表征性。这样做的好处在于通过对输入进行线性变换模型可以更灵活地调整每个词在不同空间的表示从而更好地匹配和捕捉语义关系。 相似度计算Q 和 K 之间的点积运算衡量了查询与键之间的相似度。这一步是注意力机制的关键因为它决定了不同单词之间的关联程度。点积计算的结果越大表示两个向量之间的相关性越高因此在后续的 Softmax 函数中会得到更高的权重从而更多地关注相关性较高的单词。 归一化Softmax 函数对相似度进行归一化将其转化为概率分布。这一步使得模型能够更加专注于重要的信息同时抑制不相关信息的影响。通过将相似度转化为概率分布模型可以更好地选择与当前查询最相关的信息提高了信息的利用效率。 加权平均最后将归一化后的相似度作为权重对值向量 V 进行加权平均。这一步实际上是根据查询和键之间的相似度来调整值的重要性从而得到最终的输出。这样做的好处在于模型能够在保留原始信息的基础上更好地关注与当前查询相关的信息实现了信息的精准提取和利用。 总的来说QKV 注意力机制通过将输入进行线性变换并通过点积相似度计算、归一化和加权平均等步骤实现了对不同单词之间关联程度的准确度量和精细控制从而有效地提升了模型的表征能力和性能。 视频里有讲计算过程。不同单词的词向量先被QKV投影矩阵W投影到qkv 那么计算注意力的过程就如下图片 Attention ( Q , K , V ) softmax ( Q K T d k ) V \text{Attention}(Q, K, V) \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)softmax(dk​ ​QKT​)V 也就是这个图 11. 为何不是BN 使用的是Layer Normalization 而不是BN为何 Layer Normalization (LN) 是一种深度学习中的归一化技术它用于将神经网络中的每个层的输入进行归一化处理。Layer Normalization 将每个样本的输入进行归一化即对每个样本在每个特征维度上进行归一化而不是像 BN 那样对每个特征维度在一个 batch 中进行归一化。 LN 的计算方式如下 对于一个输入向量 ( x [x_1, x_2, …, x_n] )计算均值 ( \mu ) 和方差 ( \sigma^2 ) μ 1 n ∑ i 1 n x i \mu \frac{1}{n} \sum_{i1}^{n} x_i μn1​i1∑n​xi​ σ 2 1 n ∑ i 1 n ( x i − μ ) 2 \sigma^2 \frac{1}{n} \sum_{i1}^{n} (x_i - \mu)^2 σ2n1​i1∑n​(xi​−μ)2 对输入向量 ( x ) 进行归一化 x i ^ x i − μ σ 2 ϵ \hat{x_i} \frac{x_i - \mu}{\sqrt{\sigma^2 \epsilon}} xi​^​σ2ϵ ​xi​−μ​ 其中( \epsilon ) 是一个很小的常数避免分母为零。 将归一化后的向量 ( \hat{x} ) 通过缩放参数 ( \gamma ) 和偏移参数 ( \beta ) 进行线性变换 y i γ x i ^ β y_i \gamma \hat{x_i} \beta yi​γxi​^​β 这样LN 会保留每个样本的独立特性而不会像 BN 那样受到 batch 中其他样本的影响。 BN受到其他样本影响太大可以比作这个图 12. RNN的梯度消失是指什么 RNN的梯度消失和其他模型的梯度消失有本质差别 一般意义的梯度消失是指在神经网络的反向传播过程中梯度在经过多个层次传播时逐渐变小并最终接近于零的现象。这导致在更新网络参数时某些层的参数几乎没有更新从而使得这些层无法有效地学习到输入数据的特征。【关键词层数影响】 对于其他类型的神经网络比如深度前馈神经网络Feedforward Neural Networks梯度消失通常与网络的深度有关。在深度神经网络中梯度需要通过多个层次反向传播而在每一层中都可能受到梯度逐渐衰减的影响特别是在使用一些传统的激活函数如 sigmoid 或 tanh时更容易出现这种情况。 相比之下RNN 的梯度消失问题与其循环结构和时间依赖关系密切相关。由于 RNN 的循环连接使得网络能够处理序列数据并在每个时间步都与前一个时间步相关联梯度需要在时间维度上传播。因此RNN 的梯度消失问题通常与序列长度、时间步数以及网络架构中的循环连接有关。【关键词多个时间步数迭代多次迭代后的影响】 如何降低RNN的梯度消失 长短期记忆网络LSTM和门控循环单元GRU是为了解决 RNN 中的梯度消失问题而设计的。它们通过引入门控机制可以选择性地记忆或遗忘先前的信息从而更好地捕捉长期依赖关系。下面我将简要介绍它们的门控机制和公式。 长短期记忆网络LSTM LSTM 引入了三个门输入门input gate、遗忘门forget gate和输出门output gate。这些门控制着信息的流动从而允许网络在处理序列数据时选择性地记忆或遗忘信息。 输入门 i t σ ( W i ⋅ [ h t − 1 , x t ] b i ) i_t \sigma(W_i \cdot [h_{t-1}, x_t] b_i) it​σ(Wi​⋅[ht−1​,xt​]bi​) 遗忘门 f t σ ( W f ⋅ [ h t − 1 , x t ] b f ) f_t \sigma(W_f \cdot [h_{t-1}, x_t] b_f) ft​σ(Wf​⋅[ht−1​,xt​]bf​) 输出门 o t σ ( W o ⋅ [ h t − 1 , x t ] b o ) o_t \sigma(W_o \cdot [h_{t-1}, x_t] b_o) ot​σ(Wo​⋅[ht−1​,xt​]bo​) 细胞状态更新 c t f t ⊙ c t − 1 i t ⊙ tanh ( W c ⋅ [ h t − 1 , x t ] b c ) c_t f_t \odot c_{t-1} i_t \odot \text{tanh}(W_c \cdot [h_{t-1}, x_t] b_c) ct​ft​⊙ct−1​it​⊙tanh(Wc​⋅[ht−1​,xt​]bc​) 隐藏状态更新 h t o t ⊙ tanh ( c t ) h_t o_t \odot \text{tanh}(c_t) ht​ot​⊙tanh(ct​) 其中(\sigma) 是 Sigmoid 函数(\odot) 表示逐元素相乘(W) 和 (b) 是模型的权重和偏置([h_{t-1}, x_t]) 是上一时间步的隐藏状态和当前时间步的输入的连接(\text{tanh}) 是双曲正切函数。 门控循环单元GRU GRU 也具有类似的门控机制但它将输入门和遗忘门合并为一个单一的更新门update gate并引入了重置门reset gate来控制历史信息的保留。GRU 的公式如下 更新门 z t σ ( W z ⋅ [ h t − 1 , x t ] b z ) z_t \sigma(W_z \cdot [h_{t-1}, x_t] b_z) zt​σ(Wz​⋅[ht−1​,xt​]bz​) 重置门 r t σ ( W r ⋅ [ h t − 1 , x t ] b r ) r_t \sigma(W_r \cdot [h_{t-1}, x_t] b_r) rt​σ(Wr​⋅[ht−1​,xt​]br​) 更新隐藏状态 h t ( 1 − z t ) ⊙ h t − 1 z t ⊙ tanh ( W h ⋅ [ r t ⊙ h t − 1 , x t ] b h ) h_t (1 - z_t) \odot h_{t-1} z_t \odot \text{tanh}(W_h \cdot [r_t \odot h_{t-1}, x_t] b_h) ht​(1−zt​)⊙ht−1​zt​⊙tanh(Wh​⋅[rt​⊙ht−1​,xt​]bh​) 其中(z_t) 是更新门(r_t) 是重置门(W) 和 (b) 是模型的权重和偏置([h_{t-1}, x_t]) 是上一时间步的隐藏状态和当前时间步的输入的连接(\odot) 表示逐元素相乘(\sigma) 是 Sigmoid 函数(\text{tanh}) 是双曲正切函数。 通过这些门控机制LSTM 和 GRU 能够更好地控制信息的流动并且减轻了梯度消失问题使得网络能够更有效地捕捉长期依赖关系。
http://www.yingshimen.cn/news/113930/

相关文章:

  • 东莞免费建站模板有没有专门做淘宝客的网站
  • 专题页网站怎么做建筑网格
  • 中国风网站欣赏wordpress网站访问验证码
  • wordpress时尚英文站赤峰网站制作公司
  • 三河网站建设wordpress主查询
  • scratch在线编程网站触屏手机网站建设
  • wpf 网站开发广东建设工程信息网官网证书查询
  • vue网站引导页怎么做php网站开发 pdf
  • 网站建设方案推销建筑公司网站平台
  • 南沙外贸网站建设网站怎么做图片动态图片不显示
  • 福安网站设计关于解决网站 建设的请示
  • 东莞机械网络推广成都网站排名生客seo怎么样
  • 网站建设规划表网站网络服务器是什么情况
  • 做王境泽表情的网站10条重大新闻
  • 洛阳霞光做网站的公司西安网页设计培训班费用
  • 长春哪家公司做网站好网站建设好之后怎么自己推广
  • 汉中市建设工程招投标信息网官网江门seo网络推广
  • 企业门户网站建设渠道wordpress淘宝客建站教程
  • 怎么进入微信官方网站铜川网站建设哪家好
  • 江宁区建设局网站足球世界排名国家
  • 做软件赚钱的网站有哪些锦州做网站公司哪家好
  • 苏州高端网站建设企业注册会计师报考条件和时间2023
  • 如何做微信电子书下载网站wordpress 手机api接口
  • 网站建设出错1004wordpress 排除文章
  • 高端网站建设教程合肥如何做百度的网站
  • 龙泉公路建设投资有限公司网站网络营销的应用研究论文
  • 俄语网站推广通搭建网站案例
  • 做网站群的公司阿里巴巴 网站设计
  • 福州网站建设服务平台龙华做网站联系电话
  • 网站布局教程网站cron