吴恩达《序列模型》01——循环神经网络RNN

文章目录

      • 一、序列模型
        • 1. 什么是序列模型?
        • 2. 数学符号(Notation)
      • 二、循环神经网络
        • 1. 标准NN存在的问题
        • 2. RNN
        • 3. 通过时间反向传播(Backpropagation through time)
        • 4. 不同结构
      • 三、语言模型
        • 1. Language model and sequence generation
        • 2. 采样(Sampling novel sequences)
      • 四、GRU和LSTM
        • 1. RNN 的梯度消失(Vanisging gradients with RNNs)
        • 2. GRU(门控循环单元)
        • 3. LSTM(Long Short Term Memory,长短期记忆)
      • 五、BRNN和DRNN
        • 1. 双向循环神经网络(BRNN)
        • 2. 深度循环神经网络(DRNN)

《Recurrent Neural Networks》是Andrw Ng深度学习专项课程中的第五门课,也是最后一门课。这门课主要介绍循环神经网络(RNN)的基本概念、模型和具体应用。

一、序列模型

1. 什么是序列模型?

自然语言和音频都是前后相互关联的数据,对于这些序列数据需要使用循环神经网络(Recurrent Neural Network,RNN)来进行处理。

序列模型能够应用在许多领域,例如:

  • 语音识别
  • 音乐发生器
  • 情感分析
  • DNA序列分析
  • 机器翻译
  • 视频动作识别
  • 命名实体识别

吴恩达《序列模型》01——循环神经网络RNN_第1张图片
这些序列模型基本都属于监督式学习,输入x和输出y不一定都是序列模型。如果都是序列模型的话,模型长度不一定完全一致。

2. 数学符号(Notation)

下面以命名实体识别为例,介绍序列模型的命名规则。示例语句为:
Harry Potter and Hermione Granger invented a new spell.

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

对于一个序列数据 x x x,用符号 x x x( i i i)< t t t>来表示这个数据中的第t个元素。一般约定使用 y y y < t > <t>表示序列对应位置的输出,使用 T T T x x x T T T y y y来表示输入输出的序列长度。对于一段音频,元素可能是其中的几帧;对于一句话,元素可能是一到多个单词。

对于输入x,表示为:
在这里插入图片描述
i i i 个序列数据的第 t t t 个元素用符号 x x x( i i i)< t t t>,第 t t t 个标签即为 y y y y yy( i i i)< t t t>。对应即有 T T T ( i ) (i) (i) x x x T T T ( i ) (i) (i) y y y

如何来表示每个 x x x( i i i)< t t t>呢?

方法是首先建立一个词汇库vocabulary,尽可能包含更多的词汇。例如一个包含10000个词汇的词汇库为:
吴恩达《序列模型》01——循环神经网络RNN_第2张图片
该词汇库可看成是10000 × 1 的向量。值得注意的是自然语言处理NLP实际应用中的词汇库可达百万级别的词汇量。

然后,使用one-hot编码,例句中的每个单词 x x x( i i i)< t t t>都可以表示成10000 × 1 的向量,词汇表中与 x x x( i i i)< t t t>对应的位置为1,其他位置为0。该 x x x( i i i)< t t t>为one-hot向量。值得一提的是,如果出现词汇表之外的单词,可以使用UNK或其他字符串来表示。

例如,'zebra’排在词汇表的最后一位,因此它的词向量表示为:
在这里插入图片描述
补充: one-hot 向量是最简单的词向量。它的缺点是,由于每个单词被表示为完全独立的个体,因此单词间的相似度无法体现。例如单词 hotel 和 motel 意思相近,而与 cat 不相似,但是
在这里插入图片描述

二、循环神经网络

1. 标准NN存在的问题

对于序列模型,如果使用标准的神经网络,其模型结构如下:
吴恩达《序列模型》01——循环神经网络RNN_第3张图片使用标准的神经网络模型存在以下问题:

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

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

2. RNN

标准的神经网络不适合解决序列模型问题,而循环神经网络(RNN)是专门用来解决序列模型问题的。RNN模型结构如下:
吴恩达《序列模型》01——循环神经网络RNN_第4张图片
序列模型从左到右,依次传递,此例中, T x T_x Tx ≠ ≠ = T y T_y Ty x x x< t t t> y h y^h yh< t t t>之间都是隐藏神经元。 a a a< t t t>会传入到第 t + 1 t+1 t+1个元素中作为输入。其中, a a a< 0 0 0>一般为零向量。

RNN模型包含三类权重系数,分别是 W W W a x ax ax W W W a a aa aa W W W y a ya ya。且不同元素之间同一位置共享同一权重系数。
吴恩达《序列模型》01——循环神经网络RNN_第5张图片
RNN的正向传播(Forward Propagation)过程为:
吴恩达《序列模型》01——循环神经网络RNN_第6张图片
其中, g ( ⋅ ) g(·) g()表示激活函数,不同的问题需要使用不同的激活函数。第一个激活函数通常选择tanh,有时也用ReLU;第二个激活函数可选sigmoid或softmax,取决于需要的输出类型。

为了简化表达式,可以对 a a a< t t t>项进行整合:将 W W W a x ax ax W W W a a aa aa 水平并列 为一个矩阵 W W W a a a,同时将 a a a< t − 1 t-1 t1> x x x< t t t> 堆叠 成一个矩阵。则有:
在这里插入图片描述下图是一个RNN神经元的结构:吴恩达《序列模型》01——循环神经网络RNN_第7张图片
值得一提的是,以上所述的RNN为单向RNN,即按照从左到右顺序,单向进行 y h y^h yh< t t t>只与左边的元素有关。但是,有时候 y h y^h yh< t t t>也可能与右边元素有关。例如下面两个句子中,单凭前三个单词,无法确定“Teddy”是否为人名,必须根据右边单词进行判断。

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

He said, “Teddy bears are on sale!”

因此,有另外一种RNN结构是双向RNN,简称为BRNN y h y^h yh< t t t>与左右元素均有关系,我们之后再详细介绍。

3. 通过时间反向传播(Backpropagation through time)

为了计算反向传播过程,需要先定义一个损失函数。单个位置上(或者说单个时间步上)某个单词的预测值的损失函数采用交叉熵损失函数,单个元素的Loss function如下所示:
在这里插入图片描述
将单个位置上的损失函数相加,得到该样本所有元素的Loss function为:
在这里插入图片描述
循环神经网络的反向传播被称为通过时间反向传播(Backpropagation through time),因为从右向左计算的过程就像是时间倒流。反向传播过程就是从右到左分别计算 L ( y h , y ) L(y^h,y) L(yh,y)对参数 W a W_a Wa W y W_y Wy b a b_a ba b y b_y by的偏导数。思路与做法与标准的神经网络是一样的。一般可以通过成熟的深度学习框架自动求导,例如PyTorch、Tensorflow等。

更详细的计算公式如下:
吴恩达《序列模型》01——循环神经网络RNN_第8张图片

4. 不同结构

某些情况下,输入长度和输出长度不一致。根据所需的输入及输出长度,循环神经网络可分为“一对一”、“多对一”、“多对多”等结构:
吴恩达《序列模型》01——循环神经网络RNN_第9张图片
不同类型相应的示例结构如下:
吴恩达《序列模型》01——循环神经网络RNN_第10张图片
目前我们看到的模型的问题是,只使用了这个序列中之前的信息来做出预测,即后文没有被使用。 可以通过双向循环神经网络(Bidirectional RNN,BRNN)来解决这个问题。

三、语言模型

1. Language model and sequence generation

语言模型(Language Model) 是根据语言客观事实而进行的语言抽象数学建模,能够估计某个序列中各元素出现的可能性。例如,在一个语音识别系统中,语言模型能够计算两个读音相近的句子为正确结果的概率,以此为依据作出准确判断。

建立语言模型所采用的训练集是一个大型的语料库(Corpus),指数量众多的句子组成的文本。建立过程的第一步是标记化(Tokenize),即建立字典;然后将语料库中的每个词表示为对应的 one-hot 向量。另外,需要增加一个额外的标记 EOS(End of Sentence)来表示一个句子的结尾。 标点符号可以忽略,也可以加入字典后用 one-hot 向量表示。

对于语料库中部分特殊的、不包含在字典中的词汇,例如人名、地名,可以不必针对这些具体的词,而是在词典中加入一个 **UNK(Unique Token)**标记来表示。

例句:The Egyptian Mau is a bread of cat.

假设单词“Mau”不在词汇表中,则上面这句话可表示为:The Egyptian < UNK > is a bread of cat. < EOS >

准备好训练集并对语料库进行切分词等处理之后,接下来构建相应的RNN模型。
吴恩达《序列模型》01——循环神经网络RNN_第11张图片
将标志化后的训练集用于训练RNN,过程如下所示:
吴恩达《序列模型》01——循环神经网络RNN_第12张图片
语言模型的RNN结构如上图所示, x x x< 1 1 1> a a a< 0 0 0>均为零向量。Softmax输出层 y h y^h yh< 1 1 1>表示出现该语句第一个单词的概率,softmax输出层 y h y^h yh< 2 2 2>表示在第一个单词基础上出现第二个单词的概率,即条件概率,以此类推,最后是出现< EOS >的条件概率。
吴恩达《序列模型》01——循环神经网络RNN_第13张图片
单个元素的softmax loss function为:
在这里插入图片描述
该样本所有元素的Loss function为:
在这里插入图片描述
对语料库的每条语句进行RNN模型训练,最终得到的模型可以根据给出语句的前几个单词预测其余部分,将语句补充完整。例如给出“Cats average 15”,RNN模型可能预测完整的语句是“Cats average 15 hours of sleep a day.”。

最后补充一点,整个语句出现的概率等于语句中所有元素出现的条件概率乘积。例如某个语句包含 y y y< 1 1 1> y y y< 2 2 2> y y y< 3 3 3>则整个语句出现的概率为:
在这里插入图片描述

2. 采样(Sampling novel sequences)

在训练好一个语言模型后,可以通过采样(Sample)新的序列来了解这个模型中都学习到了一些什么。
吴恩达《序列模型》01——循环神经网络RNN_第14张图片
在第一个时间步输入 a a a< 0 0 0> x x x< 1 1 1>为零向量,输出预测出的字典中每个词作为第一个词出现的概率,根据 softmax 的分布进行随机采样(np.random.choice),将采样得到的 y y y< 1 1 1>作为第二个时间步的输入 x x x< 2 2 2>。以此类推,直到采样到 EOS,最后模型会自动生成一些句子,从这些句子中可以发现模型通过语料库学习到的知识。

这里建立的是基于词汇构建的语言模型(word level RNN)。根据需要也可以构建基于字符的语言模型(character level RNN),其优点是不必担心出现未知标识(UNK),其缺点是得到的序列过多过长,并且训练成本高昂。因此,基于词汇构建的语言模型更为常用。
在这里插入图片描述

四、GRU和LSTM

1. RNN 的梯度消失(Vanisging gradients with RNNs)

语句中可能存在跨度很大的依赖关系,即某个word可能与它距离较远的某个word具有强依赖关系。例如下面这两条语句:
吴恩达《序列模型》01——循环神经网络RNN_第15张图片
第一句话中,was受cat影响;第二句话中,were受cats影响。它们之间都跨越了很多单词。而一般的RNN模型每个元素受其周围附近的影响较大,难以建立跨度较大的依赖性。上面两句话的这种依赖关系,由于跨度很大,普通的RNN网络容易出现梯度消失,捕捉不到它们之间的依赖,造成语法错误。 究其原因,由于梯度消失,在反向传播时,后面层的输出误差很难影响到较靠前层的计算,网络很难调整靠前的计算。

在反向传播时,随着层数的增多,梯度不仅可能指数型下降,也有可能指数型上升,即梯度爆炸。不过梯度爆炸比较容易发现,因为参数会急剧膨胀到数值溢出(可能显示为 NaN)。这时可以采用梯度修剪(Gradient Clipping) 来解决:观察梯度向量,如果它大于某个阈值,则缩放梯度向量以保证其不会太大。相比之下,梯度消失问题更难解决。GRU 和 LSTM 都可以作为缓解梯度消失问题的方案。

2. GRU(门控循环单元)

RNN的隐藏层单元结构如下所示:
吴恩达《序列模型》01——循环神经网络RNN_第16张图片
a a a< t t t>的表达式为:
在这里插入图片描述
GRU(Gated Recurrent Units, 门控循环单元)改善了 RNN 的隐藏层,使其可以更好地捕捉深层连接,并改善了梯度消失问题。

The cat,which already ate a bunch of food, was full.

当我们从左到右读上面这个句子时,GRU 单元有一个新的变量称为 c,代表记忆细胞(Memory Cell),其作用是提供记忆的能力,记住例如前文主语是单数还是复数等信息。在时间 t,记忆细胞的值 c c c< t t t>等于输出的激活值 a a a< t t t>。相关的具体公式如下:
吴恩达《序列模型》01——循环神经网络RNN_第17张图片
添加了记忆单元后的结构如下图所示:
吴恩达《序列模型》01——循环神经网络RNN_第18张图片
当使用sigmoid作为激活函数得到 Γ u Γ_u Γu 时, Γ u Γ_u Γu 的值在0-1范围内,且大多数时间非常接近于0或1.当 Γ u = 1 Γ_u=1 Γu=1 时, c c c< t t t>被更新为新的c,否则保持不变。因为 Γ u Γ_u Γu 可以很接近0,因此 c c c< t t t> 几乎就等于 c c c< t − 1 t-1 t1>在经过很长的序列后,c的值依然被维持,从而实现“记忆”功能。
吴恩达《序列模型》01——循环神经网络RNN_第19张图片
以上实际上是简化过的 GRU 单元,但是蕴涵了 GRU 最重要的思想。完整的 GRU 单元添加了一个新的相关门(Relevance Gate) Γ r Γ_r Γr,表示 c~⟨t⟩和 c ⟨ t ⟩ c^{⟨t⟩} ct的相关性。因此,表达式改为如下所示:
吴恩达《序列模型》01——循环神经网络RNN_第20张图片
相关论文:

  1. Cho et al., 2014. On the properties of neural machine translation: Encoder-decoder approaches
  2. Chung et al., 2014. Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling

3. LSTM(Long Short Term Memory,长短期记忆)

LSTM(Long Short Term Memory,长短期记忆)网络比 GRU 更加灵活和强大,它额外引入了遗忘门(Forget Gate) Γ f Γ_f Γf输出门(Output Gate) Γ o Γ_o Γo

LSTM是另一种更强大的解决梯度消失问题的方法。它对应的RNN隐藏层单元结构如下图所示:
吴恩达《序列模型》01——循环神经网络RNN_第21张图片

其结构图和公式如下:
吴恩达《序列模型》01——循环神经网络RNN_第22张图片
如果考虑 c c c< t − 1 t-1 t1> Γ u Γ_u Γu Γ f Γ_f Γf Γ o Γ_o Γo的影响,可加入peephole connection,对LSTM的表达式进行修改即可。
相关论文:Hochreiter & Schmidhuber 1997. Long short-term memory

五、BRNN和DRNN

1. 双向循环神经网络(BRNN)

单向的循环神经网络在某一时刻的预测结果只能使用之前输入的序列信息。我们在第3节中简单提过Bidirectional RNN:双向循环神经网络(Bidirectional RNN,BRNN) 可以在序列的任意位置使用之前和之后的数据。 其工作原理是增加一个反向循环层,结构如下图所示:
吴恩达《序列模型》01——循环神经网络RNN_第23张图片
更为一般的结构如图:
吴恩达《序列模型》01——循环神经网络RNN_第24张图片
BRNN对应的输出 y < t > y^{} y<t>表达式为:
在这里插入图片描述
BRNN能够同时对序列进行双向处理,性能大大提高。 这个改进的方法不仅能用于基本的 RNN,也可以用于 GRU 或 LSTM。缺点是需要完整的序列数据,才能预测任意位置的结果。例如构建语音识别系统,需要等待用户说完并获取整个语音表达,才能处理这段语音并进一步做语音识别。因此,实际应用会有更加复杂的模块。

2. 深度循环神经网络(DRNN)

循环神经网络的每个时间步上也可以包含多个隐藏层,形成深度循环神经网络(Deep RNN)。结构如下图所示:
吴恩达《序列模型》01——循环神经网络RNN_第25张图片
与DNN一样,用上标 [ l ] [l] [l] 表示层数。

a [ 2 ] < 3 > a^{[2]<3>} a[2]<3>为例,有:
在这里插入图片描述
Deep RNNs中 a [ l ] < t > a^{[l]} a[l]<t>的表达式为:
在这里插入图片描述
我们知道DNN层数可达100多,而Deep RNNs一般没有那么多层,3层RNNs已经较复杂了。

另外一种Deep RNNs结构是每个输出层上还有一些垂直单元,如下图所示:
吴恩达《序列模型》01——循环神经网络RNN_第26张图片
参考资料:red stone 笔记
课后习题:循环神经网络习题

你可能感兴趣的:(DeepLearning,rnn,人工智能)