目录
摘要
本周我读了一篇题为《Sequence to Sequence Learning with Neural Networks》的论文,文中使用了两个多层LSTM来实现输入序列到固定维度向量再到目标序列的转换,很好地解决了此前序列到序列任务中的效果不佳问题。接着,我对GRU进行了深入学习,通过矩阵运算推导,弄清楚了GRU每一步的输出维度变化。最后,我学习了张量中协变量与逆变量变换的知识。
ABSTRACT
This week, a paper entitled "Sequence to Sequence Learning with Neural Networks" was read by me. Two multi-layer LSTMs were used in the paper to implement the conversion from an input sequence to a fixed-dimensional vector and then to a target sequence, which solved the problem of poor effects in previous sequence-to-sequence tasks very well. Next, GRU was studied in depth by me through matrix operation deduction, and the output dimension changes of GRU at each step were clarified. Finally, knowledge about covariant and contravariant transformations in tensors was learned by me.
一、文献阅读
1、题目
题目:Sequence to Sequence Learning with Neural Networks
链接:https://arxiv.org/pdf/1409.3215.pdf
期刊:NIPS2014
2、ABSTRACT
由于DNN在序列-序列的问题上效果不好,所以提出了Sequence to Sequence,本篇论文通过多层的LSTM将输入的语言序列(原序列)转换为固定维度的向量,然后另一个深层的LSTM将此向量解码成相应的另一种语言序列(目标序列),还通过逆转原序列的方式,提高了LSTM的性能表现。
Since DNN did not perform well on sequence-to-sequence problems, Sequence to Sequence was proposed. In this paper, the input language sequence (source sequence) was converted into a fixed-dimensional vector through a multilayer LSTM. Then the vector was decoded into the corresponding sequence in another language (target sequence) by another deep LSTM. The performance of LSTM was also improved by reversing the source sequence.
3、网络架构
文章中的模型架构的思想是使用一个LSTM读取输入序列,每次一个时间步长,以获得大的固定维向量表示,然后使用另一个LSTM从该向量提取输出序列。也就是Encoder-Decoder模型,Encoder负责将序列转换为固定维度的向量,Decoder负责将固定维度的向量再转换为序列。
从图中来说,先读入原序列‘ABC’,遇到结束符停止,然后输出目标序列‘WXYZ’。在本文中,LSTM是反过来读取输入语句的,所以这样做可以引入更多的短期依赖,使得优化更容易。
4、文献解读
1、Introduction
深度神经网络(DNN)在处理各种难题,如图像识别上有着近乎完美的表现。这种模型之所以这么强大,是因为它能在有限的步骤内实现任意并行计算。只要有足够的训练数据集,它就能训练出神经网络的参数,但它只能将源序列和目标序列都编译为固定维度的向量。这是一个致命的缺陷,因为很多问题都无法提前预知被表示序列的长度,例如语音识别与机器翻译。所以本文提出了一种解决方案。
2、创新点
1、逆转原序列
当源句子反转(目标句子不反转)时,LSTM 学得更好。当我们将源句子与目标句子连接时,源句子中的每个单词与目标句子中对应的单词相距甚远。因此,该问题具有很大的“最小时滞。通过颠倒源句子中的单词,源语言和目标语言中对应单词之间的平均距离保持不变。然而,源语言中的前几个单词现在与目标语言中的前几个单词非常接近,因此问题的最小时间滞后大大减少。
2、使用深层LSTM
文章使用了两种不同的 LSTM:一种用于输入序列,另一种用于输出序列,因为这样做以可忽略的计算成本增加了模型参数的数量,并且使得同时训练 LSTM 多个语言对变得自然。其次,我们发现深层 LSTM 的性能明显优于浅层 LSTM,因此我们选择了四层 LSTM。
3、实验过程
一、数据集
使用WMT’14英法数据集,在12000万个句子的子集上训练模型,这些句子由3.48亿个法语单词和3.04亿个英语单词组成。词汇表:源语言中使用了160000个最常用词,在目标语言中使用了80000个最常用词。每一个词汇表外的单词都被替换为一个特殊的“UNK”标记。
二、评估指标
评估在 BLEU score上的得分
三、超参数的设定
1、初始化所有LSTM参数, 均匀分布在-0.08和 0.08 之间
2、使用无动量的SGD, 固定学习率为0.7, 5个epochs之后, 每半个epoch 学习率减半, 总共训练7.5个epochs.
3、batch_size 为128
4、虽然LSTM没有梯度消失的问题,但是可能会发生梯度爆炸,所以使用范数进行约束,对于每个batch,计算s=|g|_2,其中g是梯度除以128,如果s>5,则设置g=5g/s
四、实验结果
下表是与其他模型在机器翻译上的效果对比,上面两行是其他模型的效果,下面六行是作者模型在不同参数设置时的效果
此外,作者还尝试将自己的模型与传统的STM系统进行结合,效果显著,BLEU最好的达到了37.0,超过Baseline System将近4个点
4、结论
LSTM可以优于一个基于SMT的标准系统。如果有足够的训练数据,它应该可以很好地解决许多其他序列学习问题。颠倒源语句中单词获得的改善程度很大。找到一个具有最多短期依赖性的问题编码会使学习问题更加简单。LSTM能够正确翻译非常长的句子。我们认为由于记忆有限,LSTM在长句上会失败。但是在反向数据集上训练的LSTM翻译长句几乎没有困难。
二、GRU手动推导
下述代码建立了一个GRU的前向传播过程函数,其中输入大小,隐藏层大小,样本数量,时间步的大小分别为4,5,2,3。然后通过GRU中的两个门,重置门以及更新门的计算,得到一个输出,通过该输出与我们手动推导的结果进行对比。
import torch
from torch import nn
def gru_forward(input,initial_states,w_ih,w_hh,b_ih,b_hh):
prev_h=initial_states
bs,T,i_size=input.shape
h_size=w_ih.shape[0]//3
#对权重扩维,扩成batch_size倍
batch_w_ih = w_ih.unsqueeze(0).title(bs,1,1)
batch_w_hh = w_hh.unsqueeze(0).title(bs,1,1)
output = torch.zeros(bs,T,h_size)
for t in range(T):
x=input[:,t,:]
w_times_x=torch.bmm(batch_w_ih,x.unsqueeze(-1))
w_times_x=w_times_x.squeeze(-1)
w_times_h_prev=torch.bmm(batch_w_hh,prev_h.unsqueeze(-1))
w_times_h_prev=w_times_h_prev.squeeze(-1)
r_t = torch.sigmoid(w_times_x[:,:h_size]+w_times_h_prev[:,:h_size]+b_ih[:h_size]+b_hh[:h_size])
z_t = torch.sigmoid(w_times_x[:,h_size:2*h_size]+w_times_h_prev[:,h_size:2*h_size]+b_ih[h_size:2*h_size]+b_hh[h_size:2*h_size])
n_t =torch.tanh(w_times_x[:,2*h_size:3*h_size]+b_ih[2*h_size:3*h_size]+r_t*(w_times_h_prev[:,2*h_size:3*h_size]+b_hh[2*h_size:3*h_size]))
prev_h = (1-z_t)*n_t + z_t*prev_h
output[:,t,:] = prev_h
return output,prev_h
bs,T,i_size,h_size = 2,3,4,5
input = torch.randn(bs,T,i_size)
h0=torch.randn(bs,h_size)
gru_layer = nn.GRU(i_size,h_size,batch_first=True)
output,h_final = gru_layer(input,h0.unsqueeze(0))
print(output)
代码运行结果如下:
我们可以发现,运行结果的shape也是(2,3,5),与我们的推导是一致的。
三、张量学习
一、逆变向量
1、分量变化的两种形式
一般来说,当坐标系发生变化时,向量的分量变化可分为:
(1)、逆变形式(Contravarient);
(2)、协变形式(Covarient)。
- 当分量和坐标变换方向相反时,称为逆变向量;
- 当分量和坐标变换方向相同是,称为协变向量。
2、举例
假设有一个二维坐标系,和不垂直,有一个夹角。基矢量的长度为1,方向为方向;基矢量的长度为1,方向为方向。
设有向量在这个坐标系中,我们该如何表示这个向量?
我们可以找出拼出所需要的的个数,我们记作;然后找出拼出所需要的的个数,我们记作。那么就可以被表示为:
现在我们对这个坐标系施加一个坐标变换,使得在新坐标系下的基矢量:
的长度变为的两倍,但方向不变;相较于没有变化,两者相等。
当我们用这组新的基矢量去表示时:
由于的长度是的两倍,那么所需要的个数就减半了,这意味着′所对应的分量
从上面这个例子我们可以看出,基向量和其对应的分量以相反的方向在变化,基向量翻倍之后,分量减半了。这时可称这个分量是逆变分量,因为分量的变化方向相反于基向量变化的方向。
标明分量是逆变的要使用上标,这是因为基向量一般都是使用下标,为了表示分量变化形式与基向量相反,所以我们采用上标来表示逆变分量。
一个用逆变分量表示的向量就叫做逆变向量。
二、协变向量与协变分量
举例:
可以发现,坐标变换之后的分量等于变换前的分量,而坐标变换之后的分量等于2倍变换前的分量。
1、当基向量的长度翻倍时,相应的协变分量同样翻倍了,所以协变分量以与基向量相同的方式进行变换。
2、用下标来表示协变分量,就像我们用下标来表示基向量,这样可以表达出协变分量和基向量变换方式相同的特性。
3、用协变分量表示的向量叫做协变向量,协变向量和一般所说的逆变向量有很大的不同。比如协变向量一般写作行向量,而通常的向量一般写作列向量。
4、一般情况下,为了描述准备和表达合理,我们不会把向量同时用逆变和协变形式表示,要不然是逆变向量,要不然是协变向量,不会混在一起。
5、协变向量一般被理解为函数(比如一个三维空间到一维空间的线性变换),而不是一个空间中的箭头。
6、协变向量一般会使用对偶基向量表示,而不是这个例子中所使用的通常的基向量。
总结
本周继续学习了GRU,下周我将对seq2seq进行深入学习。