首页 > 其他分享 >基于seq2seq模型实现英译法02

基于seq2seq模型实现英译法02

时间:2023-12-26 22:32:43浏览次数:47  
标签:02 GRU 译法 self seq2seq 解码器 output hidden size


一、 模型设计

模型的构建需要依次实现其嵌入层(embedding)、编码器(encoder)、解码器(decoder)等部分。下面以python 3.6 + pytorch 1.3.1为例,给出了各部分的核心代码。

代码4-1 基于GRU的编码器

class EncoderRNN(nn.Module):def __init__(self, input_size, hidden_size):super(EncoderRNN, self).__init__()self.hidden_size = hidden_sizeself.embedding = nn.Embedding(input_size, hidden_size)self.gru = nn.GRU(hidden_size, hidden_size)  #编码器前向逻辑函数def forward(self, input, hidden):output = self.embedding(input).view(1, 1, -1)output, hidden = self.gru(output, hidden)return output, hidden#初始化隐层张量函数def initHidden(self):return torch.zeros(1, 1, self.hidden_size)

代码4-1中,input_size代表编码器的输入尺寸,即源语言英文的词表大小;hidden_size代表GRU的隐藏层神经单元数, 也是词嵌入维度。首先,我们需要将参数hidden_size传入类中,然后实例化Embedding层,输入参数分别是词表单词总数和词嵌入的维度,再实例化GRU,输入参数是hidden_size。

在编码器前向逻辑函数中,参数input代表源语言的输入张量,参数hidden代表初始化的隐藏层张量。经过Embedding处理后,张量是二维的,由于gru要求输入三维张量,所以要对结果拓展维度,同时让任意单词映射后的尺寸是[1,embedding],将经过维度拓展的结果与hidden传入GRU单元中得到返回结果。除此之外,还需要对隐藏层张量大小进行初始化。


| 代码4-2 基于GRU和Attention的解码器 ```

class AttnDecoderRNN(nn.Module):def __init__(self, hidden_size, output_size, dropout_p=0.1, max_length=MAX_LENGTH):super(AttnDecoderRNN, self).__init__()self.hidden_size = hidden_sizeself.output_size = output_sizeself.dropout_p = dropout_pself.max_length = max_lengthself.embedding = nn.Embedding(self.output_size, self.hidden_size)self.attn = nn.Linear(self.hidden_size * 2, self.max_length)self.attn_combine = nn.Linear(self.hidden_size * 2, self.hidden_size)self.dropout = nn.Dropout(self.dropout_p)self.gru = nn.GRU(self.hidden_size, self.hidden_size)self.out = nn.Linear(self.hidden_size, self.output_size)  #解码器前向逻辑函数def forward(self, input, hidden, encoder_outputs):embedded = self.embedding(input).view(1, 1, -1)embedded = self.dropout(embedded)attn_weights = F.softmax(self.attn(torch.cat((embedded[0], hidden[0]), 1)), dim=1)attn_applied = torch.bmm(attn_weights.unsqueeze(0), encoder_outputs.unsqueeze(0))output = torch.cat((embedded[0], attn_applied[0]), 1)output = self.attn_combine(output).unsqueeze(0)output = F.relu(output)output, hidden = self.gru(output, hidden)output = F.log_softmax(self.out(output[0]), dim=1)return output, hidden, attn_weights  #初始化隐层张量函数def initHidden(self):return torch.zeros(1, 1, self.hidden_size)

代码4-2中,hidden_size代表解码器GRU的隐藏层神经单元数, 也是解码器输入尺寸。output_size代表解码器的输出尺寸,即目标语言法文的词表大小;output_size代表解码器的输出尺寸,即目标语言法文的词表大小;dropout_p代表使用dropout层时的置零比率,max_length代表句子的最大长度。

首先,我们需要将参数传入类中,接下来实例化Embedding层,输入参数分别是目标语言单词总数和词嵌入的维度,再实例化两个attention层,第二个attention层的输出要进入GRU中,再实例化dropout层,然后实例化GRU,输入参数是hidden_size。再实例化线性层对象,对GRU的输出做线性变换,得到期待的输出尺寸output_size;最后使用softmax进行处理,以便于分类。

在解码器前向逻辑函数中,参数input代表目标语言的输入张量,参数hidden代表初始化的隐藏层张量,参数encoder_output代表编码器的输出张量。与编码器相同,将经过Embedding处理后的张量维度拓展为三维,使用dropout进行随机丢弃,防止过拟合。再进行attention层处理。attention结构的结果使用relu激活,将激活后的结果作为GRU的输入和hidden一起传入解码器GRU。最后将结果降维并使用softmax处理得到最终的结果。除此之外,还需要对隐藏层张量大小进行初始化。

二、 模型训练

| 代码5-1 损失计算与优化训练
| if use_teacher_forcing:for di in range(target_length):loss += criterion(decoder_output, target_tensor[di])decoder_input = target_tensor[di]else:for di in range(target_length):topv, topi = decoder_output.topk(1)loss += criterion(decoder_output, target_tensor[di])if topi.squeeze().item() == EOS_token:Breakdecoder_input = topi.squeeze().detach() encoder_optimizer.step()decoder_optimizer.step() # 使用预定义的SGD作为优化器,将参数和学习率传入其中 encoder_optimizer = optim.SGD(encoder.parameters(), lr=learning_rate) decoder_optimizer = optim.SGD(decoder.parameters(), lr=learning_rate) # 选择损失函数 criterion = nn.NLLLoss() |


代码5-1中,target_length是目标文本张量获得对应的长度,target_tensor为目标语言输入张量,encoder_optimizer,decoder_optimizer为编码器,criterion指损失函数计算方法,通过总损失除以间隔得到平均损失。

训练过程中使用了teacher_forcing,它是一种用于序列生成任务的训练技巧,在seq2seq架构中,根据循环神经网络理论,解码器每次应该使用上一步的结果作为输入的一部分,但是训练过程中,一旦上一步的结果是错误的,就会导致这种错误被累积,无法达到训练效果,因此,我们需要一种机制改变上一步出错的情况,因为训练时我们是已知正确的输出应该是什么,因此可以强制将上一步结果设置成正确的输出,这种方式就叫做teacher_forcing。

训练时teacher_forcing比率设置为0.5,也就是有50%的概率使用teacher_forcing。如果使用了teacher_forcing,无论解码器输出的decoder_output是什么,我们都只使用‘正确的答案’,即target_tensor[di]来计算损失,并强制将下一次的解码器输入设置为‘正确的答案’。如果不使用teacher_forcing,损失计算仍然使用decoder_output和target_tensor[di],下一次的解码器输入即当前步最大概率值的那个。


训练参数设置如代码5-2所示:

| 代码5-2 参数设置
| #设置隐层大小为256 ,也是词嵌入维度 hidden_size = 256 # input_lang.n_words输入词汇总数2803,与hidden_size一同传入EncoderRNN类中#得到编码器对象encoder1 encoder1 = EncoderRNN(input_lang.n_words, hidden_size) # output_lang.n_words获取目标词汇总数4345,与hidden_size和dropout_p一同传入AttnDecoderRNN类中#得到解码器对象attn_decoder1 attn_decoder1 = AttnDecoderRNN(hidden_size, output_lang.n_words, dropout_p=0.1)#学习率learning_rate=0.01# 设置迭代步数 n_iters = 75000 # 设置日志打印间隔 print_every = 5000 |



训练输出结果如图5所示:

基于seq2seq模型实现英译法02_ci

图5 训练结果


训练的损失下降曲线如图6所示:

图6 损失下降曲线

可以看出模型在经过多次迭代后效果逐渐增强。

三、 模型评测

从pairs随机选取10条语言对,模型测试得到的法文翻译输出与正确的翻译对比如图7所示:

图7 生成翻译结果

可以看出模型生成的翻译已经很接近正确翻译,但仍然存在一些偏差。

对句子sentence = "we re both teachers ."评估得到生成的目标语言对应的词汇以及Attention可视化如图8、图9所示:

图8 目标语言对应词汇

基于seq2seq模型实现英译法02_ci_02

图9 attention可视化

基于seq2seq模型实现英译法02_目标语言_03

Attention图像的纵坐标代表输入的源语言各个词汇对应的索引, 0-6分别对应["we", "re", "both", "teachers", ".", ""], 纵坐标代表生成的目标语言各个词汇对应的索引, 0-7代表['nous', 'sommes', 'toutes', 'deux', 'enseignantes', '.', ''], 图中浅色小方块(颜色越浅说明影响越大)代表词汇之间的影响关系,通过这样的可视化图像,可以知道Attention的效果好坏,与人为去判定到底还有多大的差距,进而衡量训练模型的可用性。

四、 总结

本实验围绕seq2seq模型完成英法翻译,在整个实验过程中我学习到了整个翻译模型进行翻译的过程,包括分词、字符规范化、编码器和解码器设计、加入注意力机制等。在最后得到了模型生成的翻译,感受到了神经网络的强大。除此之外,此次实验生成的翻译在丰富度和正确性上都有所不足,实验迭代的时间较长,对设置合适的训练参数仍有很多进步空间。我在后期的学习会继续努力,期望能做出更好的实验结果。

标签:02,GRU,译法,self,seq2seq,解码器,output,hidden,size
From: https://blog.51cto.com/u_15655475/8988415

相关文章

  • 我的2023年总结
    2023年,北京的冬天特别寒冷,雪下的好大好大,持续的时间还特别特别的长。极端的低温,长时间的降雪甚至引发了地铁线路的追尾,个人感觉这在北京地铁交通历史上,应该是第一次。远在欧洲的俄乌冲突已经不是人们谈论的焦点,因为滴滴前所未见的故障而打不上车才是迫切需要关心和解决的事情。不......
  • 金蝶云表单【表单插件】---物料新增按钮点击自动获取老系统中对应的物料信息20231226
    金蝶云需求:1、物料新增时,通过快捷方式自动获取老系统K3Wise中对应物料的相关信息;2、具体相关对应物料字段项信息,由存储过程:execpro_lyh_get_oldsystemwlxx'002'来查询结果;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSyste......
  • [20231226]vim Align插件使用例子.txt
    [20231226]vimAlign插件使用例子.txt--//有时候看别人的blog如果遇到执行计划如下,我会使用vim的Align插件做一些处理,好久不用有点生疏,做一个记录:--//假设拷贝和粘贴的执行计划如下:---------------------------------------------------------------------------------------......
  • 2023“强网杯”部分WP
    强网先锋SpeedUp题目我的解答:分析代码可知是求2的27次方的阶乘的每一位的和。使用在线网址直接查看:https://oeis.org/A244060/list然后sha256加密flag{bbdee5c548fddfc76617c562952a3a3b03d423985c095521a8661d248fad3797}MISC谍影重重2.0题目我的解答:根据题目信......
  • android-studio-2021.1.1.11-windows 版本遇到的各种大坑
    1、使用2023.12月的最新版本会无法选择java语言开发,所以必须选择较老的版本,比如我选择的android-studiobumbblebee 2021.1.1.11这个版本就可以选择java语言。2、不光需要设置代码自动补全提示,更重要的是最新的SDK,androidapi34有bug,无法语法提示,也可能是不支持我所使用的语......
  • Solution Set 2023.12.26
    [YnoiEasyRound2023]TEST_69发现若一个数被进行了一次有效操作,那么其的值至少会除以\(2\),所以一个数至多被操作\(\mathcal{O}(\loga_i)\)次。那么可以通过势能线段树维护操作,考虑什么情况下一个区间不会被操作,即\(a_i\)的值不会被改变。即对于区间的任何元素,其值均为......
  • 02-redis的持久化和数据类型
    一、redis持久化1.1持久化类型|持久化类型|介绍|优点|缺点|-------------|-----------------|-----------------|-------------|--|RDB持久化|可以在指定的时间间隔内生成数据集的时间点快照(point-in-timesnapshot)。|速度快,适合于用做备份,主从复制也是基于RDB持久化功能......
  • 实力上榜|棱镜七彩荣登《嘶吼2023中国网络安全产业势能榜》
    近日,国内网络安全行业第三方研究机构嘶吼安全产业研究院发布《嘶吼2023中国网络安全产业势能榜》。棱镜七彩凭借过硬的技术实力和产品创新能力,作为创新型厂商荣登《2023中国网络安全产业势能榜》互联网行业榜单。据悉,《2023中国网络安全产业势能榜》旨在深入研判和展望中国网络安全......
  • 2023最新中级难度R语言面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-中级难度R语言面试题合集问:请解释一下R语言中的向量(vector)和列表(list)有什么区别?R语言中的向量(vector)和列表(list)是两种非常基本的数据结构,它们有一些重要的区别:数据类型:向量:在R中,向量是同质的,即所有元素必须是相同的数据类型。例如......
  • 2023最新高级难度R语言面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-高级难度R语言面试题合集问:请解释一下R语言中的闭包(closure)是什么,并举一个例子说明如何使用闭包来实现柯里化(currying)函数。在R语言中,闭包是一种特殊的函数,它能够记住并访问在其外部定义的变量。当一个函数被定义在一个环境中,并且这个......