领取你的递归神经网络的入门教程!
介绍
人类不会每秒从头开始思考。当你阅读这篇文章时,你会根据你对前面的单词的理解然后去理解之后认识的每个单词。你不会丢掉所有东西,然后再次从头开始思考,通常想法都是有持续性的。
传统的神经网络无法做到这一点,这似乎是一个主要的缺点。例如,假设你想分类电影中每个点发生的事件类型。目前还不清楚传统神经网络如何利用其对电影中之前事件的推理来未后来的事件提供信息。
递归神经网络解决了这个问题。他们具有循环的网络,允许信息持久。
在上图中,一组神经网络A查看一些输入xt并输出一个值ht。循环允许信息从网络的一个步骤传递到下一个步骤。经常性神经网络可以被认为是同一网络的多个副本,每个副本都会将消息传递给后继者。考虑如果我们展开循环会发生什么:
这种链式性质揭示了递归神经网络与序列和列表密切相关。它们是用于这种数据的神经网络的自然架构。他们当然可以使用。在过去的几年中,RNN应用于各种问题取得了令人难以置信的成功:语音识别、语言建模、翻译、图像字幕......
虽然它不是强制性的,但对读者来说,理解WordVectors是什么会有好处,这是一种创建Word矢量的技术。
什么是递归神经网络
“香草”型神经网络(以及卷积网络)的显著局限在于它们的API太受限制:它们接受固定大小的向量作为输入(例如图像)并产生固定大小的向量作为输出(例如,不同类别的概率)。不仅如此:这些模型使用固定数量的计算步骤(例如模型中的层数)执行该映射。
经常性网络更令人兴奋的核心原因是它们允许我们对矢量序列进行操作:输入序列、输出或最一般情况下的序列。
一些例子可能会使这个更具体:
每个矩形都是一个矢量,箭头表示函数(例如矩阵乘法)。输入矢量为红色,输出矢量为蓝色,绿色矢量为RNN状态(稍后会详细介绍)。
从左到右:
无RNN的Vanilla处理模式,从固定尺寸输入到固定尺寸输出(例如图像分类)。
序列输出(例如图像字幕拍摄图像并输出一个单词的句子)。
序列输入(例如,将给定句子分类为表达正面或负面情绪的情绪分析)序列输入和序列输出(例如,机器翻译:RNN读取英文句子,然后输出法语句子)。
同步序列输入和输出(例如,我们希望标记视频的每个帧的视频分类)。
请注意,在所有情况下,长度序列都没有预先指定的约束,因为经常变换(绿色)是固定的,并且可以按照我们的喜好多次应用。
我们稍后会看到,RNN将输入向量与它们的状态向量组合起来,形成一个固定的(但是学习到的)函数,以产生一个新的状态向量。
RNN计算
那么这些事情是如何工作的?
他们接受一个输入向量x并给出一个输出向量y。然而,关键的是,这个输出向量的内容不仅受到刚刚输入的影响,还受到过去输入的整个历史记录的影响。作为一个类,RNN的API由一个单步函数组成:
RNN类具有一些内部状态,每次调用该步时都会进行更新。在最简单的情况下,这个状态由单个隐藏向量h组成。下面是Vanilla RNN中step函数的实现:
以上指定了“香草”型RNN的正向传球。这个RNN的参数是三个矩阵
W_hh:基于前一个隐藏状态的矩阵
W_xh:基于电流输入的矩阵
W_hy:基于隐藏状态和输出之间的矩阵
隐藏状态self.h用零矢量初始化。 np.tanh(双曲正切)函数实现将激活压缩到范围[-1,1]的非线性。
所以它是如何工作的:
tanh中有两个术语:一个基于前一个隐藏状态,另一个基于当前输入。在numpy中,np.dot是矩阵乘法。两个中间体与加法相互作用,然后被tanh压扁成新的状态向量。
隐藏状态更新的数学表示法是 -
tanh在元素上应用。
我们用随机数初始化了RNN的矩阵,并且在训练过程中的大部分工作都是寻找产生理想行为的矩阵,如用一些损失函数来衡量的,这些损失函数表示您希望得到的输出类型。
那么我们现在深入进行
换句话说,我们有两个独立的RNN:一个RNN正在接收输入矢量,第二个RNN正在接收第一个RNN的输出作为其输入。
简单地提一下,在实践中,我们大多数人使用的方式与上面提到的长期短期记忆(LSTM)网络略有不同。 LSTM是一种特殊类型的循环网络,由于其更强大的更新方程和一些吸引人的后向传播动态,在实践中效果稍好。
一个例子 - 字符级语言模型
我们将训练RNN字符级语言模型。也就是说,我们会给RNN大片的文本,并要求它给出一系列先前字符序列中下一个字符的概率分布。这将允许我们一次生成一个新字符。
具体而言,我们将使用1-k编码将每个字符编码为一个矢量(即,除词汇表中字符索引处的单个字符以外的所有零),然后使用帮助一次将它们送入RNN的一个步骤功能。然后,我们将观察一系列4维输出向量(每个字符一个维度),我们将其解释为RNN当前分配给序列中接下来每个字符的置信度。这是一张图表:
例如,我们看到,在RNN看到字符“h”的第一个时间步中,它给1.0的下一个字母为“h”,2.2为字母“e”,-3.0至“l”和4.1到“o”。由于在我们的训练数据(字符串“hello”)中,下一个正确的字符是“e”,我们希望增加其信心(绿色)并降低所有其他字母(红色)的置信度。
由于RNN完全由可微分操作组成,因此我们可以运行反向传播算法(这只是递归应用来自演算的链式规则),以找出我们应该调整的每一个权重的方向,以增加分数正确的目标(绿色粗体数字)。
然后,我们可以执行参数更新,就可以在这个梯度方向上轻轻推动每个权重。如果我们在参数更新之后向RNN提供相同的输入,我们会发现正确字符的分数(例如,第一个时间步中的“e”)会略高(例如2.3而不是2.2),不正确字符的分数会略低。
然后我们多次重复这个过程,直到网络收敛,并且预测最终与训练数据一致,因为正确的字符总是接下来预测的。
更技术性的解释是我们在每个输出向量上同时使用标准的Softmax分类器(通常也称为交叉熵损失)。 RNN使用小批量随机梯度下降进行训练。
还要注意,第一次输入字符“l”时,目标是“l”,但第二次目标是“o”。因此,RNN不能单独依靠输入,并且必须使用其循环连接来跟踪上下文以实现此任务。
在测试的时候,我们会向RNN提供一个角色,并分配下一个可能出现的角色。