附录2:循环神经网络RNN和长-短时记忆网络LSTM
附录2:循环神经网络RNN和长-短时记忆网络LSTM
循环神经网络RNN
CNN比较适合处理图像,因为每幅图像之间都没有太多相关性,所以可以一幅一幅地输入CNN里。但许多非图像信息例如语音、天气预报、股市等是一个连续的数值序列,不仅无法截成一段一段地输入,前后之间还有很强的相关性。例如我们在下面句子里猜词填空:“我是上海人,会讲————话。”在这里如果我们没有看到第一句“我是上海人”就很难填空。处理这一类问题最有效的神经元网络叫循环神经网络。图附2.1是一个最简单的RNN。
图附2.1最简单的RNN
这里X 是t时刻的输入向量,A是神经元网络,h 是t时刻的输出。注意到方框A有一个自我反馈的箭头,网络A下一时刻的状态依赖于上一时刻的状态,这是RNN和CNN及全连接网络的最大的区别。为了更清楚地理解图附2.1,我们可以把每个离散时间网络的状态都画出来生成图附2.2。
图附2.2把RNN从时间上展开看
这个链状结构展现出RNN与列表、数据流等序列化数据的密切关系,而这类数据的处理也确实在使用RNN这样的神经网络。在过去几年中,将RNN应用于很多问题后,已经取得了难以想象的成功,例如语音识别、语言建模、翻译、图像抓取等,而它所涉及的领域还在不断地增加。
现在我们已经知道了RNN是什么,以及基本的工作原理。下面我们通过一个有趣的例子来加深对RNN的理解:训练一个基于字符的RNN语言模型。我们的做法是,给RNN“喂”大段的文字,要求它基于前一段字符建立下一个字母的概率分布,这样我们就可以通过前一个字母预测下一个字母,这样可以一个字母一个字母地生成新的文字。
举一个简单的例子,假设我们的字母库里只有4个字母可选:“h”“e”“l”“o”,我们想训练出一个能产生“hello”顺序的RNN,这个训练过程事实上是4个独立训练的组合。
(1)给出字母“h”后,后面大概率是字母“e”。
(2)给出字符“he”后,后面大概率是字母“l”。
(3)给出字符“hel”后,后面大概率还是字母“l”。
(4)给出字符“hell”后,后面大概率是字母“o”。
具体来说,我们可以将每个字母编码成一个向量,这个向量除了该字母顺序位是1,其余位置都是0(例如对于“h”而言,第一位是1,其余位置都是0,而“e”则第二位是1,其余位置是0)。之后我们把这些向量一次一个地“喂”给RNN,这样可以得到一个四维输出向量序列(每个维度对应一个字母),这个向量序列我们可以认为是RNN目前认为每个字母即将在下一个出现的概率。
图附2.3是一个输入和输出层为4维,隐含层为3个单元(神经元)的RNN。图中显示了当RNN被“喂”了字符“hell”作为输入后,前向传递是如何被激活的。输出层包括RNN为下一个可能出现的字母(字母表里只有h、e、l、o 4个字母)所分配的概率,我们希望输出层加粗的数越大越好,输出层其他的数越小越好。例如,我们可以看到在第一步时,RNN看到字母“h”,它认为下一个字母是“h”的概率是1.0,是“e”的概率是2.2,是“l”的概率是-3.0,是“o”的概率是4.1。由于在我们的训练数据(字符串“hello”)中,正确的下一个字母是“e”,所以我们希望提升“e”的概率,同时降低其他字母的概率。同样地,对于4步中的每一步,我们都希望网络能提升对某一个目标字母的概率。由于RNN完全由可分的操作组成,因此我们可以采用反向传播算法来计算出我们应该向哪个方向调整每一个权量,以便提升正确目标的概率(输出层里的加粗数字)。
图附2.3 RNN学习“hello”语句的训练过程
接下来我们可以进行参数调整,即将每一个权值向着刚才说的梯度方向微微调整一点,调整之后如果还将刚才那个输入字符“喂”给RNN,我们就会看到正确字母(例如第一步中的“e”)的分值提高了一点(例如从2.2提高到2.3),而其他字母的分值降低了一点。然后我们不断地重复这个步骤,直到整个网络的预测结果最终与训练数据一致,即每一步都能正确预测下一个字母。需要注意的是,第一次字母“l”作为输入时,目标输出是“l”,但第二次目标输出就变成了“o”,因此RNN不是仅仅根据输入判断,而是使用反复出现的关系来了解语言环境,以便完成任务。
LSTM:记忆增强版RNN
RNN可以根据前一个字母预测出下一个字母。但有时候可能需要更前面的信息,例如我们要填空“我在上海出生,一直待到高中毕业,所以我可以讲————话”。此时如果没有看到第一句“我在上海出生”就猜不到填空的内容。为了解决这个问题,人们对RNN进行了改造,使其可以有更长的记忆。这就是长-短时记忆网络(LSTM)。
所有的RNN都是链状的、模块不断重复的神经网络,标准的RNN中,重复的模块结构简单。如图附2.4所示,每个模块由单个的tanh层组成。
图附2.4在标准的RNN中,重复的模块是单层结构
LSTM也是链状的,和RNN相比,其重复模块中的神经网络并非单层,而是有4层,并且这4层以特殊的形式相互作用。(见图附2.5)
图附2.5在LSTM中,重复模块中含有相互作用的4层神经网络
在图附2.5中,σ(希腊字母sigma)是sigmoid函数,其定义如下:
这个sigmoid函数的图形如图附2.6所示。
图附2.6 sigmoid函数的图形
tanh函数是sigmoid函数的放大平移版,它们之间的关系如下:
tanh(x)=2σ(2·x)-1
图附2.7 sigmoid函数和tanh函数曲线
不要被上面这么多复杂的东西吓着,我们等一下会详述LSTM的结构。从现在开始,请试图熟悉和适应我们将使用的一些符号。
在图附2.8中左起,长方形表示已经学习的神经网络层;圆圈代表逐点运算,就像向量加法;单箭头代表一个完整的向量,从一个节点的输出指向另一个节点的输入;合并的箭头表示关联;分叉的箭头表示同样的内容被复制并发送到不同的地方。
图附2.8 LSTM中使用的符号
LSTM背后的核心
LSTM的关键是单元状态,即图附2.9中上方那条贯穿单元的线。单元状态有点像传送带,它在整个链条一直传送下去,只有少数节点对它有影响,信息可以很方便地传送过去,保持不变。
图附2.9 LSTM的单元状态
LSTM对单元状态有增加或移除信息的能力,但需要在一个叫作“门”的结构下按照一定的规范进行。“门”是有条件地让信息通过的路径,它由一个sigmoid神经网络层和一个逐点乘法运算构成。
图附2.10 LSTM的单元“门”结构
sigmoid层输出0 ~1的数值,表示每个要素可以通过的程度,0表示“什么都过不去”,1表示“全部通过”。一个LSTM有3个这样的“门”,用来保护和控制单元状态。