目录
一、为什么使用序列模型(Why sequence models)
三、循环神经网络(Recurrent neural network)
四、通过时间的反向传播(Backpropagation through time)
五、不同类型的循环神经网络(Different types of RNNs)
六、语言模型和序列生成(Language model and sequence generation)
七、对新序列的采样(Sampling novel sequences)
八、循环神经网络的梯度消失(Vanishing gradients with RNNs)
十、LSTM(long short term memory)
一、为什么使用序列模型(Why sequence models)
输入和输出是序列,使用序列模型。应用很广泛,如下图:
二、数学符号(Notation)
尖括号表示序列中的词的位置编号,圆括号表示第i个样本。两种括号一起使用,表示第i个样本的位置t的词。
单词的表示方法:在词典中出现的位置编号,用one-hot编码。
三、循环神经网络(Recurrent neural network)
为什么不使用普通的神经网络处理句子等NLP问题?
有两个原因:
1、句子的长短是不一致的,即输入层的向量维度是不固定的。如果以最长的为准,其余的补零,也不是一种好方法。
2、没有在整个文本中共享信息。(类似CNN中权值共享的思想)
RNN的图示:
单向的RNN只与前面的词有关系,双向的RNN是与前后的词均有关系。
前向传播的公式:
为了表示方便,把和合写成。
四、通过时间的反向传播(Backpropagation through time)
反向传播过程:从右到左的计算,类似“穿越时空”,“时光倒流”。
一个元素上的损失函数:
整个序列的损失函数
五、不同类型的循环神经网络(Different types of RNNs)
在解决上述不同的场景时,需要用到不同的RNN结构。
如下图,有一对一、一对多、多对一、多对多(输入与输出等长)、多对多(输入与输出不等长)等。
六、语言模型和序列生成(Language model and sequence generation)
语言模型:一句话出现的概率。
比如你在做一个语音识别系统,你听到一个句子,“the apple and pear(pair)salad was delicious.”,所以我究竟说了什么?我说的是“the apple and pair salad”,还是“the apple and pear salad”?(pear和pair是近音词)。你可能觉得我说的应该更像第二种,事实上,这就是一个好的语音识别系统要帮助输出的东西,即使这两句话听起来是如此相似。而让语音识别系统去选择第二个句子的方法就是使用一个语言模型,他能计算出这两句话各自的可能性。
举个例子,一个语音识别模型可能算出第一句话的概率是:
而第二句话的概率是
比较这两个概率值,显然我说的话更像是第二种,因为第二句话的概率比第一句高出1000倍以上,这就是为什么语音识别系统能够在这两句话中作出选择。
使用RNN建立语言模型:
句尾要添加<EOS>。(常宝宝老师课上提到过,加EOS是为了防止概率和不归一)
七、对新序列的采样(Sampling novel sequences)
八、循环神经网络的梯度消失(Vanishing gradients with RNNs)
基本的RNN算法还有一个很大的问题,就是梯度消失的问题。
你已经知道了RNN的样子,现在我们举个语言模型的例子,假如看到这个句子(上图编号1所示),“The cat, which already ate ……, was full.”,前后应该保持一致,因为cat是单数,所以应该用was。“The cats, which ate ……, were full.”(上图编号2所示),cats是复数,所以用were。这个例子中的句子有长期的依赖,最前面的单词对句子后面的单词有影响。但是我们目前见到的基本的RNN模型(上图编号3所示的网络模型),不擅长捕获这种长期依赖效应,解释一下为什么。
你应该还记得之前讨论的训练很深的网络,我们讨论了梯度消失的问题。比如说一个很深很深的网络(上图编号4所示),100层,甚至更深,对这个网络从左到右做前向传播然后再反向传播。我们知道如果这是个很深的神经网络,从输出得到的梯度很难传播回去,很难影响靠前层的权重,很难影响前面层(编号5所示的层)的计算。
对于有同样问题的RNN,首先从左到右前向传播,然后反向传播。但是反向传播会很困难,因为同样的梯度消失的问题,后面层的输出误差(上图编号6所示)很难影响前面层(上图编号7所示的层)的计算。这就意味着,实际上很难让一个神经网络能够意识到它要记住看到的是单数名词还是复数名词,然后在序列后面生成依赖单复数形式的was或者were。而且在英语里面,这中间的内容(上图编号8所示)可以任意长,对吧?所以你需要长时间记住单词是单数还是复数,这样后面的句子才能用到这些信息。也正是这个原因,所以基本的RNN模型会有很多局部影响,意味着这个输出(上图编号9所示)主要受附近的值(上图编号10所示)的影响,上图编号11所示的一个数值主要与附近的输入(上图编号12所示)有关,上图编号6所示的输出,基本上很难受到序列靠前的输入(上图编号10所示)的影响,这是因为不管输出是什么,不管是对的,还是错的,这个区域都很难反向传播到序列的前面部分,也因此网络很难调整序列前面的计算。这是基本的RNN算法的一个缺点,我们会在下几节视频里处理这个问题。如果不管的话,RNN会不擅长处理长期依赖的问题。
尽管我们一直在讨论梯度消失问题,但是,你应该记得我们在讲很深的神经网络时,我们也提到了梯度爆炸,我们在反向传播的时候,随着层数的增多,梯度不仅可能指数型的下降,也可能指数型的上升。事实上梯度消失在训练RNN时是首要的问题,尽管梯度爆炸也是会出现,但是梯度爆炸很明显,因为指数级大的梯度会让你的参数变得极其大,以至于你的网络参数崩溃。所以梯度爆炸很容易发现,因为参数会大到崩溃,你会看到很多NaN,或者不是数字的情况,这意味着你的网络计算出现了数值溢出。如果你发现了梯度爆炸的问题,一个解决方法就是用梯度修剪。梯度修剪的意思就是观察你的梯度向量,如果它大于某个阈值,缩放梯度向量,保证它不会太大,这就是通过一些最大值来修剪的方法。所以如果你遇到了梯度爆炸,如果导数值很大,或者出现了NaN,就用梯度修剪,这是相对比较鲁棒的,这是梯度爆炸的解决方法。
梯度爆炸基本上用梯度修剪就可以应对,但梯度消失比较棘手。我们下节会介绍GRU,门控循环单元网络,这个网络可以有效地解决梯度消失的问题,并且能够使你的神经网络捕获更长的长期依赖。
九、GRU(Gated Recurrent Unit)
吴恩达提到的,最早提出GRU结构的两篇论文。
(Chung J, Gulcehre C, Cho K H, et al. Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling[J]. Eprint Arxiv, 2014.
Cho K, Merrienboer B V, Bahdanau D, et al. On the Properties of Neural Machine Translation: Encoder-Decoder Approaches[J]. Computer Science, 2014.)
十、LSTM(long short term memory)
LSTM前向传播图:
论文
(Hochreiter S, Schmidhuber J. Long Short-Term Memory[J]. Neural Computation, 1997, 9(8):1735-1780.)
十一、双向RNN(Bidirectional RNN)
十二、深层循环神经网络(Deep RNNs)
普通的深层神经网络,可以达到100层,但是RNN不会那么多层。因为RNN有横向的时间轴上的传递,所以结构较复杂,一般三层就是比较深的了。可以在几层RNN后面,连接普通的神经网络,不再进行横向时间轴上的传递,这也是比较常见的一种方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:吴恩达深度学习笔记——循环神经网络(RNN) - Python技术站