nlp学习笔记(二)- Seq2seq

nlp中最常见的基本单元:RNN,SLTM,GRU。

一、RNN(Recurrent Neural Network),nlp往往是一种序列问题,在计算时需要后面的单元记住前面一些单元的信息,所以前人发明了一种递归神经网络来替换传统神经网络。就是把神经元的一些变量传到下一个神经元。如下图:

与传统神经网络不同,递归神经网络可以实现参数共享:

左边传统神经网络,右边RNN结构网络

双向RNN(Bidirectional RNNs)结构:

Forward RNN得到的状态变量: \rightarrow_{h^{(t)}}=RNN_{FW}(\rightarrow_{h^{(t-1)}},x^{(t)}) ,Backword RNN得到的状态变量: \leftarrow_{h^{(t)}}=RNN_{BW}(\leftarrow_{h^{(t+1)}},x^{(t)}) ,最终的hidden state为两个连接的结果 h^{(t)}=\left[ \rightarrow_{h^{(t)}};\leftarrow_{h^{(t)}} \right]

Deep RNNs:多层RNN叠加,机器翻译可能会用到这种结构。神经网络机器翻译一般使用2~4层效果会比较好。文本摘要使用的话容易导致过拟合。

训练过程常见问题 梯度爆炸和梯度消失(Exploding and Vanishing Gradient Problem):

损失函数求导过程

根据链式法则,损失函数求导过程需要每一步导数连乘。如果导数梯度特别小,连乘之后非常非常小,移动步数太小,很难达到最优值的现象叫梯度消失;如果梯度特别大,连乘之后非常大,移动步数太大,在最优值前后来回震荡的现象叫梯度爆炸。这种现象是sigmoid激活函数的特性造成的。如下图示,当x<-3或x>3时,梯度几乎为0了。相同的激活函数条件下,层数越多,越易出现。

sigmoid激活函数

梯度爆炸的解决方法:gradient clipping 梯度削减,设置阈值来阻止梯度过大。当 \left|\left| g \right|\right|>thresholdg\leftarrow \frac{threshold\times g}{\left| \left| g \right| \right|}

梯度消失解决方法:

1.Identity Initialization 更换激活函数为relu;

2.使用LSTM,使用单元结构削弱梯度消失问题;

3.残差网络(Residual Networks);

4.Batch Normalization 将输入归一化,将取值范围缩小,归一到绿色区域,减少梯度消失。

二、LSTM(Long Short Term Memory),与RNN对比图:

前面讲到的RNN结构
SLTM结构

LSTM中引入了三个门:输入门(input gate)、遗忘门(forget gate)和输出门(output gate),以及与隐藏状态相同的记忆细胞。

forget gate

遗忘门 f_t=\sigma(w_f\left[h_{t-1};x_t\right]+b_f)

input gate

输入门 i_t=\sigma(w_i\left[ h_{t-1};x_t \right]+b_i) ,候选记忆细胞 \tilde{C_t}=tanh(w_c\left[ h_{t-1};x_t \right]+b_c)

记忆细胞

记忆细胞 C_t=f_t\times C_{t-1}+i_t\times \tilde{C_t}

output gate

输出门 o_t=\sigma(w_o\left[ h_{t-1};x_t \right]+b_o) ,有了记忆细胞,我们还可以通过输出门来控制从记忆细胞到隐藏状态 h_t 的信息流动 h_t=o_t\times tanh(C_t) 。这里的tanh函数确保隐藏状态元素值在-1~1之间。需要注意:当输出门近似1时,记忆细胞信息将传递到隐藏状态供输出层使用;当输出门近似0时,记忆细胞信息只自己保留。

三、GRU(gated recurrent unit)门控循环单元

GRU结构

GRU中的重置门(reset gate)和更新门(update gate)的输入均为当前时间步输入 x_t与上一时间步隐藏状态 h_{t-1},输出由激活函数为sigmoid函数的全连接层计算得到 。

重置门 r_t=\sigma(w_r\left[ h_{t-1};x_t \right]) ,更新门 z_t=\sigma(w_z\left[ h_{t-1};x_t \right]) ,候选隐藏状态 \tilde{h_t}=tanh(w\left[ r_t\times h_{t-1};x_t \right]+b),隐藏状态 h_t=(1-z_t)\times h_{t-1}+z_t\times \tilde{h_t}

SLTM与GRU总结:1.GRU参数少一些,计算更快;2.LSTM参数多记录的信息也更多,一般也作为缺省选择,但需要更多的训练数据来解决参数过多造成的过拟合问题;3.可以采用比较讨巧的方式,先使用LSTM,之后再切换为GRU。

Seq2Seq(Encoder-Decoder结构)

Encoder-Decoder结构

上图描述了机器对话的一种方法。Encoder每个时间步的输入依次为英语句子中的单词、标点,使用了Encoder在最终时间步的隐藏状态作为输入句子的表征或编码信息。Decoder在各个时间步中使用输入句子的编码信息和上个时间步的输出以及隐藏状态作为输入。

Attention机制

使用Encoder-Decoder结构将句子由英语翻译成法语

Decoder在生成输出序列中的每一个词时可能只需要利用输入序列某一部分的信息。Attention机制通过对Encoder所有时间步的隐藏状态做加权平均来得到背景向量。Decoder在每一时间步调整这些权重,及注意力权重,从而能够在不同的时间步分别关注输入序列中的不同部分并编码进相应时间步的背景向量。

计算背景向量(context vector):首先,通过一个函数根据Decoder在时间步1的隐藏状态和Encoder在各个时间步的隐藏状态计算softmax运算的输入,softmax运算输出概率分布并对Encoder各个时间步的隐藏状态做加权平均,从而得到context vector。在Attention机制中,Decoder的每一时间步将使用可变的context vector,这样便能够更新隐藏状态。

Seq2Seq训练

cross-entropy loss交叉熵:预测一个词的交叉熵函数 D(S,L)=-\sum_{i}{L_ilog(S_i)} ,S为预测词,L为真实的标签。完整句子的损失函数 J=-\frac{1}{N}(\sum_{i=1}^{N}{y_ilog(\hat{y_i}})) 。二分类问题的损失函数 J(w)=-\frac{1}{N}\sum_{n=1}^N\left[ y_nlog\hat{y_n}+(1-y_n)log(1-\hat{y_n}) \right]

Teacher Forcing:RNN模型是用前一步的输出作为输入,Teacher Forcing是忽略前一步的输出,使用真实的标签作为输入。这种方法只能在训练过程使用,能够解决收敛速度慢和不稳定的问题。缺点是使模型更脆弱。解决方法:1.使用beam search集束搜索来获取更多序列组合来提高准确度;2.Curriculum Learning课程学习,设置概率选择使用预测值和真实标签来实现学习效果。

编辑于 2020-03-12 23:04