Why sequence models?:序列数据例子,如下图:(1).语音识别(speech recognition):给定一个输入音频片段X,并要求输出片段对应的文字记录Y,这里输入和输出都是序列数据(sequence data)。因为X是按时序播放的音频片段,输出Y是一系列单词。(2). 音乐生成(music generation):只有输出数据Y是序列;输入数据可以是空集,也可以是单一的整数,这个数可能指代你想要生成的音乐风格,也可能是你想要生成的那首曲子的头几个音符。无论怎样,输入X可以是空的或者就是某个数字,然输入Y是一个序列。(3). 情感分类(sentiment classification):输入数据X是序列。(4). DNA序列分析(DNA sequence analysis);(5). 机器翻译(machine translation);(6).视频行为识别(video activity recognition);(7). 命名实体识别(name entity recognition):可能会给出一个句子,要求识别出句中的人名。所有这些问题都可以被称作使用标签数据(X,Y)作为训练集的监督学习。序列问题可以有很多不同的类型,有些问题里输入X和输出数据Y都是序列,但是X和Y有时也会有不一样的长度。在一些问题里,只有X或Y是序列。

吴恩达老师深度学习视频课笔记:循环神经网络

符号(Notation):使用x<t>来索引序列中的位置,t意味着它们是时序序列;使用Tx来表示输入序列的长度;使用Ty来表示输出序列的长度;Tx和Ty可以有不同的长度;x(i)<t>来表示训练样本i的输入序列中第t个元素;Tx(i)来表示第i个训练样本的输入序列长度;y(i)<t>来表示训练样本i的输出序列中第t个元素;Ty(i)来表示第i个训练样本的输出序列长度。

自然语言处理(Natural Language Processing, NLP)怎样表示一个序列里单独的单词,如下图:想要表示一个句子里的单词,第一件事是做一张词表,有时也称为词典(dictionary),意思是列一列你的表示方法中要用到的单词,如第一个单词是a,第二个单词是aaron,等等,用了10000个单词大小的词典。一般常见的词典大小为30000到50000,有的也会用百万词典。接下来你可以用one-hot表示法来表示词典里的每个单词,x<t>指代句子里的任意词,它就是个one-hot向量,是因为只有一个值是1,其余值都是0。

吴恩达老师深度学习视频课笔记:循环神经网络

循环神经网络模型:命名实体识别不能使用标准神经网络的原因:(1). 输入和输出数据在不同例子中可以有不同的长度;(2). 一个单纯的神经网络结构并不共享从文本的不同位置上学到的特征。而循环神经网络针对序列数据就没有以上两个缺点。

循环神经网络,如下图:假如你从左往右的顺序读句子,第一个单词假如是x<1>,将第一个词输入一个神经网络层,然后尝试预测输出y<1>,判断这是否是人名的一部分。循环神经网络做的是,当它读到句中的第二单词时,假如是x<2>,它不是仅用x<2>就预测出y<2>,它也会输入一些来自时间步(time-step)1的信息。具体而言,时间步1的**值就会传递到时间步2。然后,在下一个时间步,循环神经网络输入单词x<3>,然后它尝试输出预测结果y<3>,等等。一直到最后一个时间步,输入x<Tx>,然后输出y<Ty>.在这个例子中Tx=Ty,如果Tx!=Ty那么这个网络结构需要作出一些改变。在每一个时间步中,循环神经网络传递一个**值到下一个时间步中用于计算。要开始整个流程,我们在零时刻,需要编造一个**值,这通常是零向量。也有些研究员会随机用其它方法初始化a<0>,不过使用零向量作为零时刻的伪**值是最常见的选择。循环神经网络的画法一般有两种,一种是分步画法,一种是图表画法。循环神经网络是从左向右扫描数据,同时每个时间步的参数也是共享的。我们用wax来表示从x<1>到隐藏层的连接,每个时间步使用的都是相同的参数Wax,而**值也就是水平连接是由参数waa决定的,同时每一个时间步都使用相同的参数waa,同样的,输出结果由wya决定。在这个循环神经网络中,它的意思是在预测y<3>时,不就要使用x<3>的信息,还要使用来自x<1>和x<2>的信息。因为来自x<1>的信息可以通过这样的路径来帮助预测y<3>。这个循环神经网络的一个缺点就是,它只使用了这个序列中之前的信息来做出预测,尤其,当预测y<3>时它没有用到x<4>,x<5>,x<6>等等的信息,所以这就有一个问题。所以这个特定的神经网络结构的一个限制是它在某一个时刻的预测仅使用了从序列中之前的输入信息并没有使用序列中后部分的信息。双向循环神经网络(BRNN)可以处理这个问题。

吴恩达老师深度学习视频课笔记:循环神经网络

循环神经网络前向传播(forward propagation):一般开始先输入a<0>,它是一个零向量,接着,这就是前向传播过程,循环神经网络经常选用tanh作为**函数,有时也会用ReLu等,选用哪个**函数是取决于你的输出y。它的公式如下:

吴恩达老师深度学习视频课笔记:循环神经网络

下图是RNN前向传播的简单公式:

吴恩达老师深度学习视频课笔记:循环神经网络

Backpropagation through time:如下图,反向传播的计算方向与前向传播基本上是相反的。前向传播计算:假入一个输入序列,x<1>,x<2>,x<3>,…,x<Tx>,然后用x<1>和a<0>计算出时间步(time step)的**项a<1>,再用x<2>和a<1>计算出a<2>,然后再计算出a<3>,一直到a<Tx>。为了真正计算出a<1>,还需要一些参数,wa和ba。这些参数在之后的每个时间步都会被用到,于是继续用这些参数计算出a<2>,a<3>等等。所有的这些**项最后都要取决于参数wa和ba.有了a<1>神经网络就可以计算第一个预测输出y<1>,接着到下一个时间步继续计算出y<2>,y<3>等等一直到y<Ty>。为了计算y,你需要参数wy和by,它们被用于y的所有节点。然后为了计算反向传播,还需要一个损失函数,如标准logistic回归损失函数,也叫交叉熵(cross entropy)损失函数。通过y<1>可以计算对应的损失函数,即第一个时间步的损失函数L<1>,第二个时间步的损失函数L<2>,一直到最后一个时间步的损失函数L<Ty>。最后为了计算出总体的损失函数要把它们都加起来。然后通过公式计算出最后的L。反向传播算法需要在相反的方向上进行计算和传递。在这之后你就可以计算出所有合适的量,然后就可以通过导数相关的参数用梯度下降法来更新参数。

吴恩达老师深度学习视频课笔记:循环神经网络

         不同类型的循环神经网络:如下图,(1). 多对多结构(many-to-many architecture):因为输入序列有很多的输入而输出序列也有很多输出。(2). 多对一结构(many-to-one architecture):因为它有很多的输入,然后输出一个数字。(3). 一对一结构(one-to-one architecture):类似于一个小型的标准的神经网络,输入x然后得到输出y。(4). 一对多结构:如音乐生成。多对多结构可以是输入和输出长度是不同的,如机器翻译。

吴恩达老师深度学习视频课笔记:循环神经网络

 Language model and sequence generation: 用RNN构建一个语言模型。什么是语言模型,如下图,一个好的语音识别系统能够识别出非常相似的两句话。语言识别系统使用一个语言模型计算出相似的两句话各自的可能性,比如概率值,某个特定的句子出现的概率是多少。语言模型所做的基本工作就是:输入一个句子,准确地说是一个文本序列,y<1>,y<2>,一直到y<Ty>,然后语言模型会估计某个句子序列中各个单词出现的可能性。

吴恩达老师深度学习视频课笔记:循环神经网络

         如何建立一个语言模型:如下图,为了使用RNN建立出这样的模型,首先需要一个训练集,包含一个很大的英文文本语料库,或者其它的你想用于构建模型的语言的语料库,语料库(word corpus)是自然语言处理(NLP)的一个专有名词,意思就是很长的或者说数量众多的英文句子组成的文本。比如你在训练集中得到这么一句话,Cats average 15 hours of sleep a day,你要做的第一件事就是将这个句子标记化,意思就是建立一个字典,然后将每个单词都转换成对应的one-hot向量,也就是字典中的索引,可能还有一件事就是你要定义句子的结尾,一般的做法就是增加一个额外的标记叫做EOS,它表示句子的结尾。这样能够帮你搞清楚一个句子什么时候结束。EOS标记可以被附加到训练集中每一个句子的结尾,这样你可以使你的模型能够准确识别句子的结尾。在标记化的过程中,你可以自己决定要不要把标点符号看成是标记。下图中忽略标点符号。如果你的训练集中有一些词并不在你的字典中,此时可以把不在字典中的词替换成一个叫做UNK的代表未知词的标志。我们只针对UNK建立概率模型而不针对这个具体的词。完成标志化的过程后,这意味着将输入的句子都映射到了各个标志上或者说字典中的各个词上。

吴恩达老师深度学习视频课笔记:循环神经网络

下一步,我们要建立一个RNN来构建这些序列的概率模型。如下图,在第0个时间步,你要计算**项a<1>,它是以x<1>作为输入的函数,而x<1>会被设为全为0的集合,也就是0向量,在之前的a<0>按照惯例也设为0向量,于是a<1>要做的就是通过softmax进行一些预测来计算出第一个词可能会是什么,其结果就是y<1>,这一步其实就是通过softmax层来预测字典中的任意单词,会是第一个词的概率,所以y<1>的输出是softmax的计算结果,它只是预测第一个词的概率,而不去管结果是什么。如果字典大小是10000,那么softmax层可能输出10000种结果,也有可能是10002种结果,因为你还可能加上了未知词和句子结尾这两个额外的标志。然后RNN进入下一个时间步,在下一个时间步中,使用**项a<2>,在这步要做的是计算出第二词会是什么,现在依然传给它正确的第一个词,我们会告诉它第一个词就是Cats,也就是y<1>,这就是为什么x<2>=y<1>,然后在第二个时间步中,输出结果同样经过softmax层进行预测。然后再进行RNN的下一个时间步,现在要计算a<3>,为了预测第3个词,我们现在给它前两个词,告诉它Cats average是句子的前两个词,所以这个输入x<3>=y<2>,现在要计算序列中下一个词是什么。以此类推,一直到最后第9个时间步,然后把x<9>=y<8>,它会输出y<9>,最后得到的结果会是EOS标志。所以RNN中的每一步都会考虑前面得到的单词,比如给它前3个单词,让它给出下个词的分布,这就是RNN如何学习,从左到右每次预测一个词。接下来,为了训练这个网络,我们要定义代价函数(cost function)。

吴恩达老师深度学习视频课笔记:循环神经网络

Sampling novel sequences(对新序列采样):在你训练一个序列模型之后,要想了解这个模型学到了什么,一种非正式的方法就是进行一次新序列采样。如下图,一个序列模型模拟了任意特定单词序列的概率。我们所要做的就是对这个概率分布进行采样来生成一个新的单词序列。为了进行采样,第一步要做的就是对你想要模型生成的第一个词进行采样。于是你输入x<1>=0,a<0>=0,现在你的第一个时间步得到的是所有可能的输出,是经过softmax层后得到的概率,然后根据这个softmax的分布进行随机采样。softmax分布给你的信息就是第一个词是a的概率是多少,第一个词是aaron的概率是多少,等等,还有第一个词是未知标志的概率是多少。根据向量中这些概率的分布进行采样,这样就能对第一个词进行采样得到y’<1>。然后继续下一个时间步,第二个时间步需要y<1>作为输入,而现在要做的是把刚刚采样得到的y’<1>作为第二个时间步的输入,然后sotfmax层就会预测y’<2>是什么。然后再到下一个时间步,无论你得到什么样的选择结果都把它传递到下一个时间步,一直这样直到最后一个时间步。这就是你如何从你的RNN语言模型中生成一个随机选择的句子。以上是基于词汇的RNN模型,意思就是字典中的词都是英语单词。

吴恩达老师深度学习视频课笔记:循环神经网络

         根据你实际的需要,你还可以构建一个基于字符的RNN模型。在这种情况下,你的字典仅包含从a到z的字母,可能还会有空格符,还可以有数字0到9,如果想区分大小写字母,还可以再加上大写的字母,还可以看看实际训练集中可能会出现的字符,然后用这些字符组成你的字典。如果你建立一个基于字符的语言模型比起基于词汇的语言模型,你的序列y<1>,y<2>,y<3>等在训练数据中都将是单独的字符而不是单独的词汇。自然语言处理的趋势都是基于词汇的语言模型。

         Vanishing gradients(梯度消失) with RNNs:基本的RNN算法会存在梯度消失的问题。以语言模型为例,如下图,基本的RNN不擅长处理长期依赖(long-term dependencies)的问题。如果出现梯度爆炸的问题(导数值很大或出现了NaN)一个解决方法就是用梯度修剪(gradient clipping)。梯度修剪的意思就是观察你的梯度向量,如果它大于某个阈值就缩放梯度向量,保证它不会太大。

吴恩达老师深度学习视频课笔记:循环神经网络

         Gated Recurrent Unit(GRU,门控循环单元):GRU改变了RNN的隐藏层,使其可以更好地捕捉深层连接并改善了梯度消失问题,如下图:

吴恩达老师深度学习视频课笔记:循环神经网络

         LSTM(long short term memory) unit:LSTM有时比GRU更有效。LSTM比GRU出现的早。GRU的优点是模型更加简单,更容易创建一个更大的网络,它只有两个门,在计算性上,也运行的更快,它可以扩大模型的规模。但是LSTM更加强大和灵活,它有三个门而不是两个。GRU和LSTM的主要公式如下图:

吴恩达老师深度学习视频课笔记:循环神经网络

         Bidirectional(双向) RNN:这个模型可以让你序列的某点处不仅可以获取之前的信息还可以获取未来的信息。如下图,给定一个输入序列x<1>到x<4>,这个序列首先计算前向的a<1>,然后计算前向的a<2>,接着a<3>,a<4>。而反向序列,从a<4>开始,反向进行,计算反向的a<3>,计算完了反向的a<3>后可以用这些**值计算反向的a<2>, 然后是反向的a<1>.把所有的这些**值都计算完了,就可以预测计算结果了。比如时间步3的预测结果,信息从x<1>过来,流经前向的a<1>到前向的a<2>,到前向的a<3>,再到y<3>,所以从x<1>,x<2>,x<3>来的信息都会考虑在内。而从x<4>来的信息,会流过反向的a<4>,到反向的a<3>再到y<3>,这样使得时间步3的预测结果不仅输入了过去的信息还有现在的信息。这一步涉及了前向和反向的传播信息以及未来的信息。这就是双向循环神经网络,并且这些基本单元不仅仅是标准的RNN单元也可以是GRU单元或LSTM单元。这个双向RNN网络模型的缺点是你需要完整的数据的序列你才能预测任意位置。比如说,你要构建一个语音识别系统,那么双向RNN模型需要你考虑整个语音表达,但是如果直接用这个去实现的话,你需要等待这个人说完,然后获取整个语音表达才能处理这段语音并进一步做语音识别。

吴恩达老师深度学习视频课笔记:循环神经网络

         Deep RNNs:深层神经网络,如下图,用a[l]<t>来表示第t个时间点第l层的**值:

吴恩达老师深度学习视频课笔记:循环神经网络

 

GitHub: https://github.com/fengbingchun/NN_Test