当前位置:   article > 正文

Seq2Seq-master代码详解_seq2seq预测, 多维输入matlab代码

seq2seq预测, 多维输入matlab代码

代码地址:https://github.com/keon/seq2seq

一、参数定义模块

       epochs                               --- 迭代次数(default = 100)

       batch_size                         --- 批处理参数,并行处理数据的数量(default = 32)

       lr                                        --- 学习率(default = 0.0001),是超参数

       grad_clip                           --- 梯度阈值(default = 10.0)

       hide_size = 512                ---隐层大小

       embed_size = 256            --- embedding层大小

二、数据加载模块

 train_iter, val_iter, test_iter  --- 分别为训练集、验证集、测试集的迭代器

 len(train_iter): 907  (dataset:29000)

 len(test_iter): 32    (dataset:1000)

 DE,EN --- 语言模型:英语和德语

 de_size = 8014,    德语词典里的词数

 en_size = 10004   英语词典里的词数

词典里的几个特殊标记:

                                     '<pad>': 1,  ->填充符,填充句子使其长度增加,用来统一句子的长度

                                     '<sos>': 2,  ->开始符,标志一个句子的开始

                                     '<eos>': 3   ->结束符,标志一个句子的结束

三、模型初始化

1.定义编码器

Encoder(de_size, embed_size, hidden_size, n_layers=2, dropout=0.5)

self.input_size = de_size = 8014

self.hidden_size = hidden_size = 512

self.embed_size = embed_size = 256

self.embed = Embedding(8014, 256)

2.定义解码器

Decoder(embed_size, hidden_size, en_size, n_layers=1, dropout=0.5)

self.embed_size = embed_size = 256

self.hidden_size = hidden_size = 512

self.output_size = en_size = 10004

self.embed = Embedding(10004, 256)

四、模型训练

 

通过train_iter迭代训练集(训练集的数据大小为29000,每次处理32个句子,需循环907次

每次从训练集中随机取出32个句子,以32个句子中词数最多的为准。所以每次句子的长度可能不同

这里就详细介绍第一次迭代过程(调试代码,观察数据是如何变化的)

此次的句子长度为23

src = tensor(23*32)       //这32个句子的词数统一为23,小于23的用<pad>填充 (德)

len_src = tensor(1*32)  //32个句子的实际词数,取值:[1,23] +1         

trg = tensor(22*32)       //这32个句子的词数统一为22,小于22的用<pad>填充(英)      

len_trg = tensor(1*32)  //32个句子的实际词数,取值:[1,22]+1

//进入Seq2Seq模型计算,input为输入,output为输出

input :  第0维: torch.Size([23*32])      ----src(德语)

               第1维: torch.Size([22*32])      ----trg(英语)

outputs: torch.Size([22,32,10004])          // 先初始化为全0

1.通过Encoder对输入input[0]进行编码,输出为encoder_output,hidden

encoder的输入为:input[0]: torch.Size([23*32])   

embedded: torch.Size([23*32*256])            //转为词向量,词典的每个词对应一个大小256的向量

//将转化后的输入传递给gru,它会自动为整个序列重复计算hidden(隐藏状态),初始为None

          gru的输入:embedded:torch.Size([23*32*256])  ,  hidden:None

          gru的输出:outputs: torch.Size([23*32*256])    hidden: torch.Size([4,32,512])

因为这里的gru是双向的,所以要把两层的结果加起来,然后返回

encoder的输出为:encoder_output: torch.Size([23, 32, 512])

                               hidden: torch.Size([4, 32, 512])

2.通过Decoder进行逐词解码,最后的输出为output,  hidden,  attn_weights(注意力权重)

将Encoder输出来的hidden取出第1维,作为Decoder的初始隐状态

Decoder的输入:encoder_output: torch.Size([23, 32, 512])

                            hidden: torch.Size([1, 32, 512])

刚开始input形状是torch.Size([32]),经embed转化后变为torch.Size([32,256]),再在0轴上升1维后得到embedded,形状为torch.Size([1,32,256])

然后对embedded张量dropout(随机丢弃)一些值

通过attention计算注意力权重,输出attn_weights

attention的输入:encoder_output: torch.Size([23, 32, 512])

                            last_hidden  即传入Decoder的hidden(初始隐状态)[-1]:torch.Size([32, 512])

h:torch.Size([32,23,512])       

encoder_output转置之后变为torch.Size([32,23,512])

然后传入score函数计算

energy: torch.Size([32,23,512])    转置之后为 torch.Size([32,512,23]) 

v:torch.Size([32,1,512])

将energy跟v相乘(bmm)后     energy:torch.Size([32,1,23])

 将energy降维后返回结果

所以attn_energies为torch.Size([32,23])

attention的输出:attn_weights:torch.Size([32,23])

context:torch.Size([32, 1, 512])    然后转置为  torch.Size([1, 32, 512])

rnn_input:torch.Size([1, 32, 768])

进入gru(Decoder的)网络计算,输出output,hidden

      gru的输入:rnn_input:torch.Size([1, 32, 768])

                          last_hidden:torch.Size([32, 512])

      gru的输出:output = torch.Size([1, 32, 512]) (返回)

                          hidden = torch.Size([1, 32, 512])   (返回)

将output和context降维之后再合并,进入out函数计算

out函数输出的output:torch.Size([32,10004])

然后送入激活函数log_softmax计算之后 返回结果

Decoder的输出:output:torch.Size([32, 10004])

                            hidden:torch.Size([1, 32, 512])

                            attn_weights:torch.Size([32,23])

将句子的第t个词的预测结果放入到outputs中对应的位置

为了避免此次预测不准确而影响后面的预测,加入了is_teacher,若is_teacher为True,则使用trg.data[t](真实值),否则用预测值

每个词都预测完之后,返回outputs

Seq2Seq的输出(即返回的outputs): output:torch.Size([22, 32, 10004])

通过损失函数nll_loss()求预测值与实际值的误差,根据误差对模型参数求梯度,通过设置梯度阈值(grad_clip=10)解决过度拟合,更新模型参数,并更新整个模型。

累计误差值

每100次打印1次误差值,先将累计的误差值除以100再打印出来

训练完1轮后,用验证集验证模型

第一轮训练或者误差值比上轮更小就保存这个模型

训练完100轮之后,保存的最后那个模型就是最优的,我们就可以用这个模型来预测了,结果应该比较准确了。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/802403
推荐阅读
相关标签
  

闽ICP备14008679号