1.视频网站:mooc慕课https://mooc.study.163.com/university/deeplearning_ai#/c
2.详细笔记网站(中文):http://www.ai-start.com/dl2017/
3.github课件+作业+答案:https://github.com/stormstone/deeplearning.ai
1.10 长短期记忆(LSTM) LSTM (long short term memory) unit
在上节课中你已经学了GRU(门控循环单元)。它能够让你可以在序列中学习非常深的连接。其他类型的单元也可以让你做到这个,比如LSTM即长短时记忆网络,甚至比GRU更加有效,让我们看看。
上图是上节课中的式子,对于GRU我们有 a < t > = c < t > a^{<t>}=c^{<t>} a<t>=c<t>。
还有两个门:
- 更新门 Γ u \Gamma_u Γu(the update gate)
- 相关门 Γ r \Gamma_r Γr(the relevance gate)
c ~ < t > \tilde c^{<t>} c~<t>,这是代替记忆细胞的候选值,然后我们使用更新门 Γ u \Gamma_u Γu来决定是否要用 c ~ < t > \tilde c^{<t>} c~<t> 更新 c < t > c^{<t>} c<t>(公式4)。
LSTM是一个比GRU更加强大和通用的版本,这多亏了 Sepp Hochreiter和 Jurgen Schmidhuber,感谢那篇开创性的论文,它在序列模型上有着巨大影响。我感觉这篇论文是挺难读懂的,虽然我认为这篇论文在DL社群有着重大的影响,它深入讨论了梯度消失的理论,我感觉大部分的人学到LSTM的细节是在其他的地方,而不是这篇论文。
这就是LSTM主要的式子,我们继续回到记忆细胞
c
c
c上面来。
使用
c
~
<
t
>
=
t
a
n
h
(
W
c
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
c
)
\tilde c^{<t>}=tanh(W_c[a^{<t-1>},x^{<t>}]+b_c)
c~<t>=tanh(Wc[a<t−1>,x<t>]+bc)来更新它的候选值
c
~
<
t
>
\tilde c^{<t>}
c~<t>。
注意了,在LSTM中我们不再有
a
<
t
>
=
c
<
t
>
a^{<t>}=c^{<t>}
a<t>=c<t>的情况,上图右边现在我们用的是类似于GRU的公式,但是有一些改变。现在我们专门使用
a
<
t
>
a^{<t>}
a<t>或者
a
<
t
−
1
>
a^{<t-1>}
a<t−1>,而不是用
c
<
t
−
1
>
c^{<t-1>}
c<t−1>,我们也不用
Γ
r
\Gamma_r
Γr,即相关门。虽然你可以使用LSTM的变体,然后把GRU公式公式中的这些东西都放回来,但是在更加典型的LSTM里面,我们先不那样做。
我们像以前那样有一个更新门
Γ
u
\Gamma_u
Γu和表示更新的参数
W
u
W_u
Wu,
Γ
u
=
σ
(
W
u
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
u
)
\Gamma_u=\sigma(W_u[a^{<t-1>},x^{<t>}]+b_u)
Γu=σ(Wu[a<t−1>,x<t>]+bu)
一个LSTM的新特性是不只有一个更新门控制,
Γ
r
\Gamma_r
Γr和
1
−
Γ
r
1-\Gamma_r
1−Γr这两项,我们将用不同的项来代替它们,这里我们用遗忘门(the forget gate),我们叫它
Γ
f
\Gamma_f
Γf,
Γ
f
=
σ
(
W
f
[
a
<
t
−
1
>
,
x
<
t
>
]
+
b
f
)
\Gamma_f=\sigma(W_f[a^{<t-1>},x^{<t>}]+b_f)
Γf=σ(Wf[a<t−1>,x<t>]+bf)
然后我们有一个新的sigmod输出门
Γ
o
\Gamma_o
Γo,
Γ
o
=
σ
(
W
o
[
a
<
t
−
1
>
,
x
<
t
>
]
)
+
b
o
\Gamma_o=\sigma(W_o[a^{<t-1>},x^{<t>}])+b_o
Γo=σ(Wo[a<t−1>,x<t>])+bo
于是记忆细胞的更新值
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>
所以这给了记忆细胞选择权去维持旧的值
c
<
t
−
1
>
c^{<t-1>}
c<t−1>或者就加上新的值
c
~
<
t
>
\tilde c^{<t>}
c~<t>,所以这里用了单独的更新门
Γ
u
\Gamma_u
Γu和遗忘门
Γ
f
\Gamma_f
Γf。
- Γ u \Gamma_u Γu表示更新门,update
- Γ f \Gamma_f Γf表示遗忘门,forgot
- Γ o \Gamma_o Γo表示输出门,output
最后的
a
<
t
>
a^{<t>}
a<t>公式会变成
a
t
=
Γ
o
∗
c
<
t
>
a^{t}=\Gamma_o * c^{<t>}
at=Γo∗c<t>
以上这就是LSTM主要的公式了,然后LSTM这里有三个门而不是两个,这有点复杂,它把门放到了和之前有点不同的地方。
再提一下,上图这些公式就是控制LSTM行为的主要的公式。
像之前一样用图片稍微解释一下,先让我把图画在上面。
如果图片过于复杂,别担心,我个人感觉式子比图片好理解,我画图只是因为它比较直观。这个图的灵感来自于Chris Ola的一篇博客,标题是《理解LSTM网络》(Understanding LSTM Network),这里的这张图跟他博客上的图是很相似的,但关键的不同可能是这里的这张图用了
a
<
t
−
1
>
a^{<t-1>}
a<t−1>和
x
<
t
>
x^{<t>}
x<t>来计算所有门值。
在这张图里是用
a
<
t
−
1
>
a^{<t-1>}
a<t−1>,
x
<
t
>
x^{<t>}
x<t>一起来计算遗忘门
Γ
f
\Gamma_f
Γf的值,还有更新门
Γ
u
\Gamma_u
Γu以及输出门
Γ
o
\Gamma_o
Γo。然后它们也经过tanh函数来计算
c
~
<
t
>
\tilde c^{<t>}
c~<t>,这些值被用复杂的方式组合在一起,比如说元素对应的乘积或者其他的方式来从之前的
c
<
t
−
1
>
c^{<t-1>}
c<t−1>中获得
c
<
t
>
c^{<t>}
c<t>。
这里其中一个元素很有意思,如你在这上面的一堆图中看到的,如果把它们按时间次序连起来,例如:左边第一个图输出了上一个时间的 a < 1 > a^{<1>} a<1>, a < 1 > a^{<1>} a<1>会作为下一个时间步的输入, c c c也是同理。
在这里我把图简化了一下。然后这有个有意思的事情,你会注意到上面这里有条线(上图中的红色线),这条线显示了只要你正确地设置了遗忘门和更新门,LSTM是相当容易把 c < 0 > c^{<0>} c<0>的值一直往下传递到右边,比如 c < 3 > = c < 0 > c^{<3>}=c^{<0>} c<3>=c<0>。
这就是为什么LSTM和GRU非常擅长于长时间记忆某个值,对于存在记忆细胞中的某个值,即使经过很长很长的时间步。
这就是LSTM,你可能会想到这里和一般使用的版本会有些不同,最常用的版本可能是门值不仅取决于 a < t − 1 > a^{<t-1>} a<t−1>和 x < t > x^{<t>} x<t>,有时候也可以偷窥一下 c < t − 1 > c^{<t-1>} c<t−1>的值,这叫做“窥视孔连接”(peephole connection)。虽然不是个好听的名字,但是你想,“偷窥孔连接”其实意思就是门值不仅取决于 a < t − 1 > a^{<t-1>} a<t−1>和 x < t > x^{<t>} x<t>,也取决于上一个记忆细胞的值( c < t − 1 > c^{<t-1>} c<t−1>),然后“偷窥孔连接”就可以结合这三个门( Γ u \Gamma_u Γu、 Γ f \Gamma_f Γf、 Γ o \Gamma_o Γo)来计算了。
如你所见LSTM主要的区别在于一个技术上的细节,比如 c < t − 1 > c^{<t-1>} c<t−1>有一个100维的向量,你有一个100维的隐藏的记忆细胞单元,然后比如第50个 c < t − 1 > c^{<t-1>} c<t−1>的元素只会影响第50个元素对应的那个门,所以关系是一对一的,于是并不是任意这100维的 c < t − 1 > c^{<t-1>} c<t−1>可以影响所有的门元素。相反的,第一个 c < t − 1 > c^{<t-1>} c<t−1>的元素只能影响门的第一个元素,第二个元素影响对应的第二个元素,如此类推。但如果你读过论文,见人讨论“偷窥孔连接”,那就是在说 c < t − 1 > c^{<t-1>} c<t−1>也能影响门值。
总结
这就是LSTM,我们什么时候应该用GRU?什么时候用LSTM?
这里没有统一的准则。而且即使我先讲解了GRU,在DL的历史上,LSTM也是更早出现的,而GRU是最近才发明出来的,它可能源于Pavia在更加复杂的LSTM模型中做出的简化。研究者们在很多不同问题上尝试了这两种模型,看看在不同的问题不同的算法中哪个模型更好,所以这不是个学术和高深的算法,我才想要把这两个模型展示给你。
GRU的优点是这是个更加简单的模型,所以更容易创建一个更大的网络,而且它只有两个门,在计算性上也运行得更快,然后它可以扩大模型的规模。
但是LSTM更加强大和灵活,因为它有三个门而不是两个。如果你想选一个使用,我认为LSTM在历史进程上是个更优先的选择,所以如果你必须选一个,我感觉今天大部分的人还是会把LSTM作为默认的选择来尝试。虽然我认为最近几年GRU获得了很多支持,而且我感觉越来越多的团队也正在使用GRU,因为它更加简单,而且还效果还不错,它更容易适应规模更加大的问题。
所以这就是LSTM,无论是GRU还是LSTM,你都可以用它们来构建捕获更加深层连接的神经网络。