集智翻译-The Unreasonable Effectiveness of Recurrent Neural Networks

来自集智百科
跳转到: 导航搜索

目录

任务说明

素材推荐

LSTM(Long Short-Term Memory,长短期记忆)是现在自然语言处理中最基础最常用的神经网络模型。他是如何工作的?有什么用处?这篇文章非常通俗易懂地介绍了LSTM的工作原理。

原文链接:http://karpathy.github.io/2015/05/21/rnn-effectiveness/

任务拆分

本次翻译任务拆分为7个Parts:

Part1:

文章开始……至 ……process your fixed-sized data.

Part2:

RNN computation. So how do these things work? ……至…… much more efficient Lua/Torch codebase.

Part3:

Fun with RNNs

All 5 example character models below were trained ……至…… different temperatures with the provided code.

Part4:

Wikipedia

We saw that the LSTM can learn to spell words and……至……became less common with larger/better models, but nonetheless, these are the kinds of mistakes that come up.

Part5:

Linux Source Code

I wanted to push structured data to its limit……至……emerge only much later.

Part6:

Visualizing the predictions and the “neuron” firings in the RNN……至……once it has been developed for efficiency in prod that’s fine.

Part7:

Further Reading……至……文章结束

校对分组

Part1和Part2互校、Part3和Part4互校、Part5校对Part6、Part6校对Part7、Part7校对Part5

校对的时候,若有修改,可以斜体标示或者加删除线,代码的话可以参考下面的: http://wiki.ubuntu.org.cn/Wiki%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95

完成日期

任务周期1.5周:

翻译的截止完成日期为:5月4日 晚上10点(北京时间);

校对的截止完成时间为:5月8日 晚上10点(北京时间)

Part1

(Translated by 饶双全 ,Edited by )

递归神经网络不可思议的有效性

递归神经网络(RNNs)具有一些不可思议的地方。我仍然记得我训练的第一个递归网络,我把它用于图片字幕。训练我的第一个初始模型花了几十分钟(当时只是很随意任取的超参数),差一点就训练出能够产生很漂亮的图片描述的模型。有时候,就模型输出结果的质量,你对模型简单程度比例的把握往往还是与你的期望相差甚远,而这还仅仅是其中的一个问题。还有出现令人震惊结果的时候,大家普遍认为是因为RNNs不容易训练(事实上,通过多次试验,我得出了相反的结论)。大概一年前,我一直在训练RNNs,我多次见证了它们的强大的功能和鲁棒性,而且它们不可思议的输出结果仍然让我感到惊讶。这篇文章将会给你展现它不可思议的地方。

我们将训练一个RNNs让它一个字符一个字符地生成文本,然后思考这个问题“这怎么可能,它是怎么做到的?”

顺便提醒一下,在讲述这篇文章的同时,我也会将代码上传到Github上,这样你就可以基于多层长短期记忆网络(LSTMs)来训练字符级语言模型。你向它输入大量的文本,根据字符它会学习并产生类似的文本。你也可以重新运行代码来再现我下面的试验结果。

递归神经网络

序列。根据不同的专业背景,你可能会问:是什么让递归神经网络如此特殊?Vanilla神经网络(卷积网络也一样)最大的缺点就是它们的API具有很大局限性:它们将固定大小的向量作为输入(比如一张图片),然后输出一个固定大小的向量(比如不同分类的概率)。还不止这些:这些模型按照固定的计算步骤(比如模型中层的数量)来执行这样的映射。递归网络更令人兴奋的主要原因是,它允许我们对向量序列进行操作:输入序列、输出序列、或一般情况下的输入序列和输出序列。通过几个例子可以具体理解这点:

每一个矩形代表一个向量,箭头则表示函数(比如矩阵相乘)。输入向量用红色标出,输出向量用蓝色标出,绿色的矩形是RNN的状态(下面会详细介绍)。从左到右:(1)没有使用RNN的Vanilla模型,从固定大小的输入得到固定大小输出(比如图像分类)。(2)序列输出(比如图片字幕,输入一张图片输出一段文字序列)。(3)序列输入(比如情感分析,输入一段文字然后将它分类成积极或者消极情感)。(4)序列输入和序列输出(比如机器翻译:一个RNN读取一句英文语句然后将它翻译成一句法语输出)。(5)同步序列输入和输出(比如视频分类,对视频中每一帧打标签)。我们注意到在每一个案例中,都没有对序列长度进行预先特定约束,因为递归变换(绿色部分)是固定的,而且我们可以多次使用。

正如你预想的那样,与一开始就注定要失败的基于固定计算步骤的固定网络相比,使用序列进行操作要更加强大。因此,这更加激起了我们建立更智能化系统的吸引力。而且,我们还可以从一小方面看出,RNNs用一个固定(但可以学习)函数将输入向量与状态向量绑定起来,从而用来产生一个新的状态向量。在编程层面,在编写程序时,可以用运行一个具有特定的输入和一些内部变量的固定程序对其进行解释。从这个角度来看,RNNs本质上可以描述程序。其实,在这个意义上讲,大家都知道RNNs是图灵完备的 ,即它们可以模拟任意程序(使用恰当的权值向量)。但是,类似于神经网络的通用逼近定理,你不应该太过于曲解它的意思,就当我没说过这些吧。

如果说训练Vanilla神经网络是优化函数,那么训练递归神经网络则是优化程序。

序列缺失情况下的序列处理。你可能会想,将序列作为输入或输出可能是相对少见的,但关键是明白,即使你的输入/输出是固定向量,仍然有可能使用这种强大的形式,即以序列的方式来处理它们。比如,下图显示了来自DeepMind两篇非常好论文中的结果。左图是,一个算法学习了一种递归网络策略,可以将它的注意力集中在图像周围;特别是,它能够学会阅读出从左到右的门牌号码(Ba等人)。右图是,一个递归网络通过学习在画布上序列化地添加颜色然后生成一张张数字图像(Gregor 等人)。

左图:RNN学习读出门牌号;右图:RNN学习绘制门牌号。得出的结论是:即使你的数据不是序列形式的,你仍然可以制定并训练出强大的模型来学习以系列化进行处理。你可以学习有状态的程序来处理固定大小的数据。

Part2

(Translated by Henry ,Edited by 饶双全 )

RNN的计算。RNN是怎么样进行工作的呢?在内核中,RNN有一个看似简单的API,API可以接收输入向量x,并输出向量y。然而,输出向量并不仅仅只受到输入数据的影响,还受到以往所有整个历史输入数据的影响。如果打包为一个类的话,那么RNN的API由一个step函数组成。 rnn = RNN() y = rnn.step(x) # x is an input vector, y is the RNN's output vector

RNN类中有一些内部的状态,这些状态在调用step函数的时候会发生改变进行更新。最简单的情形就是内部状态仅由一个隐藏向量h构成。以下是Vanilla RNN的step函数代码:

class RNN:

  1. def step(self, x):
  2. update the hidden state

self.h = np.tanh(np.dot(self.W_hh, self.h) + np.dot(self.W_xh, x))

  1. compute the output vector

y = np.dot(self.W_hy, self.h) return y

以上代码说明了vanilla RNN的前向传导。这个RNN网络的参数分别为以下三个矩阵W_hh,W_xh,W,hy。隐藏状态self.h初始化为零向量。Np.tanh函数是一个非线性函数,将激活数据控制在[-1,1]范围之内。注意这个RNN是如何进行工作的简单介绍一下它的工作原理:在tanh中有两项:一项是基于之前隐藏状态的,另一项是基于当前输入的。在numpy中,np.dot进行矩阵乘法。两个中间向量进行加法运算,经过tanh压缩得到新的状态向量。如果你习惯使用数学符号进行表示,我们也可以将隐藏状态写为ht = tanh(Whhht−1 + Wxhxt ),其中tanh逐个元素进行运算。

我们用随机数字来对RNN的矩阵进行初始化,在训练过程中,为了得到提升性能的矩阵为了训练找到一个满意的矩阵,需要进行大量的工作,我们用损失函数来对其进行评价。对输入序列x相应的不同,会有不同的输出,而损失函数就是指你对这些输出的偏好这样就可以根据的你的偏爱,在输入序列x上得到你希望的输出y

更深层次的讨论。RNNs属于神经网络,如果你以叠薄饼一样的方式,开始对模型进行堆叠来进行深度学习,那么算法的性能会单调上升(如果操作正确)。例如,我们可以像如下方法一样搭建一个2层循环网络。 y1 = rnn1.step(x) y = rnn2.step(y1)

换句话说,两个独立的RNN:一个RNN用于接收输入向量,第二个RNN用于接收第一个RNN的输出。两个RNN并不在乎关心向量是输入的还是输出的,而且在反向传播时梯度会沿着每一个模型通过。

Getting fancy来点奇特一点的东西。我想简要提一下的是,在实际中,我们大多数人用的是一些不同的公式,而非以上我提到的时间长短期递归神经网络LSTM. LSTM是一种特别的循环网络,在实际工作中,它的性能可以慢慢变好工作性能效果更佳。这都归功于它强有力的更新公式以及更好的动态反向传播功能。在这里我不会详细说明,但是我提到的每一个关于RNNs的东西其实都差不多,除了用于计算更新的数学构成(self.h=那一行)那部分有些复杂。从这里开始,我将混合交替使用RNN/LSTM,但是,本文中所有的实验都是使用的LSTM完成的

字母字符级的语言模型 好了,我们已经知道了RNNs的基本概念,他们强大的原因以及工作原理。接下来我们来看一个有趣的应用:我们将训练字母级别字符级语言RNN模型。我们将输入一段文本至RNN,让模型根据一个序列之前的字母字符,得到下一字母字符的概率分布。这样,我们就可以逐个字母产生新文本我们会在同一时间产生新文本字符

作为一个工作样例,假设我们只有一个字母表,字母表中由组成helo的四种可能的字母,我们希望训练RNN,使其能够组成“hello”假设我们只有四种字母的词汇“helo”,然后我们想要用训练序列“hello”训练一个RNN。这样的训练序列实际上源于四个训练样本。1.前一个字母为“h”时,“e”出现的概率最高。2. “i”出现的概率在“he”出现时最高。3.出现“hel”时,下文出现“l”的概率很大4.“o”应该跟在“hell”之后。

具体地,我们将每一个字母编码为1到k的向量,利用step函数逐个输入到RNN中。之后观察四维输出向量的序列(一个字母对应一维),我们可以将他们理解为RNN关于序列下一字母的出现可能性。视图如下:具体来说,我们将用1-of-k编码(所有都是0,除了词汇中字符的索引)将每个字符编码成一个向量,然后用step函数每次向RNN中输入一个字符。然后我们会看到一个4维序列的输出向量(每个字符代表一个维度),我们将此作为RNN分配给序列下一个字符的置信度。下面是一张案例图:

四维输入输出层和3神经隐藏层的RNN样例。这幅图展示了当输入“hell”时,前向传导是怎样进行的。输出层包含RNN关于下一个字母的预测信心指数。一个有四维输入输出层和一个有着3个单元(神经元)的隐藏层的实例。这张图显示了当将“helo”作为RNN的输入时前馈操作的活化结果。输出层包含了RNN对下一个出现字符(这里词汇是“h,e,l,o”)的置信度。我们希望使得绿色的数字尽可能高而红色数字尽可能低。

样例中,我们可以看到在第一步,字母”h”之后出现字母“h”的信心指数置信度设置为为1.0, 可能出现字符“e”的置信度设置为为2.2,可能出现字符“l”的置信度设置为为-3.0,可能出现字符“o”的置信度设置为为4.1。在我们的训练数据中(字符串hello),下一个正确的字母是“e”,我们应该增加字母“e”(绿色)信心指数的置信度,降低其他字母(红色)信心指数的置信度。类似的,4步中的在每一步中,我们都希望目标字母出现的概率置信度更大。因为整个RNN网络可以进行微分运算,我们可以利用反向传播算法(利用微积分学链式法则的递归调用)来解决从哪一个方向进行权重调整的问题,从而提高期望字母的出现概率绿色粗体数字。然后进行参数更新,也就是在梯度方向上进行权重的微小更新。如果我们将更新后的数据输入到RNN中,我们可以发现正确字母的得分变高了(例如从2.2变为了2.3),错误字母的得分降低了。我们重复这一过程多次,直至网络收敛,最终预测与训练数据连贯保持一致,总是能正确预测下一个字母。

一个更学术性的解释是我们在每一个输出向量同时运用了标准softmax分类器(也叫作交叉熵损失)。使用小批量的随机梯度下降来训练RNN,我还喜欢使用 RMSProp 或Adam(自适应学习速率理论)来稳定更新。

注意当把字母“l”第一次作为输入的时候,目标为“l”,但是第二次目标为“e”。所以RNN不能只依赖于输入,还应该使用反馈连接,根据上下文,最终完成我们的任务必须使用它的递归连接来跟踪内容以达到准确结果

测试的时候,我们向RNN输入一个字母,得到了下一个出现字母的概率分布。我们从分布中采样,将其输入到RNN获得下一个字母。重复这个过程,得到文本。现在我们利用不同的数据来训练RNN,看一下会发生什么东西有什么发生。 为了进一步阐述,我写了一篇文章minimal character-level RNN language model用于教学。代码只有100行,如果相对于文章,你更喜欢阅读代码,那么可以参考这段代码。因为这段程序是对以上叙述进行的准确,具体,有用的总结。现在我们介绍实验结果,这里用更高效的Lua/Torch代码库进行的编写。

Part3

RNN的乐趣 下文中全部五个字符模型我已经在 Github 上发布了训练好的代码。每个模型的输入均为单个文本文件。并且我们训练 RNN 来预测序列中下一个字符。

保罗格雷厄姆生成器 首先让我们尝试一个小的英文数据集作为正确性检查。我最喜欢的有趣数据集为保罗格雷厄姆的随笔集。【本案例的】基本思想是这些随笔饱含智慧,但不幸的是保罗格雷厄姆是个相对较慢的作者。如果我们可以按需提取其智慧,岂不是非常棒?那就是 RNN 的切入点。

在收集保罗最近五年的所有文章,我们得到一个约1MB 的文本文件,或大约100万个字符(这算一个非常小的数据集)。使用的技术: 让我们训练一个具有512个隐藏节点(近350万个参数)的两层LSTM,每层后使用0.5的 dropout。我们训练大小为100个样本的批次,并在长为100个字符的时间内截断反向传播。通过这些设置在 泰坦GPU上,一个批量大约0.46秒。(如果仅对50个字符的时间截断反向传播,则耗时减半,性能好耗费忽略不计。不用多说,让我们来看 RNN 的一个例子。

“The surprised in investors weren’t going to raise money. I’m not the company with the time there are all interesting quickly, don’t have to get off the same programmers. There’s a super-angel round fundraising, why do you can do. If you have a different physical investment are become in people who reduced in a startup with the way to argument the acquirer could see them just that you’re also the founders will part of users’ affords that and an alternation to the idea. [2] Don’t work at first member to see the way kids will seem in advance of a bad successful startup. And if you have to act the big company too.”

好的,显然生成器目前还无法取代保罗格雷厄姆。但请记住,RNN必须冲头开始学习英文,并且必须使用一个小数据集(包括,哪里放着逗号,顿号和空格)。我也喜欢它学会了如何去论证自己的论据(例如上面的[2]),有时它甚至会说出一些充满灵感的东西,例如“一家公司是思考让投资者打钱的集会”。如果你想查看更多,这里是一个长为50字符的例子的链接。

温度:我们也可以在采样期间调节Softmax的温度参数。将温度从1降低到一些较低的数值(如0.5)会使RNN变得更自信,它的例子也会更保守。相反,较高的温度会带来更多的多样性,但以更多错误为代价。如果降温到非常接近于0,我们就会得到最像保罗格雷厄姆说的话:

“is that they were all the same thing that was a startup is that they were all the same thing that was a startup is that they were all the same thing that was a startup is that they were all the same”

看起来我们陷入了关于初创公司的无限循环。

莎士比亚

看起来可以让我们的 RNN 学会拼写单词。但如果数据中更多的结构和风格呢?为了检查这一点,我下载了莎士比亚所有的作品,并将它们连接成一个(4.4MB)的文件。我们现在可以训练更大的网络。这种情况下,我们可以尝试一个三层 RNN,每层512个隐藏节点。在我们训练几小时候,获得如下样品。

PANDARUS:
Alas, I think he shall be come approached and the day When little srain would be attain'd into being never fed, And who is but a chain and subjects of his death, I should not sleep.
Second Senator:
They are away this miseries, produced upon my soul, Breaking and strongly should be buried, when I perish The earth and thoughts of many states.
DUKE VINCENTIO:
Well, your wit is in the care of side and that.
Second Lord:
They would be ruled after this chamber, and my fair nues begun out of the fact, to be conveyed, Whose noble souls I'll have the heart of the wars.
Clown:
Come, sir, I will make did behold your worship.
VIOLA:
I'll drink it.

记住,所有RNN 知道的都是字符,所以它会对两个对话者的名字和内容进行学习。有我们也会得到相对延长的独白段落。延长部分用粗体标注。如:

VIOLA:
Why, Salisbury must find his flesh and thought. That which I am not aps, not a man and in fire, To show the reining of the raven and the wars To grace my hand reproach within, and not a fair are hand, That Caesar and my goodly father's world; When I was heaven of presence and our fleets, We spare with hours, but cut thy council I am great, Murdered and by thy master's ready there My power to give thee but so much as hell: Some service in the noble bondman here, Would show him to her wine.

KING LEAR:
O, if you were a feeble sight, the courtesy of your law, Your sight and several breath, will wear the gods With his heads, and my hands are wonder'd at the deeds, So drop upon your lordship's head', and your opinion Shall be against your honour.

我几乎不能从这些例子从莎士比亚的真正作品中区分出来:) 如果你喜欢莎士比亚,那可以来看这篇长达一百万字符的生成文本。当然你可以使用我提供的代码,在不同温度参数下生成不同的文本。

Part4

(Translated by ,Edited by )

Part5

(Translated by ,Edited by )

Part6

(Translated by ,Edited by )

Part7

(Translated 王建男 ,Edited by )

拓展阅读

最后在本条帖子结束前,我还想在更广泛的背景下给RNN一个定位,并提供一份关于目前的研究方向的草图。最近RNN获得了大量的好评,这也使得深度学习更加激动人心。与卷积网络类似,它们已经有十多年的历史了,但是它们的全部潜力却是最近才开始得到广泛的认可,这很大程度上取决于我们计算资源的不断增长。以下是一些近期发展的简要说明(清单绝对不够完整,很多这项工作从研究回溯到20世纪90年代,参见相关工作部分)。


在NLP / Speech领域,RNN将言语转录成文本,执行机器翻译,生成手写文本,当然,它们已经被用作强大的语言模型(Sutskever等)(Graves)(Mikolov等)(两者都在字符和单词的水平上)。目前看来,词级模型比字符级模型更好,但这当然也是暂时的。

计算机视觉。RNN也迅速普及到计算机视觉系统中。例如,我们看到RNN在帧级视频分类,图像字幕(也包括我自己的工作和许多其他的),视频字幕和最新的视觉问答。我个人最喜欢的RNN在计算机视觉中应用的文章是《视觉注意的复现模式》,由于其高级方向(有序的图像处理)和低级建模(在加固学习中,REINFORCE学习规则是策略梯度方法的特例,它允许训练执行不可微分计算的模型(在文中是围绕图像进行扫视))。我相信,这种将CNN作为原始感知与RNN作为顶级扫视政策相结合的混合模式将变得普遍存在,特别是对于更复杂的任务,它超越在普通视图中的一些对象的分类。


感性推理,记忆和注意力。另一个非常令人兴奋的研究方向是面向香草复发网络的局限性。RNN的一个问题是它不具有归纳性:他们能够非常好地记录顺序,但是它们并不一定能够总是以正确的方式显示出令人信服的泛化标志(我将提供一些例子,让它更加具体)。第二个问题是它不必要地将其表示大小与每步的计算量相结合。例如,如果将隐藏状态向量的大小加倍,则由于矩阵乘法,将在每个步骤中将FLOPS的数量变成四倍。理想情况下,我们希望保持一个巨大的代表/记忆(例如存储所有维基百科或许多中间状态变量),同时保持每个时间步长运算量不变。

在这个方向上第一个具有说服力的例子是DeepMind的神经图灵机(Neural Turing Machines)论文。这篇文章绘制了一个可以在大型外部存储器阵列和一组较小的存储寄存器(可以将这些作为工作存储器)进行读/写操作的模型的路径。至关重要的是,《神经图灵机》还介绍了一种非常有趣的存储器编址机制,该机制是通过(软的,完全可区分的)注意力模型实现的。软注意力的概念已经被证明是一个强大的建模功能,并且已经在面向机器翻译的《 Neural Machine Translation by Jointly Learning to Align and Translate》一文和面向问答的《Memory Networks》中得以应用。实际上,我想说的是: 注意力的概念是神经网络中最有趣的最新创新。

现在,我不想潜入太多的细节,但是存储器编址的软注意力方案很方便,因为它保持模型完全可区分,但不好的一点是,牺牲效率,因为每一个可以关注的地方都被关注了(虽然是“软”式的)。想象一下在C中一个不指向特定地址的指针,而是在整个内存中的所有地址上定义整个分布,并且取消引用指针返回一个指向内容的加权和(这将是一个奢侈的运算!)。这促使多个作者交换软注意力模型以获得强烈的关注,其中一个样本一个特定的存储器块(例如,一些存储器单元的读取/写入动作,而不是在某种程度上从所有单元读取/写入)。这种模式在哲学上具有吸引力,可扩展性和高效性,但不幸的是它也是不可微观的。这就导致了对于增强学习领域技术的引入(比如REINFORCE算法),因为增强学习领域中的研究者们非常熟悉不可微交互的概念。这项工作现在还在进展中,但是硬注意力模型已经被发展出来了,在《 Inferring Algorithmic Patterns with Stack-Augmented Recurrent Nets》,《 Reinforcement Learning Neural Turing Machines》,《Show Attend and Tell》三篇文章中均有介绍。

学者们,如果你想阅读关于RNN的文章,我推荐Alex Graves,Ilya Sutskever和Tomas Mikolov的论文。更多关于强化和更一般的加强学习和策略梯度方法(其中,强化是一个特殊情况)可以学习David Silver的课程,或者是Pieter Abbeel的课程之一。

代码,如果你想继续训练的RNN,我听说Theano上的keras或passage还不错。代码是随着这个帖子在Torch发布的,或者是我之前写的一个原始numpy代码,这个代码实现了一个高效的,批量的LSTM正向和反向的传播。你还可以在github上看看我的NeuralTalk,它使用RNN / LSTM来标注图像,或者Jeff Donahue的Caffe实现


结论

我们已经了解了RNN,它们的工作原理,它为什么这么重要,我们已经在几个有趣的数据集上训练了RNN字符级语言模型,我们已经看到了RNN的过程。你可以信心满满地期待RNN有一个巨大的创新,我相信它将成为智能系统一个关键且必不可少的组成部分。

最后,为了给这篇文章添加一些meta,我在这篇帖基础上训练了一个RNN。不幸的是,在大约46K字符的情况下,没有足够的数据来适当地喂给RNN,但返回的样本(低温生成以获得更典型的样本)是:

I've the RNN with and works, but the computed with program of the RNN with and the computed of the RNN with with and the code 是的!!这个帖子是关于RNN,讲它的工作原理,所以很明显这个工作o(* ̄▽ ̄*)ブ。下次见!

个人工具
名字空间
操作
导航
工具箱