在循环内加的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. iOS 页面流畅技巧(1)

    一.屏幕显示图像原理 首先明确两个概念:水平同步信号.垂直同步信号. CRT 的电子枪按照上图中的方式,从上到下一行一行的扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次的扫描. ...

  2. mongodb的更新语句

    MongoDB 使用 update() 和 save() 方法来更新集合中的文档: update()方法: update() 方法用于更新已存在的文档.语法格式如下: db.collection.up ...

  3. [noip模拟20170921]模版题

      今天考的是一套很基础的模版题,但是我这种蒟蒻竟然还是没有AK,不得不说,蒟蒻和大佬的差别不是一点点啊 1.暴走的猴子(walk.pas/c/cpp) [题目描述] 从前有一个森林,森林里生活着一群 ...

  4. Python——交互式图形编程

    一. 1.图形显示 图素法 像素法 图素法---矢量图:以图形对象为基本元素组成的图形,如矩形. 圆形 像素法---标量图:以像素点为基本单位形成图形 2.图形用户界面:Graphical User ...

  5. Promise入门详解

    异步调用 异步 JavaScript的执行环境是单线程. 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它 ...

  6. NKOJ4238 天天爱跑步(【NOIP2016 DAY1】)

    问题描述 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一棵包 ...

  7. 多源第k短路 (ford + 重新定义编号) / 出发点、终点确定的第k短路 (Spfa+ 启发搜索)

    第k短路 Description 一天,HighLights实在是闲的不行,他选取了n个地点,n各地点之间共有m条路径,他想找到这m条路径组成的第k短路,你能帮助他嘛? Input 第一行三个正整数, ...

  8. Java并发基础06. 线程范围内共享数据

    假设现在有个公共的变量 data,有不同的线程都可以去操作它,如果在不同的线程对 data 操作完成后再去取这个 data,那么肯定会出现线程间的数据混乱问题,因为 A 线程在取 data 数据前可能 ...

  9. Scala学习系列(一)——Scala为什么是大数据第一高薪语言

    为什么是Scala 虽然在大数据领域Java的使用更普及,Python也有后来居上的势头,但Scala一直有着不可动摇的地位.我们熟悉的Spark,Kafka,Flink都是由Scala完成了其核心代 ...

  10. 《Three.js 入门指南》3.1.1 - 基本几何形状 -圆环面(TorusGeometry)

    3.1 基本几何形状 圆环面(TorusGeometry) 构造函数 THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments ...