Coursera吴恩达《序列模型》课程笔记(1)-- 循环神经网络(RNN)

红色石头的我的网站:redstonewill.comweb

《Recurrent Neural Networks》是Andrw Ng深度学习专项课程中的第五门课,也是最后一门课。这门课主要介绍循环神经网络(RNN)的基本概念、模型和具体应用。该门课共有3周课时,因此我将分红3次笔记来总结,这是第一节笔记。网络

1. Why sequence models

序列模型可以应用在许多领域,例如:app

  • 语音识别框架

  • 音乐发生器机器学习

  • 情感分类ide

  • DNA序列分析svg

  • 机器翻译函数

  • 视频动做识别性能

  • 命名实体识别学习

这里写图片描述

这些序列模型基本都属于监督式学习,输入x和输出y不必定都是序列模型。若是都是序列模型的话,模型长度不必定彻底一致。

2. Notation

下面以命名实体识别为例,介绍序列模型的命名规则。示例语句为:

Harry Potter and Hermione Granger invented a new spell.

该句话包含9个单词,输出y即为1 x 9向量,每位表征对应单词是否为人名的一部分,1表示是,0表示否。很明显,该句话中“Harry”,“Potter”,“Hermione”,“Granger”均是人名成分,因此,对应的输出y可表示为:

y = [ 1     1     0     1     1     0     0     0     0 ]

通常约定使用 y < t > 表示序列对应位置的输出,使用 T y 表示输出序列长度,则 1 t T y

对于输入x,表示为:

[ x < 1 >     x < 2 >     x < 3 >     x < 4 >     x < 5 >     x < 6 >     x < 7 >     x < 8 >     x < 9 > ]

一样, x < t > 表示序列对应位置的输入, T x 表示输入序列长度。注意,此例中, T x = T y ,可是也存在 T x T y 的状况。

如何来表示每一个 x < t > 呢?方法是首先创建一个词汇库vocabulary,尽量包含更多的词汇。例如一个包含10000个词汇的词汇库为:

[ a a n d h a r r y p o t t e r z u l u ]

该词汇库可当作是10000 x 1的向量。值得注意的是天然语言处理NLP实际应用中的词汇库可达百万级别的词汇量。

而后,使用one-hot编码,例句中的每一个单词 x < t > 均可以表示成10000 x 1的向量,词汇表中与 x < t > 对应的位置为1,其它位置为0。该 x < t > 为one-hot向量。值得一提的是若是出现词汇表以外的单词,可使用UNK或其余字符串来表示。

对于多样本,以上序列模型对应的命名规则可表示为: X ( i ) < t > y ( i ) < t > T x ( i ) T y ( i ) 。其中, i 表示第i个样本。不一样样本的 T x ( i ) T y ( i ) 都有可能不一样。

3. Recurrent Neural Network Model

对于序列模型,若是使用标准的神经网络,其模型结构以下:

这里写图片描述

使用标准的神经网络模型存在两个问题:

第一个问题,不一样样本的输入序列长度或输出序列长度不一样,即 T x ( i ) T x ( j ) T y ( i ) T y ( j ) ,形成模型难以统一。解决办法之一是设定一个最大序列长度,对每一个输入和输出序列补零并统一到最大长度。可是这种作法实际效果并不理想。

第二个问题,也是主要问题,这种标准神经网络结构没法共享序列不一样 x < t > 之间的特征。例如,若是某个 x < t > 即“Harry”是人名成分,那么句子其它位置出现了“Harry”,也极可能也是人名。这是共享特征的结果,如同CNN网络特色同样。可是,上图所示的网络不具有共享特征的能力。值得一提的是,共享特征还有助于减小神经网络中的参数数量,必定程度上减少了模型的计算复杂度。例如上图所示的标准神经网络,假设每一个 x < t > 扩展到最大序列长度为100,且词汇表长度为10000,则输入层就已经包含了100 x 10000个神经元了,权重参数不少,运算量将是庞大的。

标准的神经网络不适合解决序列模型问题,而循环神经网络(RNN)是专门用来解决序列模型问题的。RNN模型结构以下:

这里写图片描述

序列模型从左到右,依次传递,此例中, T x = T y x < t > y ^ < t > 之间是隐藏神经元。 a < t > 会传入到第 t + 1 个元素中,做为输入。其中, a < 0 > 通常为零向量。

RNN模型包含三类权重系数,分别是 W a x W a a W y a 。且不一样元素之间同一位置共享同一权重系数。

这里写图片描述

RNN的正向传播(Forward Propagation)过程为:

a < t > = g ( W a a a < t 1 > + W a x x < t > + b a )

y ^ < t > = g ( W y a a < t > + b y )

其中, g ( ) 表示激活函数,不一样的问题须要使用不一样的激活函数。

为了简化表达式,能够对 a < t > 项进行整合:

W a a a < t 1 > + W a x x < t > = [ W a a     W a x ] [ a < t 1 > x < t > ] W a [ a < t 1 > , x < t > ]

则正向传播可表示为:

a < t > = g ( W a [ a < t 1 > , x < t > ] + b a )

y ^ < t > = g ( W y a < t > + b y )

值得一提的是,以上所述的RNN为单向RNN,即按照从左到右顺序,单向进行, y ^ < t > 只与左边的元素有关。可是,有时候 y ^ < t > 也可能与右边元素有关。例以下面两个句子中,单凭前三个单词,没法肯定“Teddy”是否为人名,必须根据右边单词进行判断。

He said, “Teddy Roosevelt was a great President.”

He said, “Teddy bears are on sale!”

所以,有另一种RNN结构是双向RNN,简称为BRNN。 y ^ < t > 与左右元素均有关系,咱们以后再详细介绍。

4. Backpropagation through time

针对上面识别人名的例子,通过RNN正向传播,单个元素的Loss function为:

L < t > ( y ^ < t > , y < t > ) = y < t > l o g   y ^ < t > ( 1 y < t > ) l o g   ( 1 y ^ < t > )

该样本全部元素的Loss function为:

L ( y ^ , y ) = t = 1 T y L < t > ( y ^ < t > , y < t > )

而后,反向传播(Backpropagation)过程就是从右到左分别计算 L ( y ^ , y ) 对参数 W a W y b a b y 的偏导数。思路与作法与标准的神经网络是同样的。通常能够经过成熟的深度学习框架自动求导,例如PyTorch、Tensorflow等。这种从右到左的求导过程被称为Backpropagation through time。

5. Different types of RNNs

以上介绍的例子中, T x = T y 。可是在不少RNN模型中, T x 是不等于 T y 的。例如第1节介绍的许多模型都是 T x T y 。根据 T x T y 的关系,RNN模型包含如下几个类型:

  • Many to many: T x = T y

  • Many to many: T x T y

  • Many to one: T x > 1 , T y = 1

  • One to many: T x = 1 , T y > 1

  • One to one: T x = 1 , T y = 1

不一样类型相应的示例结构以下:

这里写图片描述

6. Language model and sequence generation

语言模型是天然语言处理(NLP)中最基本和最重要的任务之一。使用RNN可以很好地创建须要的不一样语言风格的语言模型。

什么是语言模型呢?举个例子,在语音识别中,某句语音有两种翻译:

  • The apple and pair salad.

  • The apple and pear salad.

很明显,第二句话更有多是正确的翻译。语言模型实际上会计算出这两句话各自的出现几率。好比第一句话几率为 10 13 ,第二句话几率为 10 10 。也就是说,利用语言模型获得各自语句的几率,选择几率最大的语句做为正确的翻译。几率计算的表达式为:

P ( y < 1 > , y < 2 > , , y < T y > )

如何使用RNN构建语言模型?首先,咱们须要一个足够大的训练集,训练集由大量的单词语句语料库(corpus)构成。而后,对corpus的每句话进行切分词(tokenize)。作法就跟第2节介绍的同样,创建vocabulary,对每一个单词进行one-hot编码。例以下面这句话:

The Egyptian Mau is a bread of cat.

One-hot编码已经介绍过了,再也不赘述。还需注意的是,每句话结束末尾,须要加上< EOS >做为语句结束符。另外,若语句中有词汇表中没有的单词,用< UNK >表示。假设单词“Mau”不在词汇表中,则上面这句话可表示为:

The Egyptian < UNK > is a bread of cat. < EOS >

准备好训练集并对语料库进行切分词等处理以后,接下来构建相应的RNN模型。

这里写图片描述

语言模型的RNN结构如上图所示, x < 1 > a < 0 > 均为零向量。Softmax输出层 y ^ < 1 > 表示出现该语句第一个单词的几率,softmax输出层 y ^ < 2 > 表示在第一个单词基础上出现第二个单词的几率,即条件几率,以此类推,最后是出现< EOS >的条件几率。

单个元素的softmax loss function为:

L < t > ( y ^ < t > , y < t > ) = i y i < t > l o g   y ^ i < t >

该样本全部元素的Loss function为:

L ( y ^ , y ) = t L < t > ( y ^ < t > , y < t > )

对语料库的每条语句进行RNN模型训练,最终获得的模型能够根据给出语句的前几个单词预测其他部分,将语句补充完整。例如给出“Cats average 15”,RNN模型可能预测完整的语句是“Cats average 15 hours of sleep a day.”

最后补充一点,整个语句出现的几率等于语句中全部元素出现的条件几率乘积。例如某个语句包含 y < 1 > , y < 2 > , y < 3 > ,则整个语句出现的几率为:

P ( y < 1 > , y < 2 > , y < 3 > ) = P ( y < 1 > ) P ( y < 2 > | y < 1 > ) P ( y < 3 > | y < 1 > , y < 2 > )

7 Sampling novel sequences

利用训练好的RNN语言模型,能够进行新的序列采样,从而随机产生新的语句。与上一节介绍的同样,相应的RNN模型以下所示:

这里写图片描述

首先,从第一个元素输出 y ^ < 1 > 的softmax分布中随机选取一个word做为新语句的首单词。而后, y < 1 > 做为 x < 2 > ,获得 y ^ < 1 > 的softmax分布。从中选取几率最大的word做为 y < 2 > ,继续将 y < 2 > 做为 x < 3 > ,以此类推。直到产生< EOS >结束符,则标志语句生成完毕。固然,也能够设定语句长度上限,达到长度上限即中止生成新的单词。最终,根据随机选择的首单词,RNN模型会生成一条新的语句。

值得一提的是,若是不但愿新的语句中包含< UNK >标志符,能够在每次产生< UNK >时从新采样,直到生成非< UNK >标志符为止。

以上介绍的是word level RNN,即每次生成单个word,语句由多个words构成。另一种状况是character level RNN,即词汇表由单个英文字母或字符组成,以下所示:

V o c a b u l a y = [ a , b , c , , z , . , ; ,   , 0 , 1 , , 9 , A , B , , Z ]

Character level RNN与word level RNN不一样的是, y ^ < t > 由单个字符组成而不是word。训练集中的每句话都当成是由许多字符组成的。character level RNN的优势是能有效避免遇到词汇表中不存在的单词< UNK >。可是,character level RNN的缺点也很突出。因为是字符表征,每句话的字符数量很大,这种大的跨度不利于寻找语句前部分和后部分之间的依赖性。另外,character level RNN的在训练时的计算量也是庞大的。基于这些缺点,目前character level RNN的应用并不普遍,可是在特定应用下仍然有发展的趋势。

8. Vanisging gradients with RNNs

语句中可能存在跨度很大的依赖关系,即某个word可能与它距离较远的某个word具备强依赖关系。例以下面这两条语句:

The cat, which already ate fish, was full.

The cats, which already ate fish, were full.

第一句话中,was受cat影响;第二句话中,were受cats影响。它们之间都跨越了不少单词。而通常的RNN模型每一个元素受其周围附近的影响较大,难以创建跨度较大的依赖性。上面两句话的这种依赖关系,因为跨度很大,普通的RNN网络容易出现梯度消失,捕捉不到它们之间的依赖,形成语法错误。关于梯度消失的原理,咱们在以前的 Coursera吴恩达《优化深度神经网络》课程笔记(1)– 深度学习的实用层面已经有过介绍,可参考。

另外一方面,RNN也可能出现梯度爆炸的问题,即gradient过大。经常使用的解决办法是设定一个阈值,一旦梯度最大值达到这个阈值,就对整个梯度向量进行尺度缩小。这种作法被称为gradient clipping。

9. Gated Recurrent Unit(GRU)

RNN的隐藏层单元结构以下图所示:

这里写图片描述

a < t > 的表达式为:

a < t > = t a n h ( W a [ a < t 1 > , x < t > ] + b a )

为了解决梯度消失问题,对上述单元进行修改,添加了记忆单元,构建GRU,以下图所示:

这里写图片描述

相应的表达式为:

c ~ < t > = t a n h ( W c [ c < t 1 > , x < t > ] + b c )

Γ u = σ ( W u [ c < t 1 > , x < t > ] + b u )

c < t > = Γ c ~ < t > + ( 1 Γ u ) c < t 1 >

其中, c < t 1 > = a < t 1 > c < t > = a < t > Γ u 意为gate,记忆单元。当 Γ u = 1 时,表明更新;当 Γ u = 0 时,表明记忆,保留以前的模块输出。这一点跟CNN中的ResNets的做用有点相似。所以, Γ u 可以保证RNN模型中跨度很大的依赖关系不受影响,消除梯度消失问题。

上面介绍的是简化的GRU模型,完整的GRU添加了另一个gate,即 Γ r ,表达式以下:

c ~ < t > = t a n h ( W c [ Γ r c < t 1 > , x < t > ] + b c )

Γ u = σ ( W u [ c < t 1 > , x < t > ] + b u )

Γ r = σ ( W r [ c < t 1 > , x < t > ] + b r )

c < t > = Γ c ~ < t > + ( 1 Γ u ) c < t 1 >

a < t > = c < t >

注意,以上表达式中的 表示元素相乘,而非矩阵相乘。

10. Long Short Term Memory(LSTM)

LSTM是另外一种更强大的解决梯度消失问题的方法。它对应的RNN隐藏层单元结构以下图所示:

这里写图片描述

相应的表达式为:

c ~ < t > = t a n h ( W c [ a < t 1 > , x < t > ] + b c )

Γ u = σ ( W u [ a < t 1 > , x < t > ] + b u )

Γ f = σ ( W f [ a < t 1 > , x < t > ] + b f )

Γ o = σ ( W o [ a < t 1 > , x < t > ] + b o )

c < t > = Γ u c ~ < t > + Γ f c < t 1 >

a < t > = Γ o c < t >

LSTM包含三个gates: Γ u Γ f Γ o ,分别对应update gate,forget gate和output gate。

若是考虑 c < t 1 > Γ u Γ f Γ o 的影响,可加入peephole connection,对LSTM的表达式进行修改:

c ~ < t > = t a n h ( W c [ a < t 1 > , x < t > ] + b c )

Γ u = σ ( W u [ a < t 1 > , x < t > , c < t 1 > ] + b u )

Γ f = σ ( W f [ a < t 1 > , x < t > , c < t 1 > ] + b f )

Γ o = σ ( W o [ a < t 1 > , x < t > , c < t 1 > ] + b o )

c < t > = Γ u c ~ < t > + Γ f c < t 1 >

a < t > = Γ o c < t >

GRU能够当作是简化的LSTM,两种方法都具备各自的优点。

11. Bidirectional RNN

咱们在第3节中简单提过Bidirectional RNN,它的结构以下图所示:

这里写图片描述

BRNN对应的输出 y < t > 表达式为:

y ^ < t > = g ( W y [ a →< t > , a ←< t > ] + b y )

BRNN可以同时对序列进行双向处理,性能大大提升。可是计算量较大,且在处理实时语音时,须要等到完整的一句话结束时才能进行分析。

12. Deep RNNs

Deep RNNs由多层RNN组成,其结构以下图所示:

这里写图片描述

与DNN同样,用上标 [ l ] 表示层数。Deep RNNs中 a [ l ] < t > 的表达式为:

a [ l ] < t > = g ( W a [ l ] [ a [ l ] < t 1 > , a [ l 1 ] < t > ] + b a [ l ] )

咱们知道DNN层数可达100多,而Deep RNNs通常没有那么多层,3层RNNs已经较复杂了。

另一种Deep RNNs结构是每一个输出层上还有一些垂直单元,以下图所示:

这里写图片描述

至此,第一节笔记介绍完毕!

更多AI资源请关注公众号:红色石头的机器学习之路(ID:redstonewill)
这里写图片描述