• 【序列模型】第一课--循环序列模型


    一. why sequence models?

    在这里插入图片描述
    (1)序列模型广泛应用于语音识别,音乐生成,情感分析,DNA序列分析,机器翻译,视频行为识别,命名实体识别等众多领域。
    (2)上面那些问题可以看成使用(x,y)作为训练集的监督学习,但是输入与输出的对应关系有非常多的组合,
    比如一对一,多对多,一对多,多对一,多对多(个数不同)等情况来针对不同的应用。

    二.数学符号说明 Notation

    假设有这样一句话:
    X:Harry Potter and Hermoine Granger invented a new spell.
    目的是想识别出句子中的实体词。所谓实体词包括人名, 地名,组织机构名称等等。
    可见,输入的句子可以看成是单词的序列,那么我们期望的输出应是如下对应的输出:
    Y:1 1 0 1 1 0 0 0 0
    1代表的是“是实体”;0代表的是“非实体”
    (当然,实际的命名实体识别比这输出要复杂得多,还需要表示实体词的结束位置与开始位置,在这个栗子中我们暂且选择以上这种简单的输出形式来讲解)

    显而易见,输入的x与输出的y的序列个数一致,且索引位置相对应,我们用如下符号来表示输入与输出:
    在这里插入图片描述
    (t)表示第t时刻的输入;
    (T_x) 表示样本(x)的序列长度;(T_y) 表示样本(x)输入模型后,输出序列的词长度,在本例中,输出与输出序列的长度相等,为9;
    (x^{(i)<t>}),(y^{(i)<t>})
    样本往往有很多个,用以下符号表示,第i个样本t时刻的输入与输出:
    用以下符号表示第i个样本的输入序列的长度与输出序列的长度:
    (T^{(i)}_x), (T^{(i)}_y)

    三.What is the Recurrent Neural Networks

    (1) 为什么叫循环神经网络呢?

    • 1.输入和输出在不同的样本中可以有不同的长度,即使能找到输入输出的最大值,对某个样本来说填充来使他达到最大长度,但是这种表示方式依然不够好;
    • 2.标准神经网络不能讲从文本不同位置学习到的特征共享,比如在第一个位置学习到了Harry是一个人名,如果Harry再次出现在其他位置的时候,不能自动识别它是一个人名,还需要重新识别
      在这里插入图片描述

    (2) 什么是循环神经网络?

    仍然使用这句话作为例子
    X:Harry otter and Hermoine Granger invented a new spell.
    首先将第一个词Harry作为第一个输入(x),中间经过一堆隐藏层,然后输出(y)
    接着将第二个词Potter作为第二个输入, 通用经过相同的隐藏层结构,获得输出。但这次,输入不但来自于第二个单词Potter,
    还有一个来自上一个单词隐藏层中出来的信息(一般叫做激活值)(a)作为输入;
    同理,接着是输入第3个词and, 同样也会输入来自第二个词的激活值;以此类推,直到最后一个词;
    另外,第一个单词前面也需要一个激活值,这个可以人为编造,可以是0向量,也可以是用一些方法随机初始化的值。
    在这里插入图片描述
    词一个一个输入的,可以看成每个时间输入一次,所有输入的隐藏层是共享参数的。设输入层到隐藏层到参数为(W_{ax}),激活值到隐藏层到参数记为(W_{aa}).
    根据以上结构,显而易见,第一次输入的单词会通过激活值影响下一个单词的预测,甚至影响接下去的所有单词的预测,这就是循环神经网络。

    (3)前向传播

    在这里插入图片描述
    (a^{<0>})是人为初始化的到的;
    (x^{<1>})是t=1时刻的输入;
    输入层的权重是(W_{ax});
    激活层的权重是(W_{aa});
    输出层的权重是(W_{y1});

    要计算的是每个时刻的激活值(a^{<t>})与输出值(y^{<t>})
    (a^{<1>})的计算:
    在这里插入图片描述
    (hat{y}^{<1>})的计算
    在这里插入图片描述
    g()是一个激活函数,通常选用tanh,有时也是用relu用于避免梯度弥散。若是输出是2分类,往往采用sigmoid作为激活函数,因为本例中是要判别是否为实体店而分类,因此采用sigmoid函数。
    扩展的一般情况(a^{<t>})与输出值(hat{y}^{<t>})如下计算:
    在这里插入图片描述

    (4)简化RNN表示

    其中(W_a)(W_{aa})(W_{ax})的左右拼接,若(W_{aa})纬度10010000,(W_{ax})纬度10010000,则组合后(W_{a})纬度是100*10100
    在这里插入图片描述
    同理第二个公式也简化成:
    在这里插入图片描述

    四.RNN中的时间反向传播

    (1)回顾前向传播

    回顾前向传播算法,有一个长度为(T_x)的序列
    在这里插入图片描述
    通过输入的(x),可以求出每一个时间上的激活值(a):

    回顾上一节,时间(t)上的激活值(a)是由(t-1)时刻的(a),与(t)时刻的输入(x)乘以参数而得:
    (a^{<t>}=g(W_{aa}a^{<t-1>}+W_{ax}x^{<t>}+b_a)) ====>>(a^{<t>}=g(W_{a}[a^{<t-1>},x^{<t>}]+b_a))

    每一个时间上的运算都是共享一组参数(W_a),(W_b),如下:
    在这里插入图片描述

    接着,计算RNN的输出y:

    同样,回顾y是通过当前时刻的激活值与参数相乘的到的:
    在这里插入图片描述

    每一时刻的计算也是共享了一组参数(W_y)
    在这里插入图片描述
    于是前向传播就完成了。

    (2)损失函数 loss function

    前向传播的过程是反向传播的基础, 而为了计算反向传播,还需要定义一个损失函数。
    此处使用交叉熵损失函数

    • 首先计算每个时间t上的损失,即计算序列中单次输入x,计算得到y的损失L( )
    • 接着计算总的损失,即计算所有时间上的损失的总和

    (3)反向传播

    将损失函数对各个参数求导,利用梯度下降法更新参数,红色箭头表示反向传播的过程
    在RNN中的反向传播亦叫时间反向传播back propogation through time

    五.RNN的不同类型

    (1)多对多

    命名实体识别中,输入的序列与输出的序列都有多个元素,且长度相同,称之为many-to-many结构,多对多结构。
    1】输入输出序列长度一致
    在这里插入图片描述
    2】多对多也可以实现输入与输出序列长度不等的情况,最常见的是机器翻译,先来看看结构:
    在这里插入图片描述
    模型由2部分组成,前面一部分叫做encoder(编码), 将要翻译的文本序列逐次输入,但不产生输出;后一部分叫做decoder(解码),编码器的输出是解码器的输入,
    而接下去的每个时间上都不再有输入,但每次都会有一个输出。解码器输出的序列就是对编码器输出序列的翻译。

    (2).多对一

    文本情感分析中,输入的是文本的序列,每个词都是一个输入,而输出的往往是类别标签,比如给电影的评价等级分为5档,或者判别文章正面情感与负面情感的2档。
    在这里插入图片描述
    最后一个时间上会有y输出,而其他时间上都不再有y输出。这种结构叫做many-to-one结构,多对一结构。

    (3).一对多

    比如音乐生成的例子,输出的是一段音符的序列,而输入的可以是整数,表示你想要的音乐风格,或者是第一个音符,表示你想要用这个音符开头,或者什么都不输入,让模型自由发挥。
    在这里插入图片描述
    首先,只在第一个时间有输入x,其他时刻都没有;
    其次,每一个时刻都会有输出,总的输出形成一个序列;
    要注意的是,有一个技术细节,通常用RNN生成序列的时候,会把前一个时刻的输出y也作为t时刻的输入,以上红色箭头表示。

    (4).总结

    在这里插入图片描述

    六.语言模型与序列生成 Language model and sequence generation

    (1)什么是语言模型?

    比如speech recognition语音识别,即将声音识别成文字(国内语音识别做得不错的是科大讯飞)。
    假如人说一句话“The apple and pear salad”,可以识别成以下两句话:
    在这里插入图片描述
    其中,pair与pear读音相同,显然第二句话才是正确识别说话人的意图。那要如何来选择最正确的句子呢?这就要用到语言模型了。
    语言模型计算出两句话概率:
    在这里插入图片描述

    显然第二句的概率是第一句概率的近100倍,因此选择第二句话。也就是说语言模型会给你任何一句的概率,从而可以根据概率来选择最有可能正确的句子。

    语言模型的应用目前有两大范畴,第一就是上面说的语音识别;第二就是机器翻译,同理,通过计算句子概率找到最正确的那句翻译。

    (2)怎么建立用RNN建立语言模型呢?

    1】首先要拥有一个训练集:巨大的语料库,越大越好
    2】对语料库进行标记化,在前面几节中提高过,根据语料库整理出一个词典,并用one-hot的词向量表示每个词。有三个注意点:
    A.一般会用的符号来表示句子的结尾
    B.对于之后新的文本中出现了语料库中未出现过的词,则将其用表示
    C.至于要不要将标点符号作为词典的一部分,这个看具体需求与问题来定夺。
    3】接着,建立RNN模型
    假设有这样一句话:
    在这里插入图片描述
    在第一个时间(t=1)时,输出的(x^{<1>})为0向量,因为第一个词之前没有词;激活值(a^{<0>})也初始化为0向量;如此计算后,得到的(y^{<1>})是softmaxt里出来的一个向量,
    其长度为词典的长度,每一个位置上的值都是对应词典中的词的概率。注意字典也包括(<EOS>),与(<UNK>)
    在这里插入图片描述
    在第二个时间(t=2)时,输入的(x^{<2>})实际上就是第一个单词(y^{<1>}:cat);通过softmax计算,同样会得到词典长度的概率分布向量,这个概率是(P(Word / cat))即前面为单词cat时,
    词典中每个词出现的条件概率。
    在这里插入图片描述
    以此类推,一直到最后一个时刻,输入的(x^{<9>}=y^{<8>}="day")
    在这里插入图片描述
    4】计算损失函数
    每次计算输出的概率分布时预测值,与实际值比较从而计算损失,对于单词次时刻,损失的公式为:
    在这里插入图片描述
    (i) 遍历词典,对词典中每个词的值进行汇总
    总的损失,是所有时间上的损失的和:
    在这里插入图片描述

    七.采样新序列 Sampling novel sequences

    当你训练好一个RNN之后,想要知道这个模型到底学到了什么呢?最基本的应用就是进行一次新序列采样,换一种说法,就是让RNN去随机生成一个新的序列。

    (1) 采样生成新序列过程

    假设我们用大量的英文语料根据如下过程训练出了一个RNN模型:

    接着我们要用这个训练好的RNN来采样生成一个新的序列。
    首先时刻t=1,仍然输入的是初始化的(x^{<1>}=0),(a^{<0>}=0),通过softmaxt的计算,会输出一个词典大小的概率分布向量,此时我们对这个向量进行采样,随机采出一个词作为输出(注意是随机,不是取最大概率)
    在这里插入图片描述
    接着来到了t=2时刻,此时的输入是上一个时间随机采样的词,同理对softmaxt概率分布随机采样,又采出了第二个词。
    在这里插入图片描述

    同理,每一个时间t,都取t-1点输出词作为输入,直到某个时刻的输出为,则采样终止。
    在这里插入图片描述

    当然有的时候会采样出,若是不想它出现,可以判断一下,若出现了则继续重新采样另一个词。

    (2) 基于字符的语言模型

    也有许多人尝试基于字的RNN模型,即每次的输入不再是一个单词,而是一个字母,字典里还包括空格,符号等等。但这有两个问题:
    第一:一句话有10-20个单词,但却有上百个字母,这使得序列的长度大大加大了,序列约长,则前面的词对后面的词传递的信息就会越来越弱,从而使词的依赖关系逐渐丧失。
    第二:训练起来会比较复杂和耗资源

    但是也有两个原因使得现在越累越多的应用中会尝试基于的RNN模型:
    第一:目前的计算能力越来越大
    第二:在某些领域中,有专有名词,而专有名词往往很稀少得不被词典包含,从而产生许多,而使用基于字母的字典结构,将不会遇到这个问题,因为再不常见的英文单词都是由24个字母组成。

    笔者:以上讲的是英文的应用,中文其实略有不同。
    首先英文的单词是被空格天然地分割,因此不会产生把一个单词错误地一劈为二的情况,但中文是没有任何符号表示单词与单词之间的分割,中文分词的瓶颈仍然是一大阻碍。因此,有时候尝试基于字的建模可能反而效果会比基于词的要好。

    基于字符的模型举例:
    根据news,用莎士比亚的样本训练后,模仿出莎士比亚的文笔
    在这里插入图片描述

    八.RNN的梯度弥散 Vanishing gradients with RNNs

    前面我们介绍了RNN的结构,前向传播与反向传播,RNN在命名实体、语言模型中的应用,这一节要讲述在构建RNN中会遇到的一个问题:梯度弥散问题。本节讲述什么是梯度弥散,后面几节会讲述如何解决这个问题。

    (1)什么是梯度弥散

    首先来看传统的深层神经网络:
    在这里插入图片描述

    假设这个网络很深,有1000层甚至更多,那么经过前向传播得到输出层的y之后,很难再通过梯度下降法将y的梯度传播回去,即后面的梯度很难影响前面的权重。

    对于RNN也是同样的道理,你已经很熟悉RNN的结构了:
    假设有两个训练样本,句子的长度非常长:
    The cat, with already ate…………, was full.
    The cats, with already ate…………, where full.
    第一个句子的was是依赖于cat, 第二个were是依赖于cats,但是这两个单词被隔得非常远,以至于后者的单词很难依赖于前者得到。

    因为,与传统的深层神经网络类似,经过前向传播之后,反向传播中后面的(y^{<t>})误差很难通过梯度影响到前面层的计算,因此当RNN在计算后面的单词was还是were的时候,对前面出现过的cat或cats已经忘得差不多了。

    也因此,其实每次的输出(y^{<t>}只能反向传播影响到前面附近的几层计算,也就是说,在训练时无论)y^{}的预测是正确的还是错误的,或者说损失是大是小,都无法通过反向传播告诉很前面的层,并且对前面的层有效调整权重。

    这是基本的RNN算法的一个缺点

    (2)梯度爆炸exploding gradients

    除了梯度弥散的问题,RNN也会遇到梯度爆炸的问题,但这个问题比较好解决,因此在这里顺带讲述。

    如何发现梯度爆炸?
    梯度爆炸很好发现,因为指数极大的梯度,会让你的参数变得极其大,以至于你的网络参数奔溃,你会看到很多NaN或者不是数字的情况,这说明你的网络出现了数值溢出。

    如何解决梯度爆炸?
    当发现梯度爆炸时,一个解决方式就是梯度修剪
    观察你的梯度向量,一旦发现超过某个阀值,就缩放梯度向量,保证他不会太大。比如通过一些最大值来修剪的方法

    九.GRU单元Gated Recurrent Unit

    上一节中讲了RNN有个梯度弥散的缺陷,难以捕捉深层依赖,于是,这一节要讲述一个解决该问题的方法,即在隐藏层加入GRU(Gated Recurrent Unit, 门控循环神经单元)。它可以捕捉深层链接,并大大改善梯度消散问题。

    (1) 前戏

    首先,回顾一下,我们之前讲的时间t上的神经元计算过程:
    在这里插入图片描述

    对于t时刻,有一个t-1时刻的激活值作为输入,有一个t时刻的x值作为输入,两个输入乘以各自的权重之后,作为激活函数tanh的输入,tanh的输出一边传给softmaxt层得到(y^{<t>}), 一边直接传给下一个时间。(a^{<t>})的公式如下:
    (a^{<t>}=g(W_a[a^{<t-1>},x^{<t>}] + b_a))

    (2) GRU的计算过程

    (1)首先我们用(C)表示记忆细胞,(C^{<t-1>})表示(t-1)时刻的记忆信息,在GRU中,你暂且认为(c^{<t>}=a^{<t>}),是层与层之间传递的激活值,只是计算过程略有不同。
    (2)同样,有两个输入,一个是上一层的(c^{<t-1>}), 一个是本时刻的输入(x^{<t>})
    (3)第一步计算:(c^{<t-1>})(x^{<t>})分别乘以各自的权重之后经过tanh激活函数,输出(hat{c}^{<t>})
    这个计算过程就相当于之前讲述的传统RNN计算过程,只是现在输出的c不是最终输出值,将它放在一边等待,我们来看另一步计算。
    在这里插入图片描述
    (4)第二步计算:可以看成是与第一步计算平行进行,将输入的(c^{<t-1>})(x^{<t>})分别乘以另一组权重,经过一个sigmoid函数,输出(Γ_u): sigmoid函数是分布在0与1之间,大部分值会非常接近0或着1.
    在这里插入图片描述
    (5)第三步计算:第一步与第二步计算中我们得到了两个值,一个来自于tanh函数,一个来自于sigmoid函数。这一步我们将这两个值整合如下,计算出最终的c
    在这里插入图片描述
    上一步可知,(Γ_u)是sigmoid函数的输出,因此大部分值会分布在0或者1的附近,假设(Γ_u=1),它与(hat{c})相乘之后,(hat{c})的信息被原封不动地保留下来了,而(c^{<t-1>})的信息被去除了;反之,若(Γ_u=0), 则该层原来的激活值(hat{c})被去除,而上一层的信息(c^{<t-1>})被全部保留。因此可以发现(Γ_u)其实就像是一个记忆门,由它决定是否需要记忆上一层的信息或着这一层的信息。
    (6)上面计算所得的(c^{<t>})为最终的激活值,继续按照老套路,一边传给softmaxt函数输出(y^{<t>}), 一边传给下一层神经元

    以上就是GRU的整个过程,或者说是一个简化版的GRU。

    (3) GRU的优点

    (1)大部分时候,其实(Γ_u)是为0的,那么其实大部分时候(c^{<t>}=c^{<t-1>})这非常有利于维持细胞的值
    (2)由于大部分时候(c^{<t>}=c^{<t-1>}),因此就一定程度上解决了梯度弥散的问题,深处的神经元也可依赖到很前面的信息,可以使神经网络运行在很深的层次上

    (4) 更复杂一点的GRU

    上面讲的GRU是简单版本的,在实际应用中的GRU会更复杂,接下去详细讲述。

    首先,上面的公式回顾一下:
    在这里插入图片描述
    在上面的公式的基础之上做一些改变:
    (1)(hat{c})的计算中加上一个另一个门(Γ_r):
    在这里插入图片描述
    可以看成是一个表示相关性的门,将它乘以(c^{<t-1>})表示(hat{c})(c^{<t-1>})有多大的相关性,即有(c^{<t-1>})向量中有哪些位置上的信息相关性大则保留得更多。
    (2)计算(Γ_r)的公式如下:
    在这里插入图片描述

    嗯嗯,就结束了。

    (5) 总结

    研究者们前赴后继地寻找着探索着更优的神经单元结构来使得RNN有更好的深层次依赖能力,来解决梯度弥散等问题,GRU算是一个非常标准或者基础,且被学术界和工业界广泛使用的结构,当然你也可以自己去探索出更优的结构。下一节将讲述另一个非常常用的RNN结构:LSTM。

    十.长短时记忆单元LSTM unit (long short term memory)

    上一节中学习了GRU,能够有效避免梯度弥散,而这一节要学习的LSTM,可谓是比GRU有更大的能力,因此也备受业界喜爱。

    首先我们从图形上直观地看一下LSTM unit的运行结构:
    在这里插入图片描述

    第一步:忘记门

    先来看上图中最左边的这块运算,
    在这里插入图片描述
    首先下方有一个叫做forget gate的小方块,它有两个输入,一个是上一个时刻的(a^{<t-1>}),另一个输入是这一个时刻的(x^{<t>}).
    接着这两个输入会各自乘以一组权重,并且进入一个sigmoid函数得到(Γ_f)
    在这里插入图片描述
    这个运算叫做忘记门,权重w里存储的是哪些信息对应的位置应该被忘记,这样不重要的信息,或者对之后的预测没有用的信息就可以被过滤掉。

    第二步:记忆门

    在这里插入图片描述
    接着看到update gate的小方块,叫做记忆门,与上面的忘记门对比显然可猜测,这个门的运算应该是为了能够更新一些信息。
    输入也是(a^{<t-1>})(x^{<t>}), 将它们乘以一组权重之后,也进入一个sigmoid函数,得到(Γ_u),即被更新的信息
    在这里插入图片描述

    第三步:输出门

    在这里插入图片描述
    直接看输出门的计算:
    在这里插入图片描述
    和上面几个门是一样的,无非是换了一组参数

    第四步:

    在这里插入图片描述
    (a^{<t-1>})(x^{<t>})这两个输入还会乘以第四组权重,并且过一个(tanh)激活函数,得到(hat{c}^{<t>}):

    可以看到,以上讲的四部运算,刚好是第一张全图的下面4个小框:

    第五步:计算c

    在这里插入图片描述
    来看黄色圈出来的这块区域,圆圈里的星号表示乘法运算,加号表示求和运算。第一个乘号分别由两个箭头指向,分别是上一个时刻的c,以及第一步中计算得到的忘记门Γf;第二个乘号也分别由两个箭头指向,分别是第二部计算中得到的更新门Γu,以及c_mao.中间的加号,将两边的乘积求和。
    在这里插入图片描述

    第六步:计算a

    在这里插入图片描述
    在这里插入图片描述

    第七步:输出

    一个LSTM unit的输出有两个,分别是第5步与第6步计算的(c^{<t>})(a^{<t>})(注意与GRU的区别,GRU中(c^{<t>}=a^{<t>})).
    (c^{<t>})会直接输给下一个时刻t+1, 它是由忘记门与更新门共同作用的,承载着滚滚黄河中前朝往事的记忆,让来世代代后人不忘初心。
    (a^{<t>})由两个方向的输出,一方面它会输给本时刻的softmax层去得到(y^{<t>}), 另一方面,它也会作为下一个时刻的输入。

    将一个LSTM unit链接起来就是酱紫的:
    在这里插入图片描述

    红线的路径就是c的流动路线,和GRU一样,它能够掌握时间维度上的深层依赖,使得后面的计算仍然能参考到前面的信息。

    上面讲述的是基础的LSTM的结构,在其他文献或者博客中你可能还会看到一个不同点,即会多一个门,叫做偷窥门。即在忘记门,更新门,输出门计算的时候,会增加一个(c^{<t-1>})作为输入,以偷窥前面的记忆。:
    在这里插入图片描述
    公式的变动上,只是在三个门中多输入一个(c^{<t-1>})即可,其他并无差别。

    结束语:

    无论是上一节讲述的GRU,还是这一节讲述的LSTM并不是由于它们是什么高深的算法,所以要特地拿出来讲,而是因为它们确确实实地被广泛地应用在了业界,是算法工程师们的头号青睐对象。
    LSTM比GRU提出地更早,GRU的效果没有LSTM好,但是其结构简单,计算复杂度低,适合于很复杂的深层网络;LSTM效果更好,但是结构略复杂。
    不过如果你硬要在建模的时候推荐一个,那么还是建议先使用LSTM哈哈。

    十一.双向神经网络Bidirectional RNN

    到目前为止,已经掌握了RNN的主要构件,但还有两个很重要的知识,能够帮助你的RNN产生更好的效果,一个就是双向RNN,另一个是深层RNN。本节将讲述双向RNN的内容。

    (1)Why BRNN?

    顾名思义,双向RNN,即可以从过去的时间点获取记忆,又可以从未来的时间点获取信息。那么我们为什么要获取未来的信息呢?还是以一开始的例子实体识别来看,假设以下两个句子,第一句话中的teddy是一只熊,非实体,第二句话中的Tedddy是一个人,是人名实体,但是仅仅是依靠这个单词前面的内容,完全无法判别它们的差异,而要继续看了后面的内容,才知道,原来第一句话讲的是bear, 第二句话将的是president.
    在这里插入图片描述
    因此,未来时间点的信息也对当前的预测起着至关重要的作用,双向RNN可以有效解决这个问题。

    (2) How BRNN?

    那么双向RNN到底是如何运作的呢?
    在这里插入图片描述
    双向RNN在RNN基础之上,在每一个时间上增加了一个新的激活单元;
    同样,新增的激活单元也会向上连接;
    最重要的是,绿色的新增激活值会向左传递,由时间t传给时间t-1;

    这样就构成了一个无环图,输入一个序列,计算的过程是这样的:
    (1)前向和反向的计算会同时异向进行
    前向从计算(a^{<1>})(a^{<2>})(a^{<4>}),同时反向从(a^{<4>})(a^{<1>})
    (2)两个方向的激活值都计算完毕后,就可以计算输出值(y)

    (y^{<3>})输出为例,在双向RNN中,它说到前面时间1,2的影响,即(x^{<1>}),(x^{<2>})的影响,同时又受到了后面信息(x^{<4>})的影响。
    注意,以上的神经元,不仅仅可以是标准的RNN单元,还可以是GRU,LSTM等。事实上,双向 LSTM RNN用得是最广泛的。
    总之,双向RNN避免了只听半语就妄下定论的不良习性,对事物有全盘了解之后再做决断,偏听则暗,兼听则明。

    十二.深层循环神经网络Deep RNN

    本节要讲的是深层循环神经网络。又可以顾名思义了,深层,那肯定是在原来的基础之上多加了几层而已。

    (1) Deep RNN 的结构

    只有一层的循环神经网络如下:
    在这里插入图片描述
    那么深层,其实就是这样:
    在这里插入图片描述
    上面是一个3层的循环神经网络,其中(a^{[1]<0>})表示第1层的第0时刻的激活值。

    (2) Deep RNN 激活值的计算

    那么这些激活值是怎么计算的呢?以(a^{[2]<3>})为例,它有两个输入:
    一个来自是当前时刻的,前一层的输出;
    一个是来自前一时刻,同层的输出。
    公式如下:
    在这里插入图片描述
    其中(W^{[2]}_a)(b^{[2]}_a)是指第二层的权重,整个第二层都共享这组权重

    (3)深层?

    以上介绍了一个有3个隐藏层循环神经网络,但是只有3层,你确定可以叫“深层”吗?
    额,是的,对于RNN来说,3层已经深得不容易了。由于时间的维度,就算只有恨少的层次,RNN的网络会变得异常大。你很少会见到向卷积神经网络那样堆叠到几十层甚至一百层的RNN。

    但是如果你说,不行不行不行,人家就要放很深很深的层,那好,可以这样放:
    也就是说,在3层的RNN基础之上,将每个时刻输出的y再进入一个深层的普通神经网络,注意这些神经元之间没有横向的连接。
    在这里插入图片描述
    同样,深层RNN中的神经单元也可以用GRU,LSTM等。

    参考文献

    [1]【序列模型】第一课--循环序列模型](https://blog.csdn.net/sinat_33761963/article/details/80195636)

  • 相关阅读:
    Spring框架(二)
    Spring概况(一)
    唉 规整规整 进阶目录
    网络编程 -- RPC实现原理 -- 目录
    基础大杂烩 -- 目录
    艺多不压身 -- 目录
    延伸 -- 分类 -- 目录
    Eclipse 快捷键
    全局
    深入浅出MySQL++数据库开发、优化与管理维护+第2版+唐汉明 -- 存储引擎
  • 原文地址:https://www.cnblogs.com/nxf-rabbit75/p/9898589.html
Copyright © 2020-2023  润新知