1、模型原理
所谓Seq2Seq(Sequence to Sequence), 就是一种能够根据给定的序列,通过特定的方法生成另一个序列的方法。最基础的Seq2Seq模型包含了三个部分,即Encoder、Decoder以及连接两者的中间状态向量C,Encoder通过学习输入,将其编码成一个固定大小的状态向量c,继而将c传给Decoder,Decoder再通过对状态向量c的学习来进行输出。结构如图所示:
这里面的输入有三个:Encoder的输入, Encoder生产的隐藏状态(语义编码c),Decoder的输入(上图画的不是很准确,Decoder部分也应该包含输入)。
2、代码实现
本文所用的数据为简单的六个词组,如下所示:
['man', 'women'], ['black', 'white'], ['king', 'queen'], ['girl', 'boy'], ['up', 'down'], ['high', 'low']
我们假设这是一个翻译模型,输入每个词组的第一个单词,经过Seq2Seq网络的训练后,模型可以给出该单词的“翻译”,例如当输入“man”时,我们希望模型给出的结果是“women”。
1. 导入需要的库,设置数据类型
import numpy as np
import torch
import torch.nn as nn
from torch.autograd import Variable
dtype = torch.FloatTensor
2. 创建数据和字典
seq_data = [['man', 'women'], ['black', 'white'], ['king', 'queen'], ['girl', 'boy'], ['up', 'down'], ['high', 'low']]
// S: 单词的开始标志
// E: 单词的结束标志
// P: 单词长度少于时间步长时用P进行填充
char_arr = [c for c in 'SEPabcdefghijklmnopqrstuvwxyz']
num_dict = {
n:i for i, n in enumerate(char_arr)}
3. 设置网络参数
n_step = 5
n_hidden = 128
n_class = len(num_dict)
batch_size = len(seq_data)
Seq2Seq的网络设计好之后的输入序列和输出序列长度是不可变的。因此我们设置时间步长为5,当一个单词的字符长度不够5时,比如“man”,我们就用"P"将长度补齐,
4. 创建batch
def make_batch(seq_data):
input_batch, output_batch, target_batch = [], [], [