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

江苏公众科技网站建设wordpress提速

江苏公众科技网站建设,wordpress提速,天河建设网站外包,运维工程师主要做什么理论基础 Transformer#xff08;来自2017年google发表的Attention Is All You Need (arxiv.org) #xff09;#xff0c;接上面一篇attention之后#xff0c;transformer是基于自注意力基础上引申出来的结构#xff0c;其主要解决了seq2seq的两个问题: 考虑了原序列和目…理论基础 Transformer来自2017年google发表的Attention Is All You Need (arxiv.org) 接上面一篇attention之后transformer是基于自注意力基础上引申出来的结构其主要解决了seq2seq的两个问题: 考虑了原序列和目标序列自身内部的自注意力大大降低的计算成本以及复杂度完全由全连接层替代了时序模型使得模型可以并行处理 自从transformer 架构出现后基于transformer的大模型就开始遍地开花可以看到下图中超过百万级别的大模型凑够18年以后就层出不穷。 transformer的整体结构如下图整体可以分成9各部分: 其中红线标记的就是transformer 独有的结构主要是多头自注意力位置编码。 缩放点积注意力 自注意力简而言之就是输入向量X通过一系列线性变换后得到了一个同样维度的X’但是这个X’ 不是简单的word2vec 而是一个动态的阅读过上下文的X’ 它包含了丰富的信息。具体的变换操作可以参考上一篇博客Attention注意力机制。 逐位置前馈网络 对多头注意力的输出(batch , seq , embedding_size)继续多一层线性变换并且是逐位置的进行线性变换后输出依然是(batch , seq , embedding_size)。这里的作用其实主要有两个 对输入序列中的每个位置的表示进行变换这里的逐位置意思是每个位置经过同样的权重和偏置可以看作是1*1 卷积后得到输出这里是逐位置的变换而不是整体将整个seq全部展开后进行变换是为了不引入顺序的依赖性并且利用transformer架构中的并行处理逐位置的前向传播网络还有助于增加模型的表达能力可以让模型学到更复杂的特征表示因为这里会涉及到一个seq , embedding_size 升维后再降维的操作 正弦位置编码表 因为在语言模型中每个词的顺序是非常重要的由于transformer 架构不像RNN这类时序模型一样模型本身知道输入序列的顺序所以为了保留输入序列的顺序信息所以引入了位置编码这个概念。 具体公式如下: 其中pos : ( 0 - seq_len ) , d :(embedding_size) , i : (0 - embedding_size ) 其中不同的embedding上函数的相位不同 其中至于为什么用正弦函数进行编码这个应该是一个实践出来的方程因为他是一个周期性的函数可以使得模型更好处理循环和重复出现的模式(比如语法结构) 4. 填充位置掩码 由于深度学习里都是以batch为单位的作为训练的所以需要把所有的句子都利用 pad 填充至等长这样就可以做batch的训练。除此之外为了将这里的 pad 的注意力设置成0 所以需要传入一个bool matrix 告诉网络哪些位置是填充了的并将其注意力权重设置成无穷小。 5. 编码器 这里是由多个编码器层叠加形成最终的深层次的编码器也就是前一层的输出是当前层的输入最后一层的输出作为整个编码器的输出具体结构如下: 而单层的编码器层是由自注意力 (正弦)位置编码 填充掩码 前馈网络构成 6. 后续位置掩码 序列生成任务中解码器的每个实践步都依赖于前面已经生成的部分序列在解码器中生成的自注意力由于每次生成的内容不能关注到后续位置的注意力换句话说就是为了防止解码器在生成当前位置实过度依赖未来的信息。 举个例子比如说我的目标中英机器翻译 编码器的输入是I love you - 解码器的输入应该是 sos 我 爱 你 eos所以对于编码器而言我由于我需要整个任务所以我必须看完所有内容所以我可以看完整个I love you 这一句话但是对于解码器而言我需要生成的目标是 sos 我 爱 你 eos 所以编码器只有看完了整个I love you 的输入解码器才能输出第一个字我 而生成第二个字爱的时候解码器只能看见 sos 我 这两个输入的自注意力而不能看见爱和你否则就类似作弊了。所以后续位置掩码就应运而生类似一个三角矩阵。 解码器 解码器也是由N层解码器层深度叠加实现的其中与编码器层结构类似但是添加了几个特别的点是编解码多头注意力 这里比较好理解就是因为在解码器得到自己的自注意力后需要与编码器的输出做注意力整合 除此之外还有一个后续位置掩码。 代码实现 Transformer搭建 缩放点积注意力 # 定义缩放点积注意力类 class ScaledDotProductAttention(nn.Module):def __init__(self):super(ScaledDotProductAttention, self).__init__() def forward(self, Q, K, V, attn_mask): Q 是当前要处理的上下文的信息, - X1K 不同位置的输入与查询的相关性 - X2V 是来自输入序列的一组表示 - X2# 计算注意力分数原始权重, score (Q * K / 缩放因子)scores torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k) #(batch , seq_q , seq_k)# 使用注意力掩码将attn_mask中值为1的位置的权重替换为极小值scores.masked_fill_(attn_mask, -1e9) # 对注意力分数进行softmaxweights nn.Softmax(dim-1)(scores)# 计算上下文向量也就是注意力的输出, 是上下文信息的紧凑表示context torch.matmul(weights, V) # (batch , seq_q , embedding)return context, weights # 返回上下文向量和注意力分数多头注意力类 class MultiHeadAttention(nn.Module):def __init__(self):super(MultiHeadAttention, self).__init__()self.W_Q nn.Linear(d_embedding, d_k * n_heads) # Q的线性变换层self.W_K nn.Linear(d_embedding, d_k * n_heads) # K的线性变换层self.W_V nn.Linear(d_embedding, d_v * n_heads) # V的线性变换层self.linear nn.Linear(n_heads * d_v, d_embedding)self.layer_norm nn.LayerNorm(d_embedding)def forward(self, Q, K, V, attn_mask): #-------------------------维度信息-------------------------------- # Q K V [batch_size, len_q/k/v, embedding_dim] #-------------------------维度信息-------------------------------- residual, batch_size Q, Q.size(0) # 保留残差连接# 将输入进行线性变换和重塑以便后续处理 下面的-1 代表的是qkv各自的seq_lenq_s self.W_Q(Q).view(batch_size, -1, n_heads, d_k).transpose(1,2) k_s self.W_K(K).view(batch_size, -1, n_heads, d_k).transpose(1,2)v_s self.W_V(V).view(batch_size, -1, n_heads, d_v).transpose(1,2)#-------------------------维度信息-------------------------------- # q_s k_s v_s: [batch_size, n_heads, len_q/k/v, d_qk/v]#-------------------------维度信息-------------------------------- # 将注意力掩码复制到多头 attn_mask: [batch_size, n_heads, len_q, len_k]attn_mask attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1)#-------------------------维度信息-------------------------------- # attn_mask [batch_size, n_heads, len_q, len_k]#-------------------------维度信息-------------------------------- # 使用缩放点积注意力计算上下文和注意力权重# context: [batch_size, n_heads, len_q, dim_v]; weights: [batch_size, n_heads, len_q, len_k]context, weights ScaledDotProductAttention()(q_s, k_s, v_s, attn_mask)#-------------------------维度信息-------------------------------- # context [batch_size, n_heads, len_q, dim_v]# weights [batch_size, n_heads, len_q, len_k]#-------------------------维度信息-------------------------------- # 重塑上下文向量并进行线性变换[batch_size, len_q, n_heads * dim_v]context context.transpose(1, 2).contiguous().view(batch_size, -1, n_heads * d_v) #-------------------------维度信息-------------------------------- # context [batch_size, len_q, n_heads * dim_v]#-------------------------维度信息-------------------------------- output self.linear(context) # [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- # output [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- # 与输入(Q)进行残差链接并进行层归一化后输出[batch_size, len_q, embedding_dim]output self.layer_norm(output residual)#-------------------------维度信息-------------------------------- # output [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- return output, weights # 返回层归一化的输出和注意力权重逐位置前向传播网络 # 定义逐位置前向传播网络类 class PoswiseFeedForwardNet(nn.Module):def __init__(self):super(PoswiseFeedForwardNet, self).__init__()# 定义一维卷积层1用于将输入映射到更高维度self.conv1 nn.Conv1d(in_channelsd_embedding, out_channels2048, kernel_size1)# 定义一维卷积层2用于将输入映射回原始维度self.conv2 nn.Conv1d(in_channels2048, out_channelsd_embedding, kernel_size1)# 定义层归一化self.layer_norm nn.LayerNorm(d_embedding)def forward(self, inputs): # inputs: [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- # inputs [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- residual inputs # 保留残差连接 [batch_size, len_q, embedding_dim]# 在卷积层1后使用ReLU激活函数 [batch_size, embedding_dim, len_q]-[batch_size, 2048, len_q]output nn.ReLU()(self.conv1(inputs.transpose(1, 2))) #-------------------------维度信息-------------------------------- # output [batch_size, 2048, len_q]#-------------------------维度信息--------------------------------# 使用卷积层2进行降维 [batch_size, 2048, len_q]-[batch_size, embedding_dim, len_q]output self.conv2(output).transpose(1, 2) # [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- # output [batch_size, len_q, embedding_dim]#-------------------------维度信息--------------------------------# 与输入进行残差链接并进行层归一化[batch_size, len_q, embedding_dim]output self.layer_norm(output residual) # [batch_size, len_q, embedding_dim]#-------------------------维度信息-------------------------------- # output [batch_size, len_q, embedding_dim]#-------------------------维度信息--------------------------------return output # 返回加入残差连接后层归一化的结果正弦位置编码表 # 生成正弦位置编码表的函数用于在Transformer中引入位置信息 def get_sin_enc_table(n_position, embedding_dim):#-------------------------维度信息--------------------------------# n_position: 输入序列的最大长度# embedding_dim: 词嵌入向量的维度#----------------------------------------------------------------- # 根据位置和维度信息初始化正弦位置编码表sinusoid_table np.zeros((n_position, embedding_dim)) # 遍历所有位置和维度计算角度值for pos_i in range(n_position):for hid_j in range(embedding_dim):angle pos_i / np.power(10000, 2 * (hid_j // 2) / embedding_dim)sinusoid_table[pos_i, hid_j] angle # 计算正弦和余弦值sinusoid_table[:, 0::2] np.sin(sinusoid_table[:, 0::2]) # dim 2i 偶数维sinusoid_table[:, 1::2] np.cos(sinusoid_table[:, 1::2]) # dim 2i1 奇数维 #-------------------------维度信息--------------------------------# sinusoid_table 的维度是 [n_position, embedding_dim]#----------------------------------------------------------------- return torch.FloatTensor(sinusoid_table) # 返回正弦位置编码表填充位置注意力掩码 # 生成填充注意力掩码的函数用于在多头自注意力计算中忽略填充部分 def get_attn_pad_mask(seq_q, seq_k):#-------------------------维度信息--------------------------------# seq_q 的维度是 [batch_size, len_q]# seq_k 的维度是 [batch_size, len_k]#-----------------------------------------------------------------batch_size, len_q seq_q.size()batch_size, len_k seq_k.size()# 生成布尔类型张量[batch_size1len_k(len_q)]pad_attn_mask seq_k.data.eq(0).unsqueeze(1) #PAD Token的编码值为0 # 变形为何注意力分数相同形状的张量 [batch_sizelen_qlen_k]pad_attn_mask pad_attn_mask.expand(batch_size, len_q, len_k)#-------------------------维度信息--------------------------------# pad_attn_mask 的维度是 [batch_sizelen_qlen_k]#-----------------------------------------------------------------return pad_attn_mask # [batch_sizelen_qlen_k]编码器(层) # 定义编码器层类 class EncoderLayer(nn.Module):def __init__(self):super(EncoderLayer, self).__init__() self.enc_self_attn MultiHeadAttention() #多头自注意力层 self.pos_ffn PoswiseFeedForwardNet() # 位置前馈神经网络层def forward(self, enc_inputs, enc_self_attn_mask):#-------------------------维度信息--------------------------------# enc_inputs 的维度是 [batch_size, seq_len, embedding_dim]# enc_self_attn_mask 的维度是 [batch_size, seq_len, seq_len]#-----------------------------------------------------------------# 将相同的QKV输入多头自注意力层enc_outputs, attn_weights self.enc_self_attn(enc_inputs, enc_inputs,enc_inputs, enc_self_attn_mask)# 将多头自注意力outputs输入位置前馈神经网络层enc_outputs self.pos_ffn(enc_outputs)#-------------------------维度信息--------------------------------# enc_outputs 的维度是 [batch_size, seq_len, embedding_dim] 维度与 enc_inputs 相同# attn_weights 的维度是 [batch_size, n_heads, seq_len, seq_len] 在注意力掩码维度上增加了头数#-----------------------------------------------------------------return enc_outputs, attn_weights # 返回编码器输出和每层编码器注意力权重# 定义编码器类 n_layers 6 # 设置Encoder/Decoder的层数 class Encoder(nn.Module):def __init__(self, corpus):super(Encoder, self).__init__() self.src_emb nn.Embedding(corpus.src_vocab, d_embedding) # 词嵌入层self.pos_emb nn.Embedding.from_pretrained( \get_sin_enc_table(corpus.src_len1, d_embedding), freezeTrue) # 位置嵌入层self.layers nn.ModuleList(EncoderLayer() for _ in range(n_layers))# 编码器层数def forward(self, enc_inputs): #-------------------------维度信息--------------------------------# enc_inputs 的维度是 [batch_size, source_len]#-----------------------------------------------------------------# 创建一个从1到source_len的位置索引序列pos_indices torch.arange(1, enc_inputs.size(1) 1).unsqueeze(0).to(enc_inputs)#-------------------------维度信息--------------------------------# pos_indices 的维度是 [1, source_len]#----------------------------------------------------------------- # 对输入进行词嵌入和位置嵌入相加 [batch_size, source_lenembedding_dim]enc_outputs self.src_emb(enc_inputs) self.pos_emb(pos_indices)#-------------------------维度信息--------------------------------# enc_outputs 的维度是 [batch_size, seq_len, embedding_dim]#-----------------------------------------------------------------enc_self_attn_mask get_attn_pad_mask(enc_inputs, enc_inputs) # 生成自注意力掩码#-------------------------维度信息--------------------------------# enc_self_attn_mask 的维度是 [batch_size, len_q, len_k] #----------------------------------------------------------------- enc_self_attn_weights [] # 初始化 enc_self_attn_weights# 通过编码器层 [batch_size, seq_len, embedding_dim]for layer in self.layers: enc_outputs, enc_self_attn_weight layer(enc_outputs, enc_self_attn_mask)enc_self_attn_weights.append(enc_self_attn_weight)#-------------------------维度信息--------------------------------# enc_outputs 的维度是 [batch_size, seq_len, embedding_dim] 维度与 enc_inputs 相同# enc_self_attn_weights 是一个列表每个元素的维度是[batch_size, n_heads, seq_len, seq_len] #-----------------------------------------------------------------return enc_outputs, enc_self_attn_weights # 返回编码器输出和编码器注意力权重后续注意力掩码 # 生成后续注意力掩码的函数用于在多头自注意力计算中忽略未来信息 def get_attn_subsequent_mask(seq):#-------------------------维度信息--------------------------------# seq 的维度是 [batch_size, seq_len(Q)seq_len(K)]#-----------------------------------------------------------------attn_shape [seq.size(0), seq.size(1), seq.size(1)] # 获取输入序列的形状 #-------------------------维度信息--------------------------------# attn_shape是一个一维张量 [batch_size, seq_len(Q), seq_len(K)]#-----------------------------------------------------------------# 使用numpy创建一个上三角矩阵triu triangle uppersubsequent_mask np.triu(np.ones(attn_shape), k1)#-------------------------维度信息--------------------------------# subsequent_mask 的维度是 [batch_size, seq_len(Q), seq_len(K)]#-----------------------------------------------------------------# 将numpy数组转换为PyTorch张量并将数据类型设置为byte布尔值subsequent_mask torch.from_numpy(subsequent_mask).byte()#-------------------------维度信息--------------------------------# 返回的subsequent_mask 的维度是 [batch_size, seq_len(Q), seq_len(K)]#-----------------------------------------------------------------return subsequent_mask # 返回后续位置的注意力掩码解码器(层) # 定义解码器层类 class DecoderLayer(nn.Module):def __init__(self):super(DecoderLayer, self).__init__() self.dec_self_attn MultiHeadAttention() # 多头自注意力层 self.dec_enc_attn MultiHeadAttention() # 多头注意力层连接编码器和解码器 self.pos_ffn PoswiseFeedForwardNet() # 位置前馈神经网络层def forward(self, dec_inputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask):#-------------------------维度信息--------------------------------# dec_inputs 的维度是 [batch_size, target_len, embedding_dim] 右移一位# enc_outputs 的维度是 [batch_size, source_len, embedding_dim] 编码器的输出# dec_self_attn_mask 的维度是 [batch_size, target_len, target_len] 解码器位置掩码(正弦位置掩码 后续位置掩码)# dec_enc_attn_mask 的维度是 [batch_size, target_len, source_len] 编解码器掩码#----------------------------------------------------------------- # 将相同的QKV输入多头自注意力层 这里QKV都是dec_inputsdec_outputs, dec_self_attn self.dec_self_attn(dec_inputs, dec_inputs, dec_inputs, dec_self_attn_mask)#-------------------------维度信息--------------------------------# dec_outputs 的维度是 [batch_size, target_len, embedding_dim]# dec_self_attn 的维度是 [batch_size, n_heads, target_len, target_len]#----------------------------------------------------------------- # 将解码器输出和编码器输出输入多头注意力层 Q:dec_inputs KV是enc_outputdec_outputs, dec_enc_attn self.dec_enc_attn(dec_outputs, enc_outputs, enc_outputs, dec_enc_attn_mask) #-------------------------维度信息--------------------------------# dec_outputs 的维度是 [batch_size, target_len, embedding_dim]# dec_enc_attn 的维度是 [batch_size, n_heads, target_len, source_len]#----------------------------------------------------------------- # 输入位置前馈神经网络层dec_outputs self.pos_ffn(dec_outputs)#-------------------------维度信息--------------------------------# dec_outputs 的维度是 [batch_size, target_len, embedding_dim]# dec_self_attn 的维度是 [batch_size, n_heads, target_len, target_len]# dec_enc_attn 的维度是 [batch_size, n_heads, target_len, source_len] #-----------------------------------------------------------------# 返回解码器层输出每层的自注意力和解-编编码器注意力权重return dec_outputs, dec_self_attn, dec_enc_attn# 定义解码器类 n_layers 6 # 设置Decoder的层数 class Decoder(nn.Module):def __init__(self, corpus):super(Decoder, self).__init__()self.tgt_emb nn.Embedding(corpus.tgt_vocab, d_embedding) # 词嵌入层self.pos_emb nn.Embedding.from_pretrained(get_sin_enc_table(corpus.tgt_len1, d_embedding), freezeTrue) # 位置嵌入层 self.layers nn.ModuleList([DecoderLayer() for _ in range(n_layers)]) # 叠加多层def forward(self, dec_inputs, enc_inputs, enc_outputs): #-------------------------维度信息--------------------------------# dec_inputs 的维度是 [batch_size, target_len]# enc_inputs 的维度是 [batch_size, source_len]# enc_outputs 的维度是 [batch_size, source_len, embedding_dim]#----------------------------------------------------------------- # 创建一个从1到source_len的位置索引序列pos_indices torch.arange(1, dec_inputs.size(1) 1).unsqueeze(0).to(dec_inputs)#-------------------------维度信息--------------------------------# pos_indices 的维度是 [1, target_len]#----------------------------------------------------------------- # 对输入进行词嵌入和位置嵌入相加 , 作为解码器层首个输入向量dec_outputs self.tgt_emb(dec_inputs) self.pos_emb(pos_indices) #-------------------------维度信息--------------------------------# dec_outputs 的维度是 [batch_size, target_len, embedding_dim]#----------------------------------------------------------------- # 生成解码器自注意力掩码和解码器-编码器注意力掩码dec_self_attn_pad_mask get_attn_pad_mask(dec_inputs, dec_inputs) # 填充位掩码dec_self_attn_subsequent_mask get_attn_subsequent_mask(dec_inputs) # 后续位掩码dec_self_attn_mask torch.gt((dec_self_attn_pad_mask.to(device) \ dec_self_attn_subsequent_mask.to(device)), 0) # 只要是填充位置或者后续位置是1的话就返回dec_enc_attn_mask get_attn_pad_mask(dec_inputs, enc_inputs) # 解码器-编码器掩码#-------------------------维度信息-------------------------------- # dec_self_attn_pad_mask 的维度是 [batch_size, target_len, target_len]# dec_self_attn_subsequent_mask 的维度是 [batch_size, target_len, target_len]# dec_self_attn_mask 的维度是 [batch_size, target_len, target_len]# dec_enc_attn_mask 的维度是 [batch_size, target_len, source_len]#----------------------------------------------------------------- dec_self_attns, dec_enc_attns [], [] # 初始化 dec_self_attns, dec_enc_attns# 通过解码器层 [batch_size, seq_len, embedding_dim]for layer in self.layers:dec_outputs, dec_self_attn, dec_enc_attn layer(dec_outputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask)dec_self_attns.append(dec_self_attn)dec_enc_attns.append(dec_enc_attn)#-------------------------维度信息--------------------------------# dec_outputs 的维度是 [batch_size, target_len, embedding_dim]# dec_self_attns 是一个列表每个元素的维度是 [batch_size, n_heads, target_len, target_len]# dec_enc_attns 是一个列表每个元素的维度是 [batch_size, n_heads, target_len, source_len]#----------------------------------------------------------------- # 返回解码器输出解码器自注意力和解-编编码器注意力权重 return dec_outputs, dec_self_attns, dec_enc_attnsTransformer类 # 定义Transformer模型 class Transformer(nn.Module):def __init__(self, corpus):super(Transformer, self).__init__() self.encoder Encoder(corpus) # 初始化编码器实例 self.decoder Decoder(corpus) # 初始化解码器实例# 定义线性投影层将解码器输出转换为目标词汇表大小的概率分布self.projection nn.Linear(d_embedding, corpus.tgt_vocab, biasFalse)def forward(self, enc_inputs, dec_inputs):#-------------------------维度信息--------------------------------# enc_inputs 的维度是 [batch_size, source_seq_len]# dec_inputs 的维度是 [batch_size, target_seq_len]#----------------------------------------------------------------- # 将输入传递给编码器并获取编码器输出和自注意力权重 enc_outputs, enc_self_attns self.encoder(enc_inputs)#-------------------------维度信息--------------------------------# enc_outputs 的维度是 [batch_size, source_len, embedding_dim]# enc_self_attns 是一个列表每个元素的维度是 [batch_size, n_heads, src_seq_len, src_seq_len] #----------------------------------------------------------------- # 将编码器输出、解码器输入和编码器输入传递给解码器# 获取解码器输出、解码器自注意力权重和编码器-解码器注意力权重 dec_outputs, dec_self_attns, dec_enc_attns self.decoder(dec_inputs, enc_inputs, enc_outputs)#-------------------------维度信息--------------------------------# dec_outputs 的维度是 [batch_size, target_len, embedding_dim]# dec_self_attns 是一个列表每个元素的维度是 [batch_size, n_heads, tgt_seq_len, src_seq_len]# dec_enc_attns 是一个列表每个元素的维度是 [batch_size, n_heads, tgt_seq_len, src_seq_len] #----------------------------------------------------------------- # 将解码器输出传递给投影层生成目标词汇表大小的概率分布dec_logits self.projection(dec_outputs) #-------------------------维度信息--------------------------------# dec_logits 的维度是 [batch_size, tgt_seq_len, tgt_vocab_size]#-----------------------------------------------------------------# 返回逻辑值(原始预测结果),编码器自注意力权重解码器自注意力权重解-编码器注意力权重return dec_logits, enc_self_attns, dec_self_attns, dec_enc_attns数据集的读取 由于pytorch中的dataloader是按照batch读取数据其中范式代码如下其中√表示的是比较常需要设置的参数: class torch.utils.data.DataLoader(dataset, # 继承torch.utils.data.Dataset后面会细讲 √ batch_size 1, # batch_size √ shuffle False, # 是否每次迭代都需要打乱数据集 √ collate_fn function default_collate, # 用于自定义样本处理的函数后面会细讲 √ sampler None, # 自定义采样规则batch_sampler None, # num_workers 0, # 使用多少个子进程来导入数据默认是0意思是用主进程导入数据这个数字必须要大于0 pin_memory False, # 内存寄存默认为False。在数据返回前是否将数据复制到CUDA内存中。drop_last False, # 丢弃最后数据默认为False。设置了 batch_size 的数目后最后一批数据未必是设置的数目即batch_len / batch_size 不是整除的情况。这时你是否需要丢弃这批数据。timeout 0, # 超时默认为0。是用来设置数据读取的超时时间的但超过这个时间还没读取到数据的话就会报错。 所以数值必须大于等于0。worker_init_fnNone # 子进程导入模式默认为Noun。在数据导入前和步长结束后根据工作子进程的ID逐个按顺序导入数据)上面可以看到dataset是自定义数据集的类其继承于torch.utils.data.Dataset主要用于读取单个数据其必须要定义的三个函数__init__ , getitem__ , len__).例子如下: class TranslationDataset(Dataset):def __init__(self, sentences, word2idx_cn, word2idx_en): # 设置参数self.sentences sentencesself.word2idx_cn word2idx_cnself.word2idx_en word2idx_endef __len__(self): # 返回数据的长度return len(self.sentences)def __getitem__(self, index): # 输入id , 返回单个数据的 feature 以及 labelsentence_cn [self.word2idx_cn[word] for word in self.sentences[index][0].split()]sentence_en [self.word2idx_en[word] for word in self.sentences[index][1].split()]sentence_en_in sentence_en[:-1] # remove eos , decorder inputsentence_en_out sentence_en[1:] # remove sos , decorder outputreturn torch.tensor(sentence_cn), torch.tensor(sentence_en_in), torch.tensor(sentence_en_out)可以看到如果初始化的dataset的每个单独的数据的长度并不一致 其次是collate_fn, 我们都知道为了使得dataloader 按照batch读取数据时需要取出同等大小的batch 的数据所以这里要求所有特征向量需要是等大小的但是我们都知道nlp任务里大部分文本数据都不可能保证对齐所以我们需要补pad这里就需要利用这个colldate_fn函数/对象了。 下其中collate_fn 传入的参数是batch的数据 也就是batch of dataset[id] 针对于上面的TranslationDataset的形状就是[batch , 3] , def collate_fn(batch):batch.sort(keylambda x: len(x[0]), reverseTrue)sentence_cn, sentence_en_in, sentence_en_out zip(*batch)sentence_cn nn.utils.rnn.pad_sequence(sentence_cn, padding_valuecorpus_loader.word2idx_cn[pad],batch_firstTrue)sentence_en_in nn.utils.rnn.pad_sequence(sentence_en_in, padding_valuecorpus_loader.word2idx_en[pad],batch_firstTrue)sentence_en_out nn.utils.rnn.pad_sequence(sentence_en_out, padding_valuecorpus_loader.word2idx_en[pad],batch_firstTrue)return sentence_cn, sentence_en_in, sentence_en_out其次是利用了nn.utils.rnn.pad_sequence 进行padding 其中有三个参数 整个函数最后返回[batch , M] , M是batch中最大的长度: target : list / 矩阵 shape [batch , N ] N 可以长度不一batch_first : 默认把batch放在第一维度padding_value : 填充的值也就是padding的index targets pad_sequence(targets , batch_firstTrue , padding_valueself.pad_idx) 其次如果需要对collate_fn输入参数一般有两种方法 使用lambda函数 info args.info # info是已经定义过的 loader Dataloader(collate_fnlambda x: collate_fn(x, info))创建可以调用的类 class collater():def __init__(self, *params):self. params paramsdef __call__(self, data):在这里重写collate_fn函数loader Dataloader(collate_fn collater(*params))结果 最后利用nltk的API测试了下整个网络在整个训练集上的BLUE分数这里其实是要分出一个验证集出来是比较好的但是实践比较有限就不做了可以看到整个BLUE的分数还不错有0.68左右。
文章转载自:
http://www.morning.gxklx.cn.gov.cn.gxklx.cn
http://www.morning.jtjmz.cn.gov.cn.jtjmz.cn
http://www.morning.hwpcm.cn.gov.cn.hwpcm.cn
http://www.morning.gzgwn.cn.gov.cn.gzgwn.cn
http://www.morning.nfcxq.cn.gov.cn.nfcxq.cn
http://www.morning.jhyfb.cn.gov.cn.jhyfb.cn
http://www.morning.kjmws.cn.gov.cn.kjmws.cn
http://www.morning.hgscb.cn.gov.cn.hgscb.cn
http://www.morning.dspqc.cn.gov.cn.dspqc.cn
http://www.morning.tfkqc.cn.gov.cn.tfkqc.cn
http://www.morning.8yitong.com.gov.cn.8yitong.com
http://www.morning.wmyqw.com.gov.cn.wmyqw.com
http://www.morning.mlckd.cn.gov.cn.mlckd.cn
http://www.morning.ttryd.cn.gov.cn.ttryd.cn
http://www.morning.bhdtx.cn.gov.cn.bhdtx.cn
http://www.morning.cybch.cn.gov.cn.cybch.cn
http://www.morning.glkhx.cn.gov.cn.glkhx.cn
http://www.morning.rgxf.cn.gov.cn.rgxf.cn
http://www.morning.sgnxl.cn.gov.cn.sgnxl.cn
http://www.morning.fkmyq.cn.gov.cn.fkmyq.cn
http://www.morning.sxmbk.cn.gov.cn.sxmbk.cn
http://www.morning.clfct.cn.gov.cn.clfct.cn
http://www.morning.lfcfn.cn.gov.cn.lfcfn.cn
http://www.morning.bwqr.cn.gov.cn.bwqr.cn
http://www.morning.xqgtd.cn.gov.cn.xqgtd.cn
http://www.morning.rmtmk.cn.gov.cn.rmtmk.cn
http://www.morning.kpbgp.cn.gov.cn.kpbgp.cn
http://www.morning.wdhhz.cn.gov.cn.wdhhz.cn
http://www.morning.spxk.cn.gov.cn.spxk.cn
http://www.morning.bpmnj.cn.gov.cn.bpmnj.cn
http://www.morning.qgjxy.cn.gov.cn.qgjxy.cn
http://www.morning.xwnnp.cn.gov.cn.xwnnp.cn
http://www.morning.zrpbf.cn.gov.cn.zrpbf.cn
http://www.morning.shuanga.com.cn.gov.cn.shuanga.com.cn
http://www.morning.jtwck.cn.gov.cn.jtwck.cn
http://www.morning.ssxlt.cn.gov.cn.ssxlt.cn
http://www.morning.tmnyj.cn.gov.cn.tmnyj.cn
http://www.morning.ywgrr.cn.gov.cn.ywgrr.cn
http://www.morning.qjlnh.cn.gov.cn.qjlnh.cn
http://www.morning.nnmnz.cn.gov.cn.nnmnz.cn
http://www.morning.lsnhs.cn.gov.cn.lsnhs.cn
http://www.morning.lsfzq.cn.gov.cn.lsfzq.cn
http://www.morning.wrlff.cn.gov.cn.wrlff.cn
http://www.morning.clzly.cn.gov.cn.clzly.cn
http://www.morning.qfths.cn.gov.cn.qfths.cn
http://www.morning.nkqnn.cn.gov.cn.nkqnn.cn
http://www.morning.smsjx.cn.gov.cn.smsjx.cn
http://www.morning.jfqpc.cn.gov.cn.jfqpc.cn
http://www.morning.sfzwm.cn.gov.cn.sfzwm.cn
http://www.morning.gbrdx.cn.gov.cn.gbrdx.cn
http://www.morning.zlces.com.gov.cn.zlces.com
http://www.morning.zlrrj.cn.gov.cn.zlrrj.cn
http://www.morning.zqwqy.cn.gov.cn.zqwqy.cn
http://www.morning.fbjqq.cn.gov.cn.fbjqq.cn
http://www.morning.gjcdr.cn.gov.cn.gjcdr.cn
http://www.morning.gnfkl.cn.gov.cn.gnfkl.cn
http://www.morning.xbyyd.cn.gov.cn.xbyyd.cn
http://www.morning.nsrtvu.com.gov.cn.nsrtvu.com
http://www.morning.hkshy.cn.gov.cn.hkshy.cn
http://www.morning.pwsnr.cn.gov.cn.pwsnr.cn
http://www.morning.lwtfr.cn.gov.cn.lwtfr.cn
http://www.morning.mqmxg.cn.gov.cn.mqmxg.cn
http://www.morning.hprmg.cn.gov.cn.hprmg.cn
http://www.morning.chehb.com.gov.cn.chehb.com
http://www.morning.rxkq.cn.gov.cn.rxkq.cn
http://www.morning.shyqcgw.cn.gov.cn.shyqcgw.cn
http://www.morning.lptjt.cn.gov.cn.lptjt.cn
http://www.morning.ryzgp.cn.gov.cn.ryzgp.cn
http://www.morning.lszjq.cn.gov.cn.lszjq.cn
http://www.morning.cszbj.cn.gov.cn.cszbj.cn
http://www.morning.nbwyk.cn.gov.cn.nbwyk.cn
http://www.morning.ljzss.cn.gov.cn.ljzss.cn
http://www.morning.nrlsg.cn.gov.cn.nrlsg.cn
http://www.morning.ldhbs.cn.gov.cn.ldhbs.cn
http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn
http://www.morning.cflxx.cn.gov.cn.cflxx.cn
http://www.morning.bgxgq.cn.gov.cn.bgxgq.cn
http://www.morning.nspzy.cn.gov.cn.nspzy.cn
http://www.morning.fkcjs.cn.gov.cn.fkcjs.cn
http://www.morning.klpwl.cn.gov.cn.klpwl.cn
http://www.tj-hxxt.cn/news/246418.html

相关文章:

  • 网站维护主要是做哪些推广营销软件
  • 精品课程网站建设建议wordpress缓存问题
  • asp.net开发移动网站模板下载微信运营
  • 长沙微网站义乌购网站做代销怎么样
  • 效果图网站接单做封面下载网站
  • 宁波网站推广软件服务网页界面制作
  • html5 国外网站手机开发者模式怎么打开
  • 如何对网站进行推广深圳 响应式网站建设
  • 商丘做网站推广的公司菏泽网站设计培训
  • 短视频素材下载网站网站建设实训总结范文
  • 南京医院网站建设wordpress收费版怎么激活
  • 网站上传图片教程模板搭建网站
  • 大麦网网站建设的功能定位网站如何做sem
  • 菏泽网站建设菏泽众皓wordpress文章总阅读量
  • 可以用来注册网站域名的入口是汽车美容网站模板
  • 怀化北京网站建设名城苏州网站
  • 秋实网站建设商品管理系统
  • dede手机wap网站模板wordpress评论后可见
  • 咸阳微网站建设外贸网站平台
  • 网站制作案例市场编程前端和后端是什么
  • 海南省建设工程质量安全检测协会网站德阳中恒网站建设
  • 湘潭市网站建设windows优化软件排行
  • 贝贝网网站开发背景想开发软件多少钱
  • 吴江区建设银行招聘网站曼朗策划响应式网站建设
  • 做任务领礼品的网站1网站免费建站
  • 张家港苏州网站建设温州网站建设方案外包
  • 个人做网站需要什么条件潍坊云建站模板
  • 高端的电影网站设计装修的软件
  • 如何制作自己的网站教程六安网络科技股份有限公司
  • 创建网站选哪家好wordpress 路径中文乱码