序列模型
对于序列学习问题如果我们使用标准的神经网络,则会有一些问题
- 输入和输出在不同的例子中有不同的长度,即使定义最大长度后补零也效果可能会比较差
- 对于NLP等领域的问题时,输入的维度过大,导致参数过多,神经网络不好训练
序列模型可以很好的帮助我们解决这些问题
RNN(recurrent neural network)
对于RNN而言,在前面的时间步的信息会影响到后面的结果。我们可以先初始化一个零向量
a
<
0
>
a^{<0>}
a<0>和
x
<
1
>
x^{<1>}
x<1>一起决定第一个时间步的输出
y
^
<
1
>
\hat{y}^{<1>}
y^<1>,
a
<
1
>
a^{<1>}
a<1>和
x
<
2
>
x^{<2>}
x<2>一起决定第二个时间步的输出,以此类推。我们用
𝑊
a
x
𝑊_{ax}
Wax来表示管理着从
𝑥
<
1
>
𝑥^{<1>}
x<1>到隐藏层的连接的一系列参数,每个时间步使用的都是相同的参数
𝑊
a
x
𝑊_{ax}
Wax。而激活值也就是水平联系是由参数
𝑊
𝑎
𝑎
𝑊_{𝑎𝑎}
Waa决定的,同时每一个时间步都使用相同的参数
𝑊
𝑎
𝑎
𝑊_{𝑎𝑎}
Waa,同样的输出结果由
𝑊
y
a
𝑊_{ya}
Wya决定。
a
<
1
>
=
g
1
(
W
a
a
a
<
0
>
+
W
a
x
x
<
1
>
+
b
a
)
y
^
<
1
>
=
g
2
(
W
y
a
a
<
1
>
+
b
y
)
\begin{gathered} a^{<1>}=g_{1}\left(W_{a a} a^{<0>}+W_{a x} x^{<1>}+b_{a}\right) \\ \hat{y}^{<1>}=g_{2}\left(W_{y a} a^{<1>}+b_{y}\right) \end{gathered}
a<1>=g1(Waaa<0>+Waxx<1>+ba)y^<1>=g2(Wyaa<1>+by)
a
i
和
y
^
<
i
>
a^i和\hat{y}^{<i>}
ai和y^<i>的具体计算可以由上面的公式得出,g表示激活函数(RNN的激活函数通常的tanh)。下图则更加清晰的画出了RNN的框图结构。
单向的RNN在当前的时间步只能够获得左端时间步的信息,但是有时候后面的信息也有助于模型的训练,比如下面这个例子。
这时候我们就可以使用双向RNN(Bidirectional RNN)。
除了单层模型,我们还可以有多层的RNN模型
对于RNN而言,这类模型也面临着一些问题,比如说梯度消失的问题,导致RNN不擅长处理长期依赖相关的问题。
LSTM(long short term memory)
相比于RNN, LSTM在处理长期依赖相关的问题往往能够有更好的结果。
对于LSTM的每一个cell而言,有三个门
更新门(update gate)
Γ
u
=
σ
(
W
u
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
u
)
\Gamma_{u}=\sigma\left(W_{u}\left[a^{<t-1>}, x^{<t>}\right]+b_{u}\right)
Γu=σ(Wu[a<t−1>,x<t>]+bu)
输出门(output gate)
Γ
o
=
σ
(
W
o
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
o
)
\Gamma_{o}=\sigma\left(W_{o}\left[a^{<t-1>}, x^{<t>}\right]+b_{o}\right)
Γo=σ(Wo[a<t−1>,x<t>]+bo)
遗忘门(forget gate)
Γ
f
=
σ
(
W
f
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
f
)
\Gamma_{f}=\sigma\left(W_{f}\left[a^{<t-1>}, x^{<t>}\right]+b_{f}\right)
Γf=σ(Wf[a<t−1>,x<t>]+bf)
对于记忆细胞而言,它能够自己选择维持旧的c值还是用新的c值
c
<
t
>
=
Γ
u
∗
c
~
<
t
>
+
Γ
f
∗
c
<
t
−
1
>
c^{<t>}=\Gamma_{u} * \tilde{c}^{<t>}+\Gamma_{f} * c^{<t-1>}
c<t>=Γu∗c~<t>+Γf∗c<t−1>
如果使用LSTM我们能够更加容易让即使很长时间之前的信息也能够被保存。
参考资料:
① : 吴恩达深度学习deeplearning.ai