python-pytorch编写transformer模型实现翻译0.5.00-写模型

打印 上一主题 下一主题

主题 960|帖子 960|积分 2880

前言

在网上看了一篇文章,借用了文章的大部分代码,并对代码的预测进行修改使得可以正确的预测了,具体链接找了半天找不到
代码

  1. import numpy as np # 导入 numpy 库
  2. import torch # 导入 torch 库
  3. import torch.nn as nn # 导入 torch.nn 库
  4. d_k = 64 # K(=Q) 维度
  5. d_v = 64 # V 维度
  6. # 定义缩放点积注意力类
  7. class ScaledDotProductAttention(nn.Module):
  8.     def __init__(self):
  9.         super(ScaledDotProductAttention, self).__init__()        
  10.     def forward(self, Q, K, V, attn_mask):
  11.         #------------------------- 维度信息 --------------------------------        
  12.         # Q K V [batch_size, n_heads, len_q/k/v, dim_q=k/v] (dim_q=dim_k)
  13.         # attn_mask [batch_size, n_heads, len_q, len_k]
  14.         #----------------------------------------------------------------
  15.         # 计算注意力分数(原始权重)[batch_size,n_heads,len_q,len_k]
  16.         scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k)
  17.         #------------------------- 维度信息 --------------------------------        
  18.         # scores [batch_size, n_heads, len_q, len_k]
  19.         #-----------------------------------------------------------------        
  20.         # 使用注意力掩码,将 attn_mask 中值为 1 的位置的权重替换为极小值
  21.         #------------------------- 维度信息 --------------------------------
  22.         # attn_mask [batch_size, n_heads, len_q, len_k], 形状和 scores 相同
  23.         #-----------------------------------------------------------------   
  24.         scores.masked_fill_(attn_mask, -1e9)
  25.         # 对注意力分数进行 softmax 归一化
  26.         weights = nn.Softmax(dim=-1)(scores)
  27.         #------------------------- 维度信息 --------------------------------
  28.         # weights [batch_size, n_heads, len_q, len_k], 形状和 scores 相同
  29.         #-----------------------------------------------------------------         
  30.         # 计算上下文向量(也就是注意力的输出), 是上下文信息的紧凑表示
  31.         context = torch.matmul(weights, V)
  32.         #------------------------- 维度信息 --------------------------------
  33.         # context [batch_size, n_heads, len_q, dim_v]
  34.         #-----------------------------------------------------------------   
  35.         return context, weights # 返回上下文向量和注意力分数
  36. # 定义多头自注意力类
  37. d_embedding = 512  # Embedding 的维度
  38. n_heads = 8  # Multi-Head Attention 中头的个数
  39. batch_size = 6 # 每一批的数据大小
  40. class MultiHeadAttention(nn.Module):
  41.     def __init__(self):
  42.         super(MultiHeadAttention, self).__init__()
  43.         self.W_Q = nn.Linear(d_embedding, d_k * n_heads) # Q的线性变换层
  44.         self.W_K = nn.Linear(d_embedding, d_k * n_heads) # K的线性变换层
  45.         self.W_V = nn.Linear(d_embedding, d_v * n_heads) # V的线性变换层
  46.         self.linear = nn.Linear(n_heads * d_v, d_embedding)
  47.         self.layer_norm = nn.LayerNorm(d_embedding)
  48.     def forward(self, Q, K, V, attn_mask):
  49.         #------------------------- 维度信息 --------------------------------
  50.         # Q K V [batch_size, len_q/k/v, embedding_dim]
  51.         #-----------------------------------------------------------------        
  52.         residual, batch_size = Q, Q.size(0) # 保留残差连接
  53.         # 将输入进行线性变换和重塑,以便后续处理
  54.         q_s = self.W_Q(Q).view(batch_size, -1, n_heads, d_k).transpose(1,2)        
  55.         k_s = self.W_K(K).view(batch_size, -1, n_heads, d_k).transpose(1,2)
  56.         v_s = self.W_V(V).view(batch_size, -1, n_heads, d_v).transpose(1,2)
  57.         #------------------------- 维度信息 --------------------------------
  58.         # q_s k_s v_s: [batch_size, n_heads, len_q/k/v, d_q=k/v]
  59.         #-----------------------------------------------------------------
  60.         # 将注意力掩码复制到多头 attn_mask: [batch_size, n_heads, len_q, len_k]
  61.         attn_mask = attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1)
  62.         #------------------------- 维度信息 --------------------------------
  63.         # attn_mask [batch_size, n_heads, len_q, len_k]
  64.         #-----------------------------------------------------------------
  65.         # 使用缩放点积注意力计算上下文和注意力权重
  66.         context, weights = ScaledDotProductAttention()(q_s, k_s, v_s, attn_mask)
  67.         #------------------------- 维度信息 --------------------------------
  68.         # context [batch_size, n_heads, len_q, dim_v]
  69.         # weights [batch_size, n_heads, len_q, len_k]
  70.         #-----------------------------------------------------------------
  71.         # 通过调整维度将多个头的上下文向量连接在一起
  72.         context = context.transpose(1, 2).contiguous().view(batch_size, -1, n_heads * d_v)
  73.         #------------------------- 维度信息 --------------------------------
  74.         # context [batch_size, len_q, n_heads * dim_v]
  75.         #-----------------------------------------------------------------        
  76.         # 用一个线性层把连接后的多头自注意力结果转换,原始地嵌入维度
  77.         output = self.linear(context)
  78.         #------------------------- 维度信息 --------------------------------
  79.         # output [batch_size, len_q, embedding_dim]
  80.         #-----------------------------------------------------------------        
  81.         # 与输入 (Q) 进行残差链接,并进行层归一化后输出
  82.         output = self.layer_norm(output + residual)
  83.         #------------------------- 维度信息 --------------------------------
  84.         # output [batch_size, len_q, embedding_dim]
  85.         #-----------------------------------------------------------------        
  86.         return output, weights # 返回层归一化的输出和注意力权重
  87. # 定义逐位置前馈网络类
  88. class PoswiseFeedForwardNet(nn.Module):
  89.     def __init__(self, d_ff=2048):
  90.         super(PoswiseFeedForwardNet, self).__init__()
  91.         # 定义一维卷积层 1,用于将输入映射到更高维度
  92.         self.conv1 = nn.Conv1d(in_channels=d_embedding, out_channels=d_ff, kernel_size=1)
  93.         # 定义一维卷积层 2,用于将输入映射回原始维度
  94.         self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_embedding, kernel_size=1)
  95.         # 定义层归一化
  96.         self.layer_norm = nn.LayerNorm(d_embedding)
  97.     def forward(self, inputs):
  98.         #------------------------- 维度信息 --------------------------------
  99.         # inputs [batch_size, len_q, embedding_dim]
  100.         #----------------------------------------------------------------                       
  101.         residual = inputs  # 保留残差连接
  102.         # 在卷积层 1 后使用 ReLU 激活函数
  103.         output = nn.ReLU()(self.conv1(inputs.transpose(1, 2)))
  104.         #------------------------- 维度信息 --------------------------------
  105.         # output [batch_size, d_ff, len_q]
  106.         #----------------------------------------------------------------
  107.         # 使用卷积层 2 进行降维
  108.         output = self.conv2(output).transpose(1, 2)
  109.         #------------------------- 维度信息 --------------------------------
  110.         # output [batch_size, len_q, embedding_dim]
  111.         #----------------------------------------------------------------
  112.         # 与输入进行残差链接,并进行层归一化
  113.         output = self.layer_norm(output + residual)
  114.         #------------------------- 维度信息 --------------------------------
  115.         # output [batch_size, len_q, embedding_dim]
  116.         #----------------------------------------------------------------
  117.         return output # 返回加入残差连接后层归一化的结果
  118. # 生成正弦位置编码表的函数,用于在 Transformer 中引入位置信息
  119. def get_sin_enc_table(n_position, embedding_dim):
  120.     #------------------------- 维度信息 --------------------------------
  121.     # n_position: 输入序列的最大长度
  122.     # embedding_dim: 词嵌入向量的维度
  123.     #-----------------------------------------------------------------   
  124.     # 根据位置和维度信息,初始化正弦位置编码表
  125.     sinusoid_table = np.zeros((n_position, embedding_dim))   
  126.     # 遍历所有位置和维度,计算角度值
  127.     for pos_i in range(n_position):
  128.         for hid_j in range(embedding_dim):
  129.             angle = pos_i / np.power(10000, 2 * (hid_j // 2) / embedding_dim)
  130.             sinusoid_table[pos_i, hid_j] = angle   
  131.     # 计算正弦和余弦值
  132.     sinusoid_table[:, 0::2] = np.sin(sinusoid_table[:, 0::2])  # dim 2i 偶数维
  133.     sinusoid_table[:, 1::2] = np.cos(sinusoid_table[:, 1::2])  # dim 2i+1 奇数维   
  134.     #------------------------- 维度信息 --------------------------------
  135.     # sinusoid_table 的维度是 [n_position, embedding_dim]
  136.     #----------------------------------------------------------------   
  137.     return torch.FloatTensor(sinusoid_table)  # 返回正弦位置编码表
  138. # 定义填充注意力掩码函数
  139. def get_attn_pad_mask(seq_q, seq_k):
  140.     #------------------------- 维度信息 --------------------------------
  141.     # seq_q 的维度是 [batch_size, len_q]
  142.     # seq_k 的维度是 [batch_size, len_k]
  143.     #-----------------------------------------------------------------
  144.     batch_size, len_q = seq_q.size()
  145.     batch_size, len_k = seq_k.size()
  146.     # 生成布尔类型张量
  147.     pad_attn_mask = seq_k.data.eq(0).unsqueeze(1)  # <PAD>token 的编码值为 0
  148.     #------------------------- 维度信息 --------------------------------
  149.     # pad_attn_mask 的维度是 [batch_size,1,len_k]
  150.     #-----------------------------------------------------------------
  151.     # 变形为与注意力分数相同形状的张量
  152.     pad_attn_mask = pad_attn_mask.expand(batch_size, len_q, len_k)
  153.     #------------------------- 维度信息 --------------------------------
  154.     # pad_attn_mask 的维度是 [batch_size,len_q,len_k]
  155.     #-----------------------------------------------------------------
  156.     return pad_attn_mask
  157. # 定义编码器层类
  158. class EncoderLayer(nn.Module):
  159.     def __init__(self):
  160.         super(EncoderLayer, self).__init__()        
  161.         self.enc_self_attn = MultiHeadAttention() # 多头自注意力层        
  162.         self.pos_ffn = PoswiseFeedForwardNet() # 位置前馈神经网络层
  163.     def forward(self, enc_inputs, enc_self_attn_mask):
  164.         #------------------------- 维度信息 --------------------------------
  165.         # enc_inputs 的维度是 [batch_size, seq_len, embedding_dim]
  166.         # enc_self_attn_mask 的维度是 [batch_size, seq_len, seq_len]
  167.         #-----------------------------------------------------------------
  168.         # 将相同的 Q,K,V 输入多头自注意力层 , 返回的 attn_weights 增加了头数  
  169.         enc_outputs, attn_weights = self.enc_self_attn(enc_inputs, enc_inputs,
  170.                                                enc_inputs, enc_self_attn_mask)
  171.         #------------------------- 维度信息 --------------------------------
  172.         # enc_outputs 的维度是 [batch_size, seq_len, embedding_dim]
  173.         # attn_weights 的维度是 [batch_size, n_heads, seq_len, seq_len]      
  174.         # 将多头自注意力 outputs 输入位置前馈神经网络层
  175.         enc_outputs = self.pos_ffn(enc_outputs) # 维度与 enc_inputs 相同
  176.         #------------------------- 维度信息 --------------------------------
  177.         # enc_outputs 的维度是 [batch_size, seq_len, embedding_dim]
  178.         #-----------------------------------------------------------------
  179.         return enc_outputs, attn_weights # 返回编码器输出和每层编码器注意力权重
  180. # 定义编码器类
  181. n_layers = 6  # 设置 Encoder 的层数
  182. class Encoder(nn.Module):
  183.     def __init__(self, corpus):
  184.         super(Encoder, self).__init__()        
  185.         self.src_emb = nn.Embedding(len(corpus.src_vocab), d_embedding) # 词嵌入层
  186.         self.pos_emb = nn.Embedding.from_pretrained( \
  187.           get_sin_enc_table(corpus.src_len+1, d_embedding), freeze=True) # 位置嵌入层
  188.         self.layers = nn.ModuleList(EncoderLayer() for _ in range(n_layers))# 编码器层数
  189.     def forward(self, enc_inputs):  
  190.         #------------------------- 维度信息 --------------------------------
  191.         # enc_inputs 的维度是 [batch_size, source_len]
  192.         #-----------------------------------------------------------------
  193.         # 创建一个从 1 到 source_len 的位置索引序列
  194.         pos_indices = torch.arange(1, enc_inputs.size(1) + 1).unsqueeze(0).to(enc_inputs)
  195.         #------------------------- 维度信息 --------------------------------
  196.         # pos_indices 的维度是 [1, source_len]
  197.         #-----------------------------------------------------------------            
  198.         # 对输入进行词嵌入和位置嵌入相加 [batch_size, source_len,embedding_dim]
  199.         enc_outputs = self.src_emb(enc_inputs) + self.pos_emb(pos_indices)
  200.         #------------------------- 维度信息 --------------------------------
  201.         # enc_outputs 的维度是 [batch_size, seq_len, embedding_dim]
  202.         #-----------------------------------------------------------------
  203.         # 生成自注意力掩码
  204.         enc_self_attn_mask = get_attn_pad_mask(enc_inputs, enc_inputs)
  205.         #------------------------- 维度信息 --------------------------------
  206.         # enc_self_attn_mask 的维度是 [batch_size, len_q, len_k]        
  207.         #-----------------------------------------------------------------         
  208.         enc_self_attn_weights = [] # 初始化 enc_self_attn_weights
  209.         # 通过编码器层 [batch_size, seq_len, embedding_dim]
  210.         for layer in self.layers:
  211.             enc_outputs, enc_self_attn_weight = layer(enc_outputs, enc_self_attn_mask)
  212.             enc_self_attn_weights.append(enc_self_attn_weight)
  213.         #------------------------- 维度信息 --------------------------------
  214.         # enc_outputs 的维度是 [batch_size, seq_len, embedding_dim] 维度与 enc_inputs 相同
  215.         # enc_self_attn_weights 是一个列表,每个元素的维度是 [batch_size, n_heads, seq_len, seq_len]         
  216.         #-----------------------------------------------------------------
  217.         return enc_outputs, enc_self_attn_weights # 返回编码器输出和编码器注意力权重
  218. # 生成后续注意力掩码的函数,用于在多头自注意力计算中忽略未来信息
  219. def get_attn_subsequent_mask(seq):
  220.     #------------------------- 维度信息 --------------------------------
  221.     # seq 的维度是 [batch_size, seq_len(Q)=seq_len(K)]
  222.     #-----------------------------------------------------------------
  223.     # 获取输入序列的形状
  224.     attn_shape = [seq.size(0), seq.size(1), seq.size(1)]  
  225.     #------------------------- 维度信息 --------------------------------
  226.     # attn_shape 是一个一维张量 [batch_size, seq_len(Q), seq_len(K)]
  227.     #-----------------------------------------------------------------
  228.     # 使用 numpy 创建一个上三角矩阵(triu = triangle upper)
  229.     subsequent_mask = np.triu(np.ones(attn_shape), k=1)
  230.     #------------------------- 维度信息 --------------------------------
  231.     # subsequent_mask 的维度是 [batch_size, seq_len(Q), seq_len(K)]
  232.     #-----------------------------------------------------------------
  233.     # 将 numpy 数组转换为 PyTorch 张量,并将数据类型设置为 byte(布尔值)
  234.     subsequent_mask = torch.from_numpy(subsequent_mask).byte()
  235.     #------------------------- 维度信息 --------------------------------
  236.     # 返回的 subsequent_mask 的维度是 [batch_size, seq_len(Q), seq_len(K)]
  237.     #-----------------------------------------------------------------
  238.     return subsequent_mask # 返回后续位置的注意力掩码
  239. # 定义解码器层类
  240. class DecoderLayer(nn.Module):
  241.     def __init__(self):
  242.         super(DecoderLayer, self).__init__()        
  243.         self.dec_self_attn = MultiHeadAttention() # 多头自注意力层      
  244.         self.dec_enc_attn = MultiHeadAttention()  # 多头自注意力层,连接编码器和解码器        
  245.         self.pos_ffn = PoswiseFeedForwardNet() # 位置前馈神经网络层
  246.     def forward(self, dec_inputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask):
  247.         #------------------------- 维度信息 --------------------------------
  248.         # dec_inputs 的维度是 [batch_size, target_len, embedding_dim]
  249.         # enc_outputs 的维度是 [batch_size, source_len, embedding_dim]
  250.         # dec_self_attn_mask 的维度是 [batch_size, target_len, target_len]
  251.         # dec_enc_attn_mask 的维度是 [batch_size, target_len, source_len]
  252.         #-----------------------------------------------------------------      
  253.         # 将相同的 Q,K,V 输入多头自注意力层
  254.         dec_outputs, dec_self_attn = self.dec_self_attn(dec_inputs, dec_inputs,
  255.                                                         dec_inputs, dec_self_attn_mask)
  256.         #------------------------- 维度信息 --------------------------------
  257.         # dec_outputs 的维度是 [batch_size, target_len, embedding_dim]
  258.         # dec_self_attn 的维度是 [batch_size, n_heads, target_len, target_len]
  259.         #-----------------------------------------------------------------        
  260.         # 将解码器输出和编码器输出输入多头自注意力层
  261.         dec_outputs, dec_enc_attn = self.dec_enc_attn(dec_outputs, enc_outputs,
  262.                                                       enc_outputs, dec_enc_attn_mask)
  263.         #------------------------- 维度信息 --------------------------------
  264.         # dec_outputs 的维度是 [batch_size, target_len, embedding_dim]
  265.         # dec_enc_attn 的维度是 [batch_size, n_heads, target_len, source_len]
  266.         #-----------------------------------------------------------------         
  267.         # 输入位置前馈神经网络层
  268.         dec_outputs = self.pos_ffn(dec_outputs)
  269.         #------------------------- 维度信息 --------------------------------
  270.         # dec_outputs 的维度是 [batch_size, target_len, embedding_dim]
  271.         # dec_self_attn 的维度是 [batch_size, n_heads, target_len, target_len]
  272.         # dec_enc_attn 的维度是 [batch_size, n_heads, target_len, source_len]   
  273.         #-----------------------------------------------------------------
  274.         # 返回解码器层输出,每层的自注意力和解 - 编码器注意力权重
  275.         return dec_outputs, dec_self_attn, dec_enc_attn
  276. #  定义解码器类
  277. n_layers = 6  # 设置 Decoder 的层数
  278. class Decoder(nn.Module):
  279.     def __init__(self, corpus):
  280.         super(Decoder, self).__init__()
  281.         self.tgt_emb = nn.Embedding(len(corpus.tgt_vocab), d_embedding) # 词嵌入层
  282.         self.pos_emb = nn.Embedding.from_pretrained( \
  283.            get_sin_enc_table(corpus.tgt_len+1, d_embedding), freeze=True) # 位置嵌入层        
  284.         self.layers = nn.ModuleList([DecoderLayer() for _ in range(n_layers)]) # 叠加多层
  285.     def forward(self, dec_inputs, enc_inputs, enc_outputs):
  286.         #------------------------- 维度信息 --------------------------------
  287.         # dec_inputs 的维度是 [batch_size, target_len]
  288.         # enc_inputs 的维度是 [batch_size, source_len]
  289.         # enc_outputs 的维度是 [batch_size, source_len, embedding_dim]
  290.         #-----------------------------------------------------------------   
  291.         # 创建一个从 1 到 source_len 的位置索引序列
  292.         pos_indices = torch.arange(1, dec_inputs.size(1) + 1).unsqueeze(0).to(dec_inputs)
  293.         #------------------------- 维度信息 --------------------------------
  294.         # pos_indices 的维度是 [1, target_len]
  295.         #-----------------------------------------------------------------              
  296.         # 对输入进行词嵌入和位置嵌入相加
  297.         dec_outputs = self.tgt_emb(dec_inputs) + self.pos_emb(pos_indices)
  298.         #------------------------- 维度信息 --------------------------------
  299.         # dec_outputs 的维度是 [batch_size, target_len, embedding_dim]
  300.          #-----------------------------------------------------------------        
  301.         # 生成解码器自注意力掩码和解码器 - 编码器注意力掩码
  302.         dec_self_attn_pad_mask = get_attn_pad_mask(dec_inputs, dec_inputs) # 填充位掩码
  303.         dec_self_attn_subsequent_mask = get_attn_subsequent_mask(dec_inputs) # 后续位掩码
  304.         dec_self_attn_mask = torch.gt((dec_self_attn_pad_mask \
  305.                                        + dec_self_attn_subsequent_mask), 0)
  306.         dec_enc_attn_mask = get_attn_pad_mask(dec_inputs, enc_inputs) # 解码器 - 编码器掩码
  307.         #------------------------- 维度信息 --------------------------------        
  308.         # dec_self_attn_pad_mask 的维度是 [batch_size, target_len, target_len]
  309.         # dec_self_attn_subsequent_mask 的维度是 [batch_size, target_len, target_len]
  310.         # dec_self_attn_mask 的维度是 [batch_size, target_len, target_len]
  311.         # dec_enc_attn_mask 的维度是 [batch_size, target_len, source_len]
  312.          #-----------------------------------------------------------------      
  313.         dec_self_attns, dec_enc_attns = [], [] # 初始化 dec_self_attns, dec_enc_attns
  314.         # 通过解码器层 [batch_size, seq_len, embedding_dim]
  315.         for layer in self.layers:
  316.             dec_outputs, dec_self_attn, dec_enc_attn = layer(dec_outputs, enc_outputs,
  317.                                                dec_self_attn_mask, dec_enc_attn_mask)
  318.             dec_self_attns.append(dec_self_attn)
  319.             dec_enc_attns.append(dec_enc_attn)
  320.         #------------------------- 维度信息 --------------------------------
  321.         # dec_outputs 的维度是 [batch_size, target_len, embedding_dim]
  322.         # dec_self_attns 是一个列表,每个元素的维度是 [batch_size, n_heads, target_len, target_len]
  323.         # dec_enc_attns 是一个列表,每个元素的维度是 [batch_size, n_heads, target_len, source_len]
  324.         #-----------------------------------------------------------------
  325.         # 返回解码器输出,解码器自注意力和解码器 - 编码器注意力权重      
  326.         return dec_outputs, dec_self_attns, dec_enc_attns
  327. # 定义 Transformer 模型
  328. class Transformer(nn.Module):
  329.     def __init__(self, corpus):
  330.         super(Transformer, self).__init__()        
  331.         self.encoder = Encoder(corpus) # 初始化编码器实例        
  332.         self.decoder = Decoder(corpus) # 初始化解码器实例
  333.         # 定义线性投影层,将解码器输出转换为目标词汇表大小的概率分布
  334.         self.projection = nn.Linear(d_embedding, len(corpus.tgt_vocab), bias=False)
  335.     def forward(self, enc_inputs, dec_inputs):
  336.         #------------------------- 维度信息 --------------------------------
  337.         # enc_inputs 的维度是 [batch_size, source_seq_len]
  338.         # dec_inputs 的维度是 [batch_size, target_seq_len]
  339.         #-----------------------------------------------------------------        
  340.         # 将输入传递给编码器,并获取编码器输出和自注意力权重        
  341.         enc_outputs, enc_self_attns = self.encoder(enc_inputs)
  342.         #------------------------- 维度信息 --------------------------------
  343.         # enc_outputs 的维度是 [batch_size, source_len, embedding_dim]
  344.         # enc_self_attns 是一个列表,每个元素的维度是 [batch_size, n_heads, src_seq_len, src_seq_len]        
  345.         #-----------------------------------------------------------------         
  346.         # 将编码器输出、解码器输入和编码器输入传递给解码器
  347.         # 获取解码器输出、解码器自注意力权重和编码器 - 解码器注意力权重     
  348.         dec_outputs, dec_self_attns, dec_enc_attns = self.decoder(dec_inputs, enc_inputs, enc_outputs)
  349.         #------------------------- 维度信息 --------------------------------
  350.         # dec_outputs 的维度是 [batch_size, target_len, embedding_dim]
  351.         # dec_self_attns 是一个列表,每个元素的维度是 [batch_size, n_heads, tgt_seq_len, src_seq_len]
  352.         # dec_enc_attns 是一个列表,每个元素的维度是 [batch_size, n_heads, tgt_seq_len, src_seq_len]   
  353.         #-----------------------------------------------------------------               
  354.         # 将解码器输出传递给投影层,生成目标词汇表大小的概率分布
  355.         dec_logits = self.projection(dec_outputs)  
  356.         #------------------------- 维度信息 --------------------------------
  357.         # dec_logits 的维度是 [batch_size, tgt_seq_len, tgt_vocab_size]
  358.         #-----------------------------------------------------------------
  359.         # 返回逻辑值 ( 原始预测结果 ), 编码器自注意力权重,解码器自注意力权重,解 - 编码器注意力权重
  360.         return dec_logits, enc_self_attns, dec_self_attns, dec_enc_attns
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我爱普洱茶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表