Press "Enter" to skip to content

深度学习——循环神经网络

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

循环神经网络

 

为什幺要引入循环神经网络

 

怎样才能建立一个模型,建立一个神经网络来学习푋到푌的映射?可以尝试的方法之一是 使用标准神经网络 ,在我们之前的例子中,我们有 9 个输入单词。想象一下,把这 9 个输入单词,可能是 9 个 one-hot 向量,然后将它们输入到一个标准神经网络中,经过一些隐藏层,最终会输出 9 个值为 0 或 1 的项,它表明每个输入单词是否是人名的一部分。

 

但结果表明这个方法并不好,主要有两个问题:

 

 

    1. 输入和输出数据在不同例子中可以有不同的长度 ,不是所有的例子都有着同样输入长度푇푥或是同样输出长度的푇푦。即使每个句子都有最大长度,也许你能够填充(pad)或零填充(zero pad)使每个输入语句都达到最大长度,但仍然看起来不是一个好的表达方式。

 

    1. 它并不共享从文本的不同位置上学到的特征 ,具体来说,如果神经网络已经学习到了在位置 1 出现的 Harry 可能是人名的一部分,那幺如果Harry 出现在其他位置,比如푥<푡>时,它也能够自动识别其为人名的一部分的话,这就很棒了。

 

    1. 之前我们提到过这些(上图编号 1 所示的푥<1>……푥<푡>……푥<푇푥>)都是 10,000 维的 one-hot 向量,因此这会是十分庞大的输入层。如果总的输入大小是最大单词数乘以 10,000,那幺第一层的权重矩阵就会有着巨量的参数。

 

 

什幺是循环神经网络?

 

如果你以从左到右的顺序读这个句子,第一个单词就是,假如说是 푥<1> ,我们要做的就是 将第一个词输入一个神经网络层 ,我打算这样画,第一个神经网络的隐藏层,我们可以让神经网络尝试预测输出,判断这是否是人名的一部分。循环神经网络做的是, 当它读到句中的第二个单词时 ,假设 푥<2> , 它不是仅用푥<2>就预测出푦^<2>,他也会输入一些来自时间步 1 的信息 。具体而言,时间步 1 的激活值就会传递到时间步 2。然后,在下一个时间步, 循环神经网络输入了单词푥<3> ,然后它尝试预测输出了预测结果푦

 

<3>,等等,一**直到最后一个时间步,输入了푥<푇푥>**,然后输出了푦

<푇푦>。至少在这个例子中푇푥 = 푇푦,同时如果푇푥和푇푦不相同,这个结构会需要作出一些改变。所以
在每一个时间步中,循环神经网络传递一个激活值到下一个时间步中用于计算

在零时刻需要构造一个激活值푎<0>,这通常是零向量。有些研究人员会随机用其他方法初始化푎<0>,不过使用零向量作为零时刻的伪激活值是最常见的选择,因此我们把它输入神经网络。

 

在每一个时间步中,你输入푥<푡>然后输出푦<푡>。然后为了表示循环连接有时人们会像这样画个圈,表示输回网络层, 有时他们会画一个黑色方块,来表示在这个黑色方块处会延迟一个时间步 (像上图最右边的循环神经网络)

 

循环神经网络是从左向右扫描数据,同时每个时间步的参数也是共享的,我们用 푊ax 来 表示管理着从푥<1>到隐藏层的连接的一系列参数 ,每个时间步使用的都是相同的参数푊ax。而 激活值也就是水平联系 是由参数 푊푎푎 决定的,同时每一个时间步都使用相同的参数푊푎푎,同样的 输出结果 由 푊ya 决定。在这个循环神经网络中,它的意思是**在预测푦

 

<3>时,不仅要使用푥<3>的信息,还要使用来自푥<1>和푥<2>的信息**,因为来自푥<1>的信息可以通过这样的绿色的路径来帮助预测푦

<3>。

这个网络的缺点是: 它只使用了这个序列中之前的信息来做出预测 ,尤其当预测푦^<3>时,它没有用到푥<4>,푥<5>,푥<6>等等的信息。所以这就有一个问题,因为如果给定了这个句子,“Teddy Roosevelt was a great President.”,为了判断 Teddy是否是人名的一部分,仅仅知道句中前两个词是完全不够的, 还需要知道句中后部分的信息 ,这也是十分有用的,因为句子也可能是这样的,“Teddy bears are on sale!”。因此如果只给定前三个单词,是不可能确切地知道 Teddy 是否是人名的一部分,第一个例子是人名,第二个例子就不是,所以你不可能只看前三个单词就能分辨出其中的区别。解决方法就是 双向循环神经网络 。

 

循环神经网络的前向计算

 

这里是一张清理后的神经网络示意图,和我之前提及的一样,一般开始先输入푎<0>,它是一个零向量。接着就是 前向传播过程 ,先计算激活值푎<1>,然后再计算푦<1>。 푎<1> = 푔1(푊푎푎푎<0> + 푊푎푥푥<1> + 푏푎) , 푦^<1> = 푔2(푊푦푎푎<1> + 푏푦) 我将用这样的符号约定来表示这些矩阵下标,举个例子푊ax, 第二个下标意味着푊ax要乘以某个푥类型的量,然后第一个下标푎表示它是用来计算某个푎类型的变量 。同样的,可以看出这里的푊ya乘上了某个푎类型的量,用来计算出某个푦^类型的量。

 

循环神经网络用的激活函数经常是 tanh,不过有时候也会用 ReLU,但是 tanh 是更通常的选择,如果它是一个二分问题,那幺我猜你会用 sigmoid 函数作为激活函数,如果是푘类别分类问题的话,那幺可以选用 softmax 作为激活函数。不过这里激活函数的类型取决于你有什幺样类型的输出푦,对于命名实体识别来说푦只可能是 0 或者 1,那我猜这里第二个激活函数푔可以是 sigmoid 激活函数。

 

更一般的情况下,在푡푎时刻,

<푡> = 푔1(푊푎푎푎<푡−1> + 푊푎푥푥<푡> + 푏푎)
푦^<푡> = 푔2(푊푦푎푎<푡> + 푏푦)

所以这些等式定义了神经网络的前向传播,你可以从零向量푎<0>开始,然后用푎<0>和 푥<1>来计算出푎<1>和푦

 

<1>,然后用푥<2>和푎<1>一起算出푎<2>和푦

<2>等等,像图中这样,从左到右完成前向传播。

接下来为了简化这些符号,我要将这部分 (푊aa푎<푡−1> + 푊ax푥<푡>) 以更简单的形式写出来,我把它写做 푎<푡> = 푔(푊푎[푎<푡−1>, 푥<푡>] + 푏푎) ,那幺左右两边划线部分应该是等价的。所以我们定义 푊푎 的方式是 将矩阵푊푎푎和矩阵푊푎푥水平并列放置 , [푊푎푎 ⋮ 푊푎푥] = 푊푎 。举个例子,如果푎是 100 维的,然后延续之前的例子,푥是 10,000 维的,那幺푊푎푎就是个(100,100)维的矩阵,푊푎푥就是个(100,10,000)维的矩阵,因此如果将这两个矩阵堆起来,푊푎就会是个(100,10,100)维的矩阵。

 

符号([푎<푡−1>, 푥<푡>])的意思是将这两个向量堆在一起.

 

你可以自己检查一下,用这个矩阵乘以这个向量,刚好能够得到原来的量,因为此时, 矩阵[푊푎푎 ⋮ 푊푎푥]乘以[푎<푡−1> 푥<푡> ],刚好等于푊푎푎푎<푡−1> + 푊푎푥푥<푡> ,刚好等于之前的这个结论。

 

同样对于这个例子( 푦^<푡> = 푔(푊푦푎푎<푡> + 푏푦) ),我会用更简单的方式重写,푦^<푡> = 푔(푊푦푎<푡> + 푏푦)。现在푊푦和푏푦符号仅有一个下标,它表示在计算时会输出什幺类型的量,所以푊푦就表明它是计算y类型的量的权重矩阵,而上面的푊푎和푏푎则表示这些参数是用来计算푎类型或者说是激活值的。

 

循环神经网络的反向计算

 

我们来分析一下 前向传播的计算 ,现在你有一个输入序列,푥<1>,푥<2>,푥<3>一直到푥<푇푥>,然后用푥<1>还有푎<0>计算出时间步 1 的激活项,再用푥<2>和푎<1>计算出푎<2>,然后计算푎<3>等等,一直到푎<푇푥>。

 

为了真正计算出푎<1>,你还需要一些参数, 푊푎푏푎 ,用它们来计算出 푎<1> 。这些参数在之后的每一个时间步都会被用到,于是继续用这些参数计算푎<2>,푎<3>等等,所有的这些激活项都要取决于参数푊푎和푏푎。有了푎<1>,神经网络就可以计算第一个预测值푦

 

<1>,接着到下一个时间步,继续计算出푦

<2>,푦^<3>,等等,一直到푦^<푇푦>。
为了计算出푦^ ,需要参数
푊푦
푏푦 ,它们将被用于所有这些点。

然后为了 计算反向传播 ,你还需要一个 损失函数 。我们先定义一个元素损失函数

퐿<푡>(푦^<푡> , 푦<푡>) = −푦<푡>log 푦^<푡> − (1 − 푦^<푡>)푙표푔(1 − 푦^<푡>)

它对应的是 序列中一个具体的词 ,如果它是某个人的名字,那幺푦<푡>的值就是 1,然后神经网络将输出这个词是名字的概率值,比如 0.1。我将它定义为标准逻辑回归损失函数,也叫 交叉熵损失函数 (Cross Entropy Loss)。这是关于单个位置上或者说某个时间步푡上某个单词的预测值的损失函数。

 

现在我们来 定义整个序列的损失函数 ,将퐿定义为

퐿(푦^ , 푦) = ∑퐿<푡>(푦^<푡> , 푦<푡>) 푇푥 푡=1

在这个计算图中, 通过푦^<1>可以计算对应的损失函数 ,于是计算出第一个时间步的损失函数, 然后计算出第二个时间步的损失函数 ,然后是 第三个时间步 ,一直到最后一个时间步,最后为了计算出总体损失函数,,我们要把它们都加起来,计算出最后的L。

 

反向传播算法需要在相反的方向上进行计算和传递信息,最终你做的就是 把前向传播的箭头都反过来,在这之后你就可以计算出所有合适的量,然后你就可以通过导数相关的参数,用梯度下降法来更新参数。

 

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。