深圳龙岗高端网站建设网站程序开发外包

pingmian/2025/10/7 14:55:24/文章来源:
深圳龙岗高端网站建设,网站程序开发外包,西安做网站服务,wordpress免费中文模板Transformer概述 相比LSTM和GRU模型#xff0c;Transformer模型有两个显著的优势#xff1a; Transformer能够利用分布式GPU进行并行训练#xff0c;提升模型训练效率。 在分析预测更长的文本时#xff0c;捕捉间隔较长的语义关联效果更好。 Transformer模型的作用 基于seq… Transformer概述 相比LSTM和GRU模型Transformer模型有两个显著的优势 Transformer能够利用分布式GPU进行并行训练提升模型训练效率。 在分析预测更长的文本时捕捉间隔较长的语义关联效果更好。 Transformer模型的作用 基于seq2seq架构的transformer模型可以完成NLP领域研究的典型任务如机器翻译文本生成等。同时又可以构建预训练语言模型用于不同任务的迁移学习。 假设使用Transformer模型架构处理从一种语言文本到另一种语言文本的翻译工作因此很多命名方式遵循NLP中的规则。比如Embeddding层将称作文本嵌入层Embedding层产生的张量称为词嵌入张量它的最后一维将称作词向量等。 Transformer总体架构图 输入部分实现 输入部分包含 源文本嵌入层及其位置编码器目标文本嵌入层及其位置编码器。 文本嵌入层的作用 无论是源文本嵌入还是目标文本嵌入都是为了将文本中词汇的数字表示转变为向量表示希望在这样的高维空间捕捉词汇间的关系。 位置编码器的作用 在Transformer的编码器结构中并没有针对词汇位置信息的处理因此需要在Embedding层后加入位置编码器将词汇位置不同可能会产生不同语义的信息加入到词嵌入张量中以弥补位置信息的缺失。 词汇向量中特征的分布曲线 保证同一词汇随着所在位置不同它对应位置嵌入向量会发生变化。正弦波和余弦波的值域范围都是1到-1这很好的控制了嵌入数值的大小有助于梯度的快速计算。 编码器部分实现 编码器介绍 由N个编码器层堆叠而成每个编码器层由两个子层连接结构组成第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接第二个子层连接结构包括一个前馈全连接子层和规范化层以及一个残差连接 掩码张量 掩代表遮掩码就是张量中的数值它的尺寸不定里面一般只有1和0的元素代表位置被遮掩或者不被遮掩至于是0位置被遮掩还是1位置被遮掩可以自定义因此它的作用就是让另外一个张量中的一些数值被遮掩也可以说被替换它的表现形式是一个张量。 掩码张量的作用 在transformer中掩码张量的主要作用在应用attention时有一些生成的attention张量中的值计算有可能已知量未来信息而得到的未来信息被看到是因为训练时会把整个输出结果都一次性进行Embedding但是理论上解码器的的输出却不是一次就能产生最终结果的而是一次次通过上一次结果综合得出的因此未来的信息可能被提前利用。所以会进行遮掩。 注意力机制 注意力的计算规则 多头注意力机制 所谓的多个头就是指多组线性变换层其实并不是只有使用了一组线性变化层即三个变换张量对QKV分别进行线性变换这些变换不会改变原有张量的尺寸因此每个变换矩阵都是方阵得到输出结果后多头的作用才开始显现每个头开始从词义层面分割输出的张量也就是每个头都想获得一组QKV进行注意力机制的计算但是句子中的每个词的表示只获得一部分也就是只分割了最后一维的词嵌入向量。这就是所谓的多头将每个头的获得的输入送到注意力机制中, 就形成多头注意力机制。这种结构设计能让每个注意力机制去优化每个词汇的不同特征部分从而均衡同一种注意力机制可能产生的偏差让词义拥有来自更多元的表达实验表明可以从而提升模型效果。 前馈全连接层  在Transformer中前馈全连接层就是具有两层线性层的全连接网络。前馈全连接层的作用考虑注意力机制可能对复杂过程的拟合程度不够通过增加两层网络来增强模型的能力。 规范化层  它是所有深层网络模型都需要的标准网络层因为随着网络层数的增加通过多层的计算后参数可能开始出现过大或过小的情况这样可能会导致学习过程出现异常模型可能收敛非常的慢。因此都会在一定层数后接规范化层进行数值的规范化使其特征数值在合理范围内。 子层连接结构 输入到每个子层以及规范化层的过程中还使用了残差链接跳跃连接因此把这一部分结构整体叫做子层连接代表子层及其链接结构在每个编码器层中都有两个子层这两个子层加上周围的链接结构就形成了两个子层连接结构。 编码器层 作为编码器的组成单元每个编码器层完成一次对输入的特征提取过程即编码过程。编码器层的构成图 编码器  编码器用于对输入进行指定的特征提取过程也称为编码由N个编码器层堆叠而成。 编码器的结构图 解码器部分实现 解码器介绍 由N个解码器层堆叠而成每个解码器层由三个子层连接结构组成第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接第二个子层连接结构包括一个多头注意力子层和规范化层以及一个残差连接第三个子层连接结构包括一个前馈全连接子层和规范化层以及一个残差连接解码器层中的各个部分如多头注意力机制规范化层前馈全连接网络子层连接结构都与编码器中的实现相同。因此这里可以直接拿来构建解码器层。 解码器层 作为解码器的组成单元每个解码器层根据给定的输入向目标方向进行特征提取操作即解码过程。 解码器 根据编码器的结果以及上一次预测的结果对下一次可能出现的值进行特征表示。 输出部分实现 输出部分介绍 输出部分包含线性层、softmax层。 线性层的作用 通过对上一步的线性变化得到指定维度的输出也就是转换维度的作用。 softmax层的作用 使最后一维的向量中的数字缩放到0-1的概率值域内并满足他们的和为1。 模型构建 Transformer总体架构图 Transformer模型架构大范围内包括两部分分别是encoder(编码器)和decoder(解码器)编码器和解码器的内部实现都使用了注意力机制实现。这里完成的是德文到英文的翻译: Willkommen in peking → welcome to BeiJing。编码器首先处理中文输入Willkommen in peking通过Transformer内部的注意力机制提取信息之后的输出张量就是一个中间语义张量c接着解码器将使用这个中间语义张量c以及每一个时间步的目标语言的语义张量逐个生成对应的翻译语言。 案例Transformer机器翻译模型 数据集:使用的是torchtext中自带的数据集Multi30k直接可以使用内置的API函数即可下载 # 默认下载的路径为: /root/.torchtext/cache/Multi30k └── Multi30k├── mmt16_task1_test.tar.gz├── test.de├── test.en├── train.de├── train.en├── training.tar.gz├── val.de├── val.en└── validation.tar.gz1 导入必备的工具包 import torch import torch.nn as nn import mathfrom torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator from torchtext.datasets import Multi30k from typing import Iterable, List from torch import Tensor from torch.nn import Transformer from torch.nn.utils.rnn import pad_sequence from torch.utils.data import DataLoader from timeit import default_timer as timerDEVICE torch.device(cuda if torch.cuda.is_available() else cpu)2 导入Multi30k数据集并做基本处理 2.1 加载对应的tokenizer # 源语言是德语 SRC_LANGUAGE de # 目标语言是英语 TGT_LANGUAGE en# 定义token的字典, 定义vocab字典 token_transform {} vocab_transform {}# 创建源语言和目标语言的kokenizer, 确保依赖关系已经安装 # pip install -U spacy # python -m spacy download en_core_web_sm # python -m spacy download de_core_news_sm # get_tokenizer是分词函数, 如果没有特殊的则按照英语的空格分割, 如果有这按照对应的分词库返回. 比如spacy, 返回对应的分词库 token_transform[SRC_LANGUAGE] get_tokenizer(spacy, languagede_core_news_sm) token_transform[TGT_LANGUAGE] get_tokenizer(spacy, languageen_core_web_sm)2.2 构建生成分词的迭代器 def yield_tokens(data_iter: Iterable, language: str) - List[str]:# data_iter: 对象的迭代对象 Multi30k对象# language: 对应的翻译语言 {de: 0, en: 1}language_index {SRC_LANGUAGE: 0, TGT_LANGUAGE: 1}# 返回对应的数据迭代器对象for data_sample in data_iter:# data_sample:(德文, 英文)# data_sample:(Zwei junge weiße Männer sind im Freien in der Nähe vieler Büsche.\n, Two young, White males are outside near many bushes.\n)# token_transform[de]()[Zwei, junge, weiße, Männer, sind, im, Freien, in, der, Nähe, vieler, Büsche, ., \n]# or token_transform[en]分别进行构造对应的字典yield token_transform[language](data_sample[language_index[language]])2.3 定义特殊字符并下载数据设置默认索引 # 定义特殊字符及其对应的索引值 UNK_IDX, PAD_IDX, BOS_IDX, EOS_IDX 0, 1, 2, 3 # 确保标记按其索引的顺序正确插入到词汇表中 special_symbols [unk, pad, bos, eos]for ln in [SRC_LANGUAGE, TGT_LANGUAGE]:# 训练数据集的迭代器,# 数据集是用英文描述图像的英文语句, 然后人工将其翻译为德文的语句,有两个文件, 一个是train.de 一个是train.en文件,# 然后将其构建为(德文, 英文)的形式train_iter Multi30k(splittrain, language_pair(SRC_LANGUAGE, TGT_LANGUAGE))# 创建torchtext的vocab对象, 即词汇表vocab_transform[ln] build_vocab_from_iterator(yield_tokens(train_iter, ln), # 用于构建 Vocab 的迭代器。必须产生令牌列表或迭代器min_freq1,#在词汇表中包含一个标记所需的最低频率specialsspecial_symbols, # 用于添加的特殊字符special_firstTrue) # 指示是在开头还是结尾插入符号# 将 UNK_IDX 设置为默认索引。未找到令牌时返回此索引 # 如果未设置则在 Vocabulary 中找不到查询的标记时抛出 RuntimeError for ln in [SRC_LANGUAGE, TGT_LANGUAGE]:vocab_transform[ln].set_default_index(UNK_IDX)3 构建Transformer模型 3.1 定义位置编码器类 class PositionalEncoding(nn.Module):def __init__(self,emb_size: int,dropout: float, maxlen: int 5000):emb_size: 词嵌入的维度大小dropout: 正则化的大小maxlen: 句子的最大长度super(PositionalEncoding, self).__init__()# 将1000的2i/d_model变型为e的指数形式den torch.exp(- torch.arange(0, emb_size, 2)* math.log(10000) / emb_size)# 效果等价与torch.arange(0, maxlen).unsqueeze(1)pos torch.arange(0, maxlen).reshape(maxlen, 1)# 构建一个(maxlen, emb_size)大小的全零矩阵pos_embedding torch.zeros((maxlen, emb_size))# 偶数列是正弦函数填充pos_embedding[:, 0::2] torch.sin(pos * den)# 奇数列是余弦函数填充pos_embedding[:, 1::2] torch.cos(pos * den)# 将其维度变成三维, 为了后期方便计算pos_embedding pos_embedding.unsqueeze(-2)# 添加dropout层, 防止过拟合self.dropout nn.Dropout(dropout)向模块添加持久缓冲区。这通常用于注册不应被视为模型参数的缓冲区。例如pos_embedding不是一个参数而是持久状态的一部分。缓冲区可以使用给定的名称作为属性访问。说明应该就是在内存中定义一个常量同时模型保存和加载的时候可以写入和读出self.register_buffer(pos_embedding, pos_embedding)def forward(self, token_embedding: Tensor):# 将token_embedding和位置编码相融合return self.dropout(token_embedding self.pos_embedding[:token_embedding.size(0), :])3.2 定义词嵌入层类 class TokenEmbedding(nn.Module):def __init__(self, vocab_size: int, emb_size):vocab_size:词表的大小emb_size:词嵌入的维度super(TokenEmbedding, self).__init__()# 调用nn中的预定义层Embedding, 获取一个词嵌入对象self.embeddingself.embedding nn.Embedding(vocab_size, emb_size)# 将emb_size传入类内, 变成类内的变量self.emb_size emb_sizedef forward(self, tokens: Tensor):# 让 embeddings vector 在增加 之后的 postion encoing 之前相对大一些的操作# 主要是为了让position encoding 相对的小这样会让原来的 embedding vector 中的信息在和 position encoding 的信息相加时不至于丢失掉# 让 embeddings vector 相对大一些return self.embedding(tokens.long()) * math.sqrt(self.emb_size)3.3 构建Seq2SeqTransformer模型 class Seq2SeqTransformer(nn.Module):def __init__(self,num_encoder_layers, num_decoder_layers,emb_size,nhead,src_vocab_size,tgt_vocab_size,dim_feedforward 512,dropout 0.1):num_encoder_layers: 编码器的层数num_decoder_layers: 解码器的层数emb_size: 词嵌入的维度nhead: 头数src_vocab_size: 源语言的词表大小tgt_vocab_size: 目标语言的词表大小dim_feedforward: 前馈全连接层的维度dropout: 正则化的大小# 继承nn.Module类, 一般继承习惯行的写法super(Seq2SeqTransformer, self).__init__()# 创建Transformer对象self.transformer Transformer(d_modelemb_size,nheadnhead,num_encoder_layersnum_encoder_layers,num_decoder_layersnum_decoder_layers,dim_feedforwarddim_feedforward,dropoutdropout)# 创建全连接线性层self.generator nn.Linear(emb_size, tgt_vocab_size)# 创建源语言的embedding层self.src_tok_emb TokenEmbedding(src_vocab_size, emb_size)# 创建目标语言的embedding层self.tgt_tok_emb TokenEmbedding(tgt_vocab_size, emb_size)# 创建位置编码器层对象self.positional_encoding PositionalEncoding(emb_size, dropoutdropout)def forward(self,src, trg, src_mask, tgt_mask, src_padding_mask, tgt_padding_mask, memory_key_padding_mask):src: 源语言trg: 目标语言src_mask: 源语言掩码tgt_mask: 目标语言掩码src_padding_mask: 源语言的padding_masktgt_padding_mask: 目标语言的padding_maskmemory_key_padding_mask: 中间语义张量的padding_mask# 获取源语言的embedding张量融合了位置编码src_emb self.positional_encoding(self.src_tok_emb(src))# 获取目标语言的embedding张量融合了位置编码tgt_emb self.positional_encoding(self.tgt_tok_emb(trg))# 经过Transformer进行编解码之后输出out值outs self.transformer(src_emb, tgt_emb, src_mask, tgt_mask, None, src_padding_mask, tgt_padding_mask, memory_key_padding_mask)# outs值经过输出层得到最后的输出分布值return self.generator(outs)# 定义Transformer的编码器def encode(self, src, src_mask):src:源语言src_mask:源语言掩码return self.transformer.encoder(self.positional_encoding(self.src_tok_emb(src)), src_mask)# 定义Transformer的解码器def decode(self, tgt, memory, tgt_mask):tgt:目标语言memory:中间语言张量输出tgt_mask: 目标语言的掩码return self.transformer.decoder(self.positional_encoding(self.tgt_tok_emb(tgt)), memory, tgt_mask)4 定义mask的函数, 创建对应的不同的mask 4.1 定义掩码 作用是防止模型在进行预测的过程中查看到未来的单词. 同时需要掩码来隐藏源语言和目标语言的padding tokens def generate_square_subsequent_mask(sz):# sz: 句子的长度# triu生成的是上三角, 经过transpose之后变成了下三角矩阵mask (torch.triu(torch.ones((sz, sz), deviceDEVICE)) 1).transpose(0, 1)# 将0的位置填充负无穷小, 将1的位置填充为0mask mask.float().masked_fill(mask 0, float(-inf)).masked_fill(mask 1, float(0.0))return maskdef create_mask(src, tgt):src: 源语言张量形状为: [seq_length , batch_size]tgt: 目标语言张量形状为: [seq_length , batch_size]# 获取源语言的句子长度src_seq_len src.shape[0]# 获取目标语言的句子长度tgt_seq_len tgt.shape[0]# 产生目标语言的掩码张量tgt_mask generate_square_subsequent_mask(tgt_seq_len)# 产生源语言的掩码张量src_mask torch.zeros((src_seq_len, src_seq_len),deviceDEVICE).type(torch.bool)# 构建源语言的padding_mask src_padding_mask [batch_size, seq_len]src_padding_mask (src PAD_IDX).transpose(0, 1)# 构建目标语言的padding_mask tgt_paddig_mask [batch_size, seq_len-1]tgt_padding_mask (tgt PAD_IDX).transpose(0, 1)return src_mask, tgt_mask, src_padding_mask, tgt_padding_mask5 定义批次数据处理的回调函数 5.1 将字符串转化为整数的tensor张量 # 将句子字符转化为对应的tensor张量 def sequential_transforms(*transforms):Transformers中会传入三个迭代器: 第一个是Tokenization的, 第二个是Numericalization, 第三个是Add BOS/EOS and create tensordef func(txt_input):# 循环三个迭代器, 第一个进行语句的分割, 第二个将对应的词语映射为对应的张量表示, 第三个是在整个句子的首尾部分添加起始和结束标志.for transform in transforms:txt_input transform(txt_input)return txt_inputreturn func5.2 在句子首尾添加起始和结束符号 # 辅助函数, 完成句子首尾BOS/EOS的添加过程 def tensor_transform(token_ids: List[int]):# 添加的是列表形式的数据, 将BOS和EOS添加到句子的首尾部分return torch.cat((torch.tensor([BOS_IDX]),torch.tensor(token_ids),torch.tensor([EOS_IDX])))text_transform {} # 循环添加源语言和目标语言 for ln in [SRC_LANGUAGE, TGT_LANGUAGE]:text_transform[ln] sequential_transforms(token_transform[ln], #Tokenizationvocab_transform[ln], #Numericalizationtensor_transform) # Add BOS/EOS and create tensor5.3 数据进行批次化处理 # 按照批次进行源语言和目标语言的组装 def collate_fn(batch):# 定义源语言和目标语言的批次列表src_batch, tgt_batch [], []# 循环批次样本for src_sample, tgt_sample in batch:# 添加源语言句子到列表中src_batch.append(text_transform[SRC_LANGUAGE](src_sample.rstrip(\n)))# 添加目标语言句子到列表中tgt_batch.append(text_transform[TGT_LANGUAGE](tgt_sample.rstrip(\n)))# 将源语言和目标语言进行截断补齐 PAD_IDX1# src_batch的形状为: [seq_length, batch] seq_length是最长的句子长度src_batch pad_sequence(src_batch, padding_valuePAD_IDX)# tgt_batch的形状为: [seq_length, batch] seq_length是最长的句子长度tgt_batch pad_sequence(tgt_batch, padding_valuePAD_IDX)return src_batch, tgt_batch6 构建训练函数和评估函数 6.1 实例化模型并定义损失函数和优化器 # 设置种子用于生成随机数以使得结果是确定的 torch.manual_seed(0)# 设置调用时候使用的参数 SRC_VOCAB_SIZE len(vocab_transform[SRC_LANGUAGE]) TGT_VOCAB_SIZE len(vocab_transform[TGT_LANGUAGE]) EMB_SIZE 512 NHEAD 8 FFN_HID_DIM 512 BATCH_SIZE 128 NUM_ENCODER_LAYERS 3 NUM_DECODER_LAYERS 3# 实例化Transformer对象 transformer Seq2SeqTransformer(NUM_ENCODER_LAYERS, NUM_DECODER_LAYERS, EMB_SIZE,NHEAD, SRC_VOCAB_SIZE, TGT_VOCAB_SIZE, FFN_HID_DIM) # 为了保证每层的输入和输出的方差相同, 防止梯度消失问题 for p in transformer.parameters():if p.dim() 1:# 此处使用的是xavier的均匀分布nn.init.xavier_uniform_(p) # 如果有GPU则将模型移动到GPU上 transformer transformer.to(DEVICE) # 定义损失函数 loss_fn torch.nn.CrossEntropyLoss(ignore_indexPAD_IDX) # 定义优化器 betas: 用于计算梯度及其平方的运行平均值的系数 eps:添加到分母以提高数值稳定性 optimizer torch.optim.Adam(transformer.parameters(), lr0.0001, betas(0.9, 0.98), eps1e-9)6.2 定义批次训练函数 def train_epoch(model, optimizer):# 开启训练模式model.train()# 定义其实的损失值为0losses 0# 获取训练数据集的迭代器, 语言对为(de, en)train_iter Multi30k(splittrain, language_pair(SRC_LANGUAGE, TGT_LANGUAGE))# 加载数据, 按照一个批次一个批次进行加载, 返回一个迭代器train_dataloader DataLoader(train_iter, batch_sizeBATCH_SIZE, collate_fncollate_fn)# 循环数据迭代器for src, tgt in train_dataloader:# 将源语言数据移动到对应的设备上去src src.to(DEVICE)# 将目标语言数据移动到对应设备上去tgt tgt.to(DEVICE)# 获取输入真实的张量 第一个单词到倒数第二个单词tgt_input tgt[:-1, :]# 调用mask函数, 生成对应的四个masksrc_mask, tgt_mask, src_padding_mask, tgt_padding_mask create_mask(src, tgt_input)# 调用模型进行训练, 得到最后的张量分布logits model(src, tgt_input, src_mask, tgt_mask,src_padding_mask, tgt_padding_mask, src_padding_mask)# 梯度清零optimizer.zero_grad()# 获取输出真实的标签数据 第二个单词到最后一个单词tgt_out tgt[1:, :]# 计算损失loss loss_fn(logits.reshape(-1, logits.shape[-1]), tgt_out.reshape(-1))# 反向传播loss.backward()# 梯度更新optimizer.step()# 损失值累加求和losses loss.item()# 返回平均损失值return losses / len(train_dataloader)6.3 定义批次评估函数 def evaluate(model):# 开启模型评估模式model.eval()# 定义起始损失值losses 0# 加载验证数据集, 语言对为(de, en)val_iter Multi30k(splitvalid, language_pair(SRC_LANGUAGE, TGT_LANGUAGE))# 返回验证集的数据加载器val_dataloader DataLoader(val_iter, batch_sizeBATCH_SIZE, collate_fncollate_fn)# 循环验证集for src, tgt in val_dataloader:# 源语言数据移动到对应的设备上src src.to(DEVICE)# 目标语言数据移动到对应的设备上tgt tgt.to(DEVICE)# 获取输入的真实的张量tgt_input tgt[:-1, :]# 调用mask函数, 产生对应的四个mask值src_mask, tgt_mask, src_padding_mask, tgt_padding_mask create_mask(src, tgt_input)# 调用模型, 得到对应的输出分布值logits model(src, tgt_input, src_mask, tgt_mask,src_padding_mask, tgt_padding_mask, src_padding_mask)# 获取输出的真实张量tgt_out tgt[1:, :]# 计算损失值loss loss_fn(logits.reshape(-1, logits.shape[-1]), tgt_out.reshape(-1))# 损失值累加, 求和losses loss.item()# 求得对应的平均损失return losses / len(val_dataloader)7 训练Transformer模型 7.1 利用循环训练Transformer模型 # 定义epoch的次数 NUM_EPOCHS 18# 循环整个数据集num_epochs次 for epoch in range(1, NUM_EPOCHS1):# 获取开始时间start_time timer()# 将整个训练数据集进行训练train_loss train_epoch(transformer, optimizer)# 获取结束时间end_time timer()# 将整个验证集进行评估val_loss evaluate(transformer)# 打印每个epoch的训练损失, 验证损失, 和训练时间.print((fEpoch: {epoch}, Train loss: {train_loss:.3f}, Val loss: {val_loss:.3f}, fEpoch time {(end_time - start_time):.3f}s))8 进行解码生成目标语言语句 8.1 使用贪心算法构建生成序列函数 def greedy_decode(model, src, src_mask, max_len, start_symbol):# 将对应的源语言数据移动的对应的设备上src src.to(DEVICE)# 将对应的源语言的mask移动到对应的设备上src_mask src_mask.to(DEVICE)# 将源语言使用模型的编码器, 得到中间语义张量 memory的形状为: [seq_len, batch_size, dim]memory model.encode(src, src_mask)# 构建一个起始的二维矩阵, 然后准备开始句子的解码过程. ys形状为[1, 1]二维的ys torch.ones(1, 1).fill_(start_symbol).type(torch.long).to(DEVICE)for i in range(max_len-1):# 将中间语义张量的数据一定到对应的设备上memory memory.to(DEVICE)# 生成目标语言的mask值tgt_mask (generate_square_subsequent_mask(ys.size(0)).type(torch.bool)).to(DEVICE)# 调用模型的解码器进行解码 out形状为:[seq_len, 1, 512] [seq_len, batch_size, emb_size]out model.decode(ys, memory, tgt_mask)# 输出张量进行形状的转换out out.transpose(0, 1)# 经过最后输出层, 获取最后的输出概率分布 out[:, -1]形状为: [1, 512] -- [seq_len, emb_size]# prob的形状为: [1, tgt_vocab_size]prob model.generator(out[:, -1])# 在1维度上, 获取概率最大的那个就是最后预测的那个值 max返回两个值, 第一个是返回的最大值的概率, 第二个是返回最大概率的下标值._, next_word torch.max(prob, dim1)# 获取对应的那个下标值next_word next_word.item()# 拼接上一步和这一步产生的单词, 作为下一步使用的ys fill_()表示用括号中的数字去填充整个矩阵ys torch.cat([ys, torch.ones(1, 1).type_as(src.data).fill_(next_word)], dim0)if next_word EOS_IDX:breakreturn ys8.2 定义最终的翻译转化函数 def translate(model: torch.nn.Module, src_sentence: str):model: 输入整个Transformer模型src_sentence:要翻译的语句# 开启模型的评估模式model.eval()# 将源语句转化为对应的张量表示 起初是一维的(seq_len, ), 后经过view(-1, 1)转化为[seq_len, 1]二维的形状.src text_transform[SRC_LANGUAGE](src_sentence).view(-1, 1)# src.shape [seq_len, 1]num_tokens src.shape[0]# 创建一个全零的矩阵作为src_mask的起始矩阵src_mask (torch.zeros(num_tokens, num_tokens)).type(torch.bool)# 使用贪心算法进行解码tgt_tokens greedy_decode(model, src, src_mask, max_lennum_tokens 5, start_symbolBOS_IDX).flatten()# 现将数据从GPU上迁移到CPU上, 然后进行tensor类型转化为numpy.ndarray类型的整数值# 使用lookup_tokens进行索引到对应字符的查找, 反转为对应的字符, 然后将句子的首尾的bos和eos替换掉, 即为解码之后的语句.return .join(vocab_transform[TGT_LANGUAGE].lookup_tokens(list(tgt_tokens.cpu().numpy()))).replace(bos, ).replace(eos, )9 模型的保存和重加载 9.1 模型的保存 path ./model/transformer_translation_18.pth torch.save(transformer.state_dict(), path)9.2 模型的重加载 transformer Seq2SeqTransformer(NUM_ENCODER_LAYERS, NUM_DECODER_LAYERS, EMB_SIZE,NHEAD, SRC_VOCAB_SIZE, TGT_VOCAB_SIZE, FFN_HID_DIM) transformer.load_state_dict(torch.load(path))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/89417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站开发公司照片网站建设调研

在部署一个cms项目到服务器上的时候,因为cms的模板比较老,服务器上用的php是5.3.3版(大于5.3,可以认为是新的),有些页面会显示“deprecated”类别的错误信息。安全起见要抑制页面中的错误信息输出&#xff…

学做网站的书哪些好定制网站报价

入口我们从使用功能上去读取源码,通常的用法是这个样子-> 我们设置layoutmanager,GridLayouManager 继承LinearLayoutManager,所以我们就LinearLayoutManager 为基准查看rv.layoutManager GridLayoutManager(this,5)rv.addItemDecoration…

咚咚抢网站怎么做的怎么免费推广自己的业务

题外话:栅格布局最初是在web 端应用的,为了解决一个系统在不同的屏幕,和不同的设备上可以不进行多次开发的问题,希望一次开发可以最大化的适配用户的不同类型设备,解决方案:将屏幕采用断点的方式进行布局分…

seo网站优化方法阿里云商标注册入口

欧拉函数的定义 1∼N1∼N 中与 NN 互质的数的个数被称为欧拉函数&#xff0c;记为 ϕ(N)ϕ(N)。 若在算数基本定理中&#xff0c;Npa11pa22…pammNp1a1p2a2…pmam&#xff0c;则&#xff1a; ϕ(N)ϕ(N) Np1−1p1p2−1p2…pm−1pm 代码&#xff1a; #include<iostream>…

五金表带厂东莞网站建设电商网站建设课程设计实验报告

要将CentOS从动态内网IP改为静态IP&#xff0c;需要按照以下步骤进行操作&#xff1a; 打开终端并以root用户身份登录。 编辑网络配置文件。在终端中输入以下命令&#xff1a; vi /etc/sysconfig/network-scripts/ifcfg-eth0 这个命令将打开eth0配置文件。如果您的网络接口…

石家庄高端网站开发wordpress更新文章收录

JavaBean 是特殊的 Java 类&#xff0c;使用 Java 语言书写&#xff0c;并且遵守 JavaBean API 规范。 接下来给出的是 JavaBean 与其它 Java 类相比而言独一无二的特征&#xff1a; 提供一个默认的无参构造函数。需要被序列化并且实现了 Serializable 接口。可能有一系列可读…

重庆建设工程造价信息总站制作网站软件网站

Python实现学生信息管理系统-详解版 个人简介实验名称&#xff1a;学生信息管理系统系统功能实验步骤详讲添加入住学生信息删除学生的住宿信息修改学生的住宿信息查询学生的住宿信息显示所有学生住宿信息显示所有请假学生的信息 运行截图展示1.主界面2.添加新的入住学生信息3.显…

关于网站建设管理工作的报告沈阳京科医院

目录 一、docker是什么 核心概念 二、docker安装 1、卸载docker 2、使用yum 安装 三、docker常用命令 1、帮助命令 2、镜像命令 1&#xff09;查看镜像 2&#xff09;查询镜像 3&#xff09;拉取镜像 4&#xff09;删除镜像 3、容器命令 四、容器数据卷 五、Dock…

包头建设厅官方网站怎么查网站是哪个公司做的

一、设置参数&#xff1a;java虚拟机可以使用JAVA_HOME/bin/java&#xff08;JAVA_HOME为jdk的安装目录&#xff09;。java进程命令行语法&#xff1a; java [options] class [args...] classpath path&#xff1a;指定Java虚拟机应该搜索类文件的路径。与javac编译器选项-cp相…

湛江网站关键词优化西安中高风险地区

前言:Hello大家好,我是小哥谈。SimSPPF是YOLOv6中提出的一种改进的空间金字塔池化方法,它是SPPF的升级版。SimSPPF通过在不同尺度上使用不同大小的池化核来提取特征,从而提高了检测器的性能。与SPPF相比,SimSPPF可以在不增加计算成本的情况下提高检测器的性能。本节课就教…

重庆网站建设团队做维修那个网站发布信息好

一、概述 本文主要介绍如何配置USART&#xff0c;并通过USART打印验证结果。以stm32f10为例&#xff0c;将PA9、PA10复用为USART功能&#xff0c;使用HSE PLL输出72MHZ时钟 APB2 clk不分频提供配置9600波特率。波特率计算公式如下&#xff1a; fck即为APB2 clk参考计算&#xf…

做网站百度一下整屏网站模板

12月26日,由中国领先的财经信息服务平台蓝鲸、记者工作平台鲸平台主办,主流财经通讯社财联社联合主办的第四届“鲸潮奖”在沪揭晓,知名睡眠科技品牌MLILY梦百合入选,荣获“2023年度最‘硬’科技奖”,其他获奖品牌还有新希望乳业、上海家化、洽洽食品、361、汤臣倍健等。 鲸潮奖…

做境外旅游的网站温州建筑信息平台

相信不少小伙伴面试时&#xff0c;都被问到过这样一个问题&#xff1a;进程和线程的区别是什么&#xff1f;大学老师会告诉我们&#xff1a;进程是资源分配的基本单位&#xff0c;线程是调度的基本单位。说到调度&#xff0c;就不得不提到CPU的上下文切换了。 何为CPU上下文切换…

深圳网站设计小程序外贸 网站推广

对我而言&#xff0c;使用Rx-java的最大好处之一就是无论底层调用是同步还是异步&#xff0c;因此代码看起来都完全相同&#xff0c;因此该条目的标题也是如此。 考虑一个非常简单的客户端代码用例&#xff0c;它执行三个缓慢运行的调用并将结果合并到一个列表中&#xff1a; …

手机建造网站江苏SEO网站建设

题目链接&#xff1a;http://poj.org/problem?id3041 没看题&#xff0c;网上搜最大二分匹配搜到的 匈牙利算法&#xff0c;深搜一次最多增加一个匹配 代码&#xff1a; #include <stdio.h> #include <stdlib.h> int tu[505][505]; int mx[505],my[505]; int flag…

wordpress网站百度数据表格模板网站

目录 一、环境搭建 二、信息收集 1、主机发现 2、指纹识别 三、漏洞复现 1、dirsearch目录探测 2、sqlmap注入测试 3、文件包含漏洞 4、Knockd敲门服务 5、ssh爆破 ​​​​​​​6、提权 四、提取flag 一、环境搭建 Vulnhub靶机下载&#xff1a; 官网地址&#xff1a;https://…

环县网站怎么做湘潭专业sem优化

Css 处理 提取 Css 成单独文件 Css 文件目前被打包到 js 文件中&#xff0c;当 js 文件加载时&#xff0c;会创建一个 style 标签来生成样式 这样对于网站来说&#xff0c;会出现闪屏现象&#xff0c;用户体验不好 我们应该是单独的 Css 文件&#xff0c;通过 link 标签加载…

柳城网站天津平台网站建设制作

来源&#xff1a;混沌巡洋舰圣塔菲研究院4月就智能的本质&#xff08;不管其是人类的&#xff0c;还是机器的&#xff09;举行的研讨会&#xff0c;旨在通过跨学科的整合来促进人工智能的发展。研讨会期间&#xff0c;来自不同学科的大牛聚集在一起&#xff0c;讨论如何将智力分…

邵阳建设网站哪家好网站建设长春

nvm-sh/nvm Stars: 67.6k License: MIT Node Version Manager&#xff0c;是一个 POSIX 兼容的 bash 脚本&#xff0c;用于管理多个活动 node.js 版本。nvm 可以让你通过命令行快速安装和使用不同版本的 Node。它可以在任何符合 POSIX 标准的 shell&#xff08;sh、dash、ksh…

天津塘沽网站建设公司电子贺卡制作软件app

深圳女作家、画家崔文僮的散文绘画集出版。该书是她观察生活、体验人生、感悟艺术的真实记录。著名女作家徐小斌看了她的文章和绘画&#xff0c;写道&#xff1a;“‘生活家’这个概念令人非常感兴趣。文僮决定做一个‘有追求’的‘生活家’&#xff0c;这本身就十分有趣&#…