在循环内加的teacher forcing机制,这种为目标确定的时候,可以这样加。

目标不确定,需要在循环外加。

decoder.py 中的修改

"""
实现解码器
"""
import torch.nn as nn
import config
import torch
import torch.nn.functional as F
import numpy as np
import random class Decoder(nn.Module):
def __init__(self):
super(Decoder, self).__init__() self.embedding = nn.Embedding(num_embeddings=len(config.ns),
embedding_dim=50,
padding_idx=config.ns.PAD) # 需要的hidden_state形状:[1,batch_size,64]
self.gru = nn.GRU(input_size=50,
hidden_size=64,
num_layers=1,
bidirectional=False,
batch_first=True,
dropout=0) # 假如encoder的hidden_size=64,num_layer=1 encoder_hidden :[2,batch_sizee,64] self.fc = nn.Linear(64, len(config.ns)) def forward(self, encoder_hidden,target): # 第一个时间步的输入的hidden_state
decoder_hidden = encoder_hidden # [1,batch_size,encoder_hidden_size]
# 第一个时间步的输入的input
batch_size = encoder_hidden.size(1)
decoder_input = torch.LongTensor([[config.ns.SOS]] * batch_size).to(config.device) # [batch_size,1]
# print("decoder_input:",decoder_input.size()) # 使用全为0的数组保存数据,[batch_size,max_len,vocab_size]
decoder_outputs = torch.zeros([batch_size, config.max_len, len(config.ns)]).to(config.device) for t in range(config.max_len):
decoder_output_t, decoder_hidden = self.forward_step(decoder_input, decoder_hidden)
decoder_outputs[:, t, :] = decoder_output_t # 获取当前时间步的预测值
value, index = decoder_output_t.max(dim=-1)
if random.randint(0,100) >70: #teacher forcing机制
decoder_input = target[:,t].unsqueeze(-1)
else:
decoder_input = index.unsqueeze(-1) # [batch_size,1]
# print("decoder_input:",decoder_input.size())
return decoder_outputs, decoder_hidden def forward_step(self, decoder_input, decoder_hidden):
'''
计算一个时间步的结果
:param decoder_input: [batch_size,1]
:param decoder_hidden: [batch_size,encoder_hidden_size]
:return:
''' decoder_input_embeded = self.embedding(decoder_input)
# print("decoder_input_embeded:",decoder_input_embeded.size()) out, decoder_hidden = self.gru(decoder_input_embeded, decoder_hidden) # out :【batch_size,1,hidden_size】 out_squeezed = out.squeeze(dim=1) # 去掉为1的维度
out_fc = F.log_softmax(self.fc(out_squeezed), dim=-1) # [bathc_size,vocab_size]
# out_fc.unsqueeze_(dim=1) #[bathc_size,1,vocab_size]
# print("out_fc:",out_fc.size())
return out_fc, decoder_hidden def evaluate(self, encoder_hidden): # 第一个时间步的输入的hidden_state
decoder_hidden = encoder_hidden # [1,batch_size,encoder_hidden_size]
# 第一个时间步的输入的input
batch_size = encoder_hidden.size(1)
decoder_input = torch.LongTensor([[config.ns.SOS]] * batch_size).to(config.device) # [batch_size,1]
# print("decoder_input:",decoder_input.size()) # 使用全为0的数组保存数据,[batch_size,max_len,vocab_size]
decoder_outputs = torch.zeros([batch_size, config.max_len, len(config.ns)]).to(config.device) decoder_predict = [] # [[],[],[]] #123456 ,targe:123456EOS,predict:123456EOS123
for t in range(config.max_len):
decoder_output_t, decoder_hidden = self.forward_step(decoder_input, decoder_hidden)
decoder_outputs[:, t, :] = decoder_output_t # 获取当前时间步的预测值
value, index = decoder_output_t.max(dim=-1)
decoder_input = index.unsqueeze(-1) # [batch_size,1]
# print("decoder_input:",decoder_input.size())
decoder_predict.append(index.cpu().detach().numpy()) # 返回预测值
decoder_predict = np.array(decoder_predict).transpose() # [batch_size,max_len]
return decoder_outputs, decoder_predict

  seq2seq.py

"""
完成seq2seq模型
"""
import torch.nn as nn
from encoder import Encoder
from decoder import Decoder class Seq2Seq(nn.Module):
def __init__(self):
super(Seq2Seq, self).__init__()
self.encoder = Encoder()
self.decoder = Decoder() def forward(self, input, input_len,target):
encoder_outputs, encoder_hidden = self.encoder(input, input_len)
decoder_outputs, decoder_hidden = self.decoder(encoder_hidden,target)
return decoder_outputs def evaluate(self, input, input_len):
encoder_outputs, encoder_hidden = self.encoder(input, input_len)
decoder_outputs, decoder_predict = self.decoder.evaluate(encoder_hidden)
return decoder_outputs, decoder_predict

  train.py

"""
进行模型的训练
"""
import torch
import torch.nn.functional as F
from seq2seq import Seq2Seq
from torch.optim import Adam
from dataset import get_dataloader
from tqdm import tqdm
import config
import numpy as np
import pickle
from matplotlib import pyplot as plt
from eval import eval
import os model = Seq2Seq().to(config.device)
optimizer = Adam(model.parameters()) if os.path.exists("./models/model.pkl"):
model.load_state_dict(torch.load("./models/model.pkl"))
optimizer.load_state_dict(torch.load("./models/optimizer.pkl")) loss_list = [] def train(epoch):
data_loader = get_dataloader(train=True)
bar = tqdm(data_loader, total=len(data_loader)) for idx, (input, target, input_len, target_len) in enumerate(bar):
input = input.to(config.device)
target = target.to(config.device)
input_len = input_len.to(config.device)
optimizer.zero_grad()
decoder_outputs = model(input, input_len,target) # [batch_Size,max_len,vocab_size]
predict = decoder_outputs.view(-1, len(config.ns))
target = target.view(-1)
loss = F.nll_loss(predict, target, ignore_index=config.ns.PAD)
loss.backward()
optimizer.step()
loss_list.append(loss.item())
bar.set_description("epoch:{} idx:{} loss:{:.6f}".format(epoch, idx, np.mean(loss_list))) if idx % 100 == 0:
torch.save(model.state_dict(), "./models/model.pkl")
torch.save(optimizer.state_dict(), "./models/optimizer.pkl")
pickle.dump(loss_list, open("./models/loss_list.pkl", "wb")) if __name__ == '__main__':
for i in range(5):
train(i)
eval() plt.figure(figsize=(50, 8))
plt.plot(range(len(loss_list)), loss_list)
plt.show()

  

pytorch seq2seq模型中加入teacher_forcing机制的更多相关文章

  1. pytorch seq2seq闲聊机器人加入attention机制

    attention.py """ 实现attention """ import torch import torch.nn as nn im ...

  2. pytorch seq2seq模型示例

    以下代码可以让你更加熟悉seq2seq模型机制 """ test """ import numpy as np import torch i ...

  3. 分布式系统读写模型中的Quorum机制

    分布式系统的设计中会涉及到许多的协议.机制用来解决可靠性问题.数据一致性问题等,Quorum 机制就是其中的一种.我们通过分布式系统中的读写模型来简单介绍它. 分布式系统中的读写模型 分布式系统是由多 ...

  4. pytorch seq2seq模型训练测试

    num_sequence.py """ 数字序列化方法 """ class NumSequence: """ ...

  5. Seq2Seq模型与注意力机制

    Seq2Seq模型 基本原理 核心思想:将一个作为输入的序列映射为一个作为输出的序列 编码输入 解码输出 解码第一步,解码器进入编码器的最终状态,生成第一个输出 以后解码器读入上一步的输出,生成当前步 ...

  6. 深度学习之seq2seq模型以及Attention机制

    RNN,LSTM,seq2seq等模型广泛用于自然语言处理以及回归预测,本期详解seq2seq模型以及attention机制的原理以及在回归预测方向的运用. 1. seq2seq模型介绍 seq2se ...

  7. 注意力机制和Seq2seq模型

    注意力机制 在"编码器-解码器(seq2seq)"⼀节⾥,解码器在各个时间步依赖相同的背景变量(context vector)来获取输⼊序列信息.当编码器为循环神经⽹络时,背景变量 ...

  8. L11注意力机制和Seq2seq模型

    注意力机制 在"编码器-解码器(seq2seq)"⼀节⾥,解码器在各个时间步依赖相同的背景变量(context vector)来获取输⼊序列信息.当编码器为循环神经⽹络时,背景变量 ...

  9. Deep Learning基础--理解LSTM/RNN中的Attention机制

    导读 目前采用编码器-解码器 (Encode-Decode) 结构的模型非常热门,是因为它在许多领域较其他的传统模型方法都取得了更好的结果.这种结构的模型通常将输入序列编码成一个固定长度的向量表示,对 ...

随机推荐

  1. CodeForces - 1006F (深搜从两端向中间搜,省时)

    题意:输入n,m,k,给出一个n*m的图,里面有权值,从1,1一路异或到n,m,只能向右或向下走,等于k有多少种路径. 思路:一开始就是直接暴力写个深搜,稳稳的超时,分析一下时间复杂度.每个点有两个方 ...

  2. coding++:java-全局异常处理

    本次使用工具:SpringBoot   <version>1.5.19.RELEASE</version> Code: AbstractException: package m ...

  3. mac 中使用git 和pycharm提交项目

    一.安装Git 1.验证git是否安装: 终端中输入: git 如果安装过出现: 2.安装git: 进入https://git-scm.com: 点击 Download 2.23.0 for Mac ...

  4. python中如何在一个for循环中遍历两个列表

    `其实就是用zip把两个列表包装起来:  for x, y in zip(list1, list2) 

  5. Windows 7集成IE11(离线安装包、补丁)

    当Win7系统需要集成IE11时,我们需要提前打入6个补丁 KB2731771.KB2786081.KB2834140.KB2670838.KB2729094.KB2533623 32位 ★百度网盘 ...

  6. 【开源】使用Angular9和TypeScript开发RPG游戏(20200410版)

    源代码地址 通过对于斗罗大陆小说的游戏化过程,熟悉Angular的结构以及使用TypeScript的面向对象开发方法. Github项目源代码地址 RPG系统构造 ver0.03 2020/04/10 ...

  7. 数据挖掘 决策树 Decision tree

    数据挖掘-决策树 Decision tree 目录 数据挖掘-决策树 Decision tree 1. 决策树概述 1.1 决策树介绍 1.1.1 决策树定义 1.1.2 本质 1.1.3 决策树的组 ...

  8. C++头文件中的模板类

    C++头文件中的模板类 这已经是我的第三篇关于头文件的博客了,没想到我还是踩了个巨坑. 大家都知道要在头文件里声明类成员,在源文件中实现. 但是今天写数据结构作业,在头文件(Stack.h)定义了一个 ...

  9. 一个关于HttpClient的轮子

    由于本文较长,需要耐住性子阅读,另外本文中涉及到的知识点较多,想要深入学习某知识点可以参考其他博客或官网资料.本文也非源码分析文章,示例中的源码大多是伪代码和剪辑过的代码示例,由于该轮子为公司内部使用 ...

  10. 基于 Spring Cloud 的微服务架构实践指南(下)

    show me the code and talk to me,做的出来更要说的明白 本文源码,请点击learnSpringCloud 我是布尔bl,你的支持是我分享的动力! 一.引入 上回 基于 S ...