注意:本篇是RNN的内容补充,关于RNN模型和BPTT可回顾:pytorch笔记本-第五课.语言模型
朴素RNN与LSTM
从NN到RNN
严格来说,全连接网络与卷积网络不适合对序列型数据进行建模,NN(Neural Networks)与ConvNN总是习惯将一个片段作为一个整体处理,没有考虑该片段以前的历史信息。因此提出循环神经网络 Recurrent neural network,最早的RNN又被称为朴素RNN,它没有LSTM或GRU中的各种复杂门结构,但已经具备对于序列信息的感知能力。
从NN与ConvNN到RNN,可以理解为 one to one 模型到 many to one 模型的迁移:
RNN结构
朴素RNN的结构如下:
输入信息
x
x
x是经过embedding映射后的词向量,
h
h
h是RNN输出的隐藏信息,参数
A
A
A是RNN参数的集中表示,RNN每一步的参数
A
A
A都是同一个参数(参数共享),上图的朴素RNN中,其信息走向可以具体描述为下图:
如果从张量计算角度看,每一步的计算为:
根据 pytorch笔记本-第五课.语言模型 中的描述,RNN每一步的计算描述为:
h
t
=
t
a
n
h
(
W
h
h
h
t
−
1
+
W
h
x
x
t
)
h_{t}=tanh(W_{hh}h_{t-1}+W_{hx}x_{t})
ht=tanh(Whhht−1+Whxxt)现在更普遍的做法是用向量的拼接代替向量相加,目的是保留特征的更多信息,所以按照上图,RNN的每一步计算通常为:
h
t
=
t
a
n
h
(
A
[
c
o
n
c
a
t
(
h
t
−
1
,
x
t
)
]
)
h_{t}=tanh(A[concat(h_{t-1},x_{t})])
ht=tanh(A[concat(ht−1,xt)])因此,参数
A
A
A可视为
W
h
h
W_{hh}
Whh和
W
h
x
W_{hx}
Whx的拼接。
我们通常使用 t a n h tanh tanh作为激活函数,这有利于在每一次计算时,对输出进行适当的归一化,限制值的范围。
RNN虽然在每一步计算中考虑了历史信息,但实验表明,RNN容易遗忘早期历史信息,即RNN只对近期历史信息敏感,以语言模型为例,我们可以在近期信息基础上得到一个合理的词语预测结果:
sky 相对于 clouds,are 距离较近并有关联,因此根据历史信息
h
2
h_{2}
h2和输入
x
3
x_{3}
x3可以较容易地从词汇表中分类出单词 sky;
但是考虑一种情况,如果某个目标分类词语和其相关词语距离很远,由于RNN在信息传递过程中会遗忘早期历史信息,因此到目标分类的位置处,模型没有合理的输入信息,从而无法自信得到分类结果,即加大了错误分类的可能性:
如果通过实验观察该现象,可以发现梯度值有很多如下的状况:
∂
h
100
∂
x
0
≈
0
,
∂
h
101
∂
x
0
≈
0
,
∂
h
102
∂
x
6
≈
0
\frac{\partial h_{100}}{\partial x_{0}}\approx 0,\frac{\partial h_{101}}{\partial x_{0}}\approx 0,\frac{\partial h_{102}}{\partial x_{6}}\approx 0
∂x0∂h100≈0,∂x0∂h101≈0,∂x6∂h102≈0
即梯度消失问题,梯度消失问题正是RNN容易遗忘早期历史信息的体现。
LSTM
为了增加RNN对于早期历史信息的记忆能力,提出LSTM(Long Short-Term Memory),缓解梯度消失问题。LSTM与朴素RNN的输入输出一样,但内部结构有所区别:
LSTM主要包含4个部分:
- 传输带 convey belt,传输带是避免梯度消失的主要改进措施,因为传输带确保信息直接在序列中流动,降低了被线性或非线性变换处理后信息失真的风险:
- 遗忘门,用于生成向量
f
t
f_{t}
ft,每个值都在0到1之间,代表容许传输带中信息的对应位置的元素被记住的概率,0代表完全遗忘,1代表完全记住;可学习参数为
W
f
W_{f}
Wf:
- 输入门,生成的向量
i
t
i_{t}
it的每个元素都在0到1之间,决定对于输入信息的接受程度,即对传输带上新增信息
C
~
t
\widetilde{C}_{t}
C
t的更新程度;
C
~
t
\widetilde{C}_{t}
C
t为经过变换的输入信息,它是传输带上的新增信息来源;
其中,向量 i t i_{t} it和 C ~ t \widetilde{C}_{t} C t的计算过程如下,可学习参数为 W i W_{i} Wi和 W c W_{c} Wc:
补充部分:信息的更新
传输带上信息
C
t
C_{t}
Ct的更新如下:
C
t
=
f
t
⊗
C
t
−
1
+
i
t
⊗
C
~
t
C_{t}=f_{t}\otimes C_{t-1}+i_{t}\otimes\widetilde{C}_{t}
Ct=ft⊗Ct−1+it⊗C
t其中,
⊗
\otimes
⊗代表向量的逐元素相乘,
f
t
f_{t}
ft为遗忘门的输出向量,
i
t
i_{t}
it与
C
~
t
\widetilde{C}_{t}
C
t来自输入门。
- 输出门,向量
o
t
o_{t}
ot决定了接收传输带信息
C
t
C_{t}
Ct到输出隐藏信息
h
t
h_{t}
ht的程度,两个向量的计算过程如下(注意,LSTM的每一步输出为
h
t
h_{t}
ht和
C
t
C_{t}
Ct),可学习参数为
W
o
W_{o}
Wo:
对于一层LSTM而言,每个计算单元(由传输带,遗忘门,输入门,输出门组成)的参数都是共享的,每层LSTM学习的参数即为 ( W f , W i , W c , W o ) (W_{f},W_{i},W_{c},W_{o}) (Wf,Wi,Wc,Wo)。
LSTM由于引入传输带的设计,加强了信息的传输,改善了RNN难以长期记忆的问题,从而在一定程度上缓解了梯度消失。
RNN的扩展模型
多层RNN
我们可以将RNN堆叠,构造多层RNN模型(Stacked RNN),多层的信息变换,可以加强特征提取的性能,从而获取更深层的隐藏空间下的信息表达;
多层RNN的结构如下:
上面模型的可学习参数为
(
A
,
A
′
,
A
′
′
)
(A,A^{'},A^{''})
(A,A′,A′′)。
同理,我们也可以堆叠LSTM,构成多层LSTM。
双向RNN
在最开始谈到的朴素RNN中,我们已经知道,RNN难以保留长期记忆信息,为了处理该问题,研究者提出LSTM利用传输带结构加强记忆的传输;另一种方式是双向RNN结构(Bidirectional RNN),双向RNN在长期和短期记忆信息上实现了信息的互相补充。
双向RNN结构如下:
对于双向RNN在隐藏信息的传输过程中,
h
h
h和
h
′
h^{'}
h′之间是互不干扰的关系,即双向RNN本质是两个独立的RNN,只是序列的计算顺序相反;
当处理模型的输出表达时,我们则需要利用两部分信息 h h h和 h ′ h^{'} h′,假设对于序列沿着正向的第 t t t步,模型输出为向量 h t h_{t} ht和 h t ′ h^{'}_{t} ht′的拼接: c o n c a t [ h t , h t ′ ] concat[h_{t},h^{'}_{t}] concat[ht,ht′]可见,双向RNN输出的信息包含了短期记忆和长期记忆,因此双向RNN具有比朴素RNN更好的表现,但可学习参数新增加了一个张量 A ′ A^{'} A′。
递归网络Recursive Network
Recursive Network是比RNN更广义的神经网络,RNN是按照时序维度展开,而Recursive Network是按照图结构(空间维度)展开。
以情感分析为背景,RNN接收输入为词序列的 word embedding,经过相同的 function-f 处理后,由 function-g 计算得到情感分类结果:
对于Recursive Network,不根据时间顺序进行计算,而是将词序列根据句法结构展开为句法树(也称为Recursive Structure),句法结构的解析可以看成输入递归神经网络前的数据预处理操作,在句法树的节点上布设同一个神经网络构成递归神经网络Recursive Network:
注意,词向量和隐状态向量的维度应该相同,因为使用的总是同一个 function-f;神经网络 function-f 的堆叠方式取决于句子的Recursive Structure;另外,我们也能够看出,循环神经网络其实是递归神经网络的一个子集。
假设有一个短句子:“not very good”
根据句法将其解析为以下树结构:
应用递归神经网络得到:
对于递归神经网络的学习,像RNN一样,也是BPTT,只是此时的反向传播不是按照时间序列进行,而是按照树结构进行。
下面了解 function-f 的具体形式,以两个向量的输入方式为例:
输入
a
a
a和
b
b
b向量,输出
p
p
p向量:
p
=
s
i
g
m
o
i
d
(
W
⋅
C
o
n
c
a
t
(
a
,
b
)
)
p=sigmoid(W\cdot Concat(a,b))
p=sigmoid(W⋅Concat(a,b))其中,
W
W
W为可学习参数。