零基础进行神经网络语言建模-阿里云开发者社区

开发者社区> 【方向】> 正文

零基础进行神经网络语言建模

简介: 本文从最简单的语言模型开始介绍,以优化模型性能为目标,由浅到深的介绍了神经网络模型在语言模型中的应用。
+关注继续查看

更多深度文章,请关注:https://yq.aliyun.com/cloud


187d6f3163372330d717420c995360fa1cdb5c65

语言模型是自然语言处理领域的基础问题,其在词性标注、句法分析、机器翻译、信息检索等任务中起到了重要作用。简而言之,统计语言模型表示为:在词序列中,给定一个词和上下文中所有词,这个序列出现的概率。例如:你手机上键盘上方正显示的三个字,系统试图预测你要输入的下一个字词就是语言建模的用途之一。在下面所示的情况下,语言模型预测“from”“on”“it”在给定句子中具有很高的下一个单词的可能性。其实输入法系统内部,语言模型都会计算词汇中的每个单词的出现的概率,但是用户只能看到前三个最可能的单词。

681b9abb080a485c1c2fc549bf93cccd62c7917a

语言模型是许多系统的基本部分,它试图解决机器翻译和语音识别等自然语言处理任务。目前,所有的最先进的语言模型都是神经网络。

这篇文章的第一部分提供了一个简单的前馈神经网络来解决这个任务。在帖子的第二部分,我们将通过添加一个循序神经网络(RNN)来改进简单的神经网络模型。最后一部分将讨论两种最近提出的改进基于RNN的语言模型的正则化技术。

一个简单的模型

作为开始,我们将建立一个简单的模型,给出一个单词,然后尝试预测其后的单词。

0490eaaeeb7820c7ef5367c63431e83fb3257f35

我们使用one-hot向量来表示单词:我们让词汇表中单词任意排序,然后将该n词表示为词汇量为(N)大小的向量。其中绝大多数标记为0,只有一个标记为 1,代表当前的词。

该模型可以分为两部分:

我们从编码输入字开始。通过取代表输入字的one-hot矢量(c在图中),并将其乘以(N,200)我们称为输入embeddingU)的大小矩阵。通过该乘法产生一个大小为200的向量,这也被称为词嵌入。该嵌入是当前输入字的密集式表征(dense representation)。该表示的大小要小于表示相同单词的单热矢量,而且它还具有一些其他有趣的属性。例如,虽然由one-hot向量表示的每两个词之间的距离总是相同的,但是这些密集式表征却具有这样的属性,即在意义上接近的词具有在嵌入空间中接近密集式表征。

第二个组件可以看作是一个解码器。在编码步骤之后,我们有输入字的表示方式。我们将它乘上一个大小的矩阵(200,N),我们称之为输出embeddingV)。所得到的矢量大小为N然后通过softmax函数,将其归一化为概率分布(意味着每个值都在01之间,并且它们的和1)。

解码器是一个简单的函数,它接受输入单词的表征,并返回一个模型表示对下一个单词的预测的分布:该模型显示每个单词成为序列中下一个单词的概率。

为了训练这个模型,我们需要一对输入和目标输出字。对于(input, target-output),我们使用Penn Treebank数据集,其中包含来自新闻文章的约40K个句子,并且具有10,000常用词汇。为了生成模型学习的单词对,我们将从文本中获取每对相邻单词,并将第一个作为输入单词,将第二个单词作为目标输出单词。因此,例如,对于句子“The cat is on the mat”:我们将提取下列词对(The, cat)(cat, is)(is, on)等等。

我们使用随机梯度下降来更新训练中的模型,所用的损失是交叉熵损失。这种损失测量了模型预测的输出分布与每次迭代的目标分布之间的差距。每次迭代的目标分布是表示当前目标字的one-hot矢量。

用于表示语言模型性能的度量标准是测试集的困惑度。最佳困惑度为1,而简单模型的困惑度为183但,我们可以通过更好的办法来提升其性能。

使用RNN来提高性能

简单模型的最大问题是,为了预测句子中的下一个单词,它只使用单个前一个单词。如果我们可以建立一个能够记住前面几句话的模型,那么它的性能应该会有所提高。我们用一个例子来理解我们为什么这样做!想想下面的例子:词语是什么?你可能会说咖啡啤酒苏打水有可能是它后面的词。如果我告诉你这个词序列实际上是奶牛喝,那么你就会完全改变你的答案。

我们可以通过使用循环神经网络RNN)来增加我们模型的记忆,如下所示。

eeeec12aeb11bc7436eba90ad78a65156f71307b

该模型与简单的模型类似,只是在对当前输入字进行编码之后,我们将所得到的大小为200矢量式提供给两层LSTM,然后输出一个也是大小为200的向量(在每个时间步长内LSTM也会接收到一个向量表示其以前的状态,这在图中未表示出)。然后,我们使用解码器将这个输出向量转换成概率值的向量。(LSTM只是一个更好地记住过去爱好的RNN,它的“API”RNN“API”相同,每个时间步长内的LSTM接收到一个输入及其以前的状态,并使用这两个输入计算输出向量。)

现在我们有一个模型,在每个时间步骤内不仅获得当前的单词表示,而且还获取了上一个时间步长中LSTM的状态,并使用它来预测下一个单词。LSTM的状态是以前看到的单词的表示(注意,我们最近看到的单词对这个状态的影响比我们以前看到的有更大的影响)。

正如预期的那样,RNN模型的困惑度为114,性能有所提高,Tensorflow提供了此模型的实现以及详细的说明。

正则化的重要性

利用RNN虽然能够提高模型的性能,但是我们依然可以做得更好。在本节中,我将介绍一些改进RNN语言模型性能的最新进展。

Dropout

我们可以通过增加嵌入层和LSTM层来改进模型网络,但是随着层数的不断增加,很快就会停止增加性能,因为网络超出了训练数据的需求。通过规范模型来解决这个问题的一个方法是使用Dropout

Dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。关于Dropout的介绍:深度学习网络大杀器之Dropout——深入解析Dropout

下图是基于RNN模型的可视化,展示了三个时间步骤。x是输入序列和y输出序列,灰色框表示LSTM层。垂直箭头表示来自相同时间步长层的输入,水平箭头表示携带先前时间步长信息的连接。

b6ca690cfb2dfd445e7501c5194140c27cfd2cff

我们可以在垂直(同一时间步)连接上应用Dropout

5d6f637b51e06815239d3eefa8ab9247b8ca2261

着色箭头代表我们应用Dropout的地方。某个层的缺陷掩码表示那个层被激活归零。在这种情况下,我们对不同的层使用不同的Dropout掩码(这由图中的不同颜色表示)。

Dropout应用于循环连接会损害性能,因此在初始使用Dropout时,我们仅在同一时间段内的连接上使用它。使用两个LSTM层,每层包含1500LSTM单元,我们实现了一个困惑度为78的模型创建。

最近引入的variational dropout 解决这个问题,并且通过在每个时间步长使用相同的dropout masks来提高模型的性能(模型困惑度75)。

68e6fbbb782ba6235adb64005f6b2e61b4a4c4b3

Weight Tying权重绑定):

输入嵌入和输出嵌入有几个共同的属性。它们共同的第一个属性是它们都是相同的大小(在我们的具有DropoutRNN模型中,它们的大小都是(10000,1500))。

他们共有的第二个属性有点微妙。在输入嵌入中,具有相似含义的词由相似的向量(与余弦相似度相似)表示。这是因为该模型得知它需要以类似的方式对类似的单词做出反应(快速这个词之后的单词与极速一词相似)。

这个属性也出现在输出嵌入中。输出嵌入接收关于下一个输出字(RNN的输出),必须将其转换成概率分布。来自给定RNN的表征,解码器判断单词的概率主要取决于其在输出嵌入中的表示。因为模型想要提升RNN输出性能,就会将类似的概率值分配给类似的单词,类似的单词由相似的向量表示。(再者,如果给定一定的RNN输出,单词快速的概率相对较高,我们也预计单词极速的概率相对较高)。

这两个相似之处使我们最近提出了一个非常简单的方法:weight tying,以降低模型的参数并提高其性能。我们简单地把输入嵌入和输出嵌入联系在一起(即我们设置U = V,这意味着我们现在有一个单独的嵌入矩阵,既用作输入嵌入和有可以用作输出嵌入)。这使得使用DropoutRNN模型的困惑度降到了73

为什么weight tying权重绑定)可以起到作用?

变化的dropout RNN模型在测试集上的困惑度是75。相同的模型在训练集上实现了困惑度24的成绩。这意味着它已经开始记住仅在训练集中的某些模式或序列,并且不会让模型涉及到数据集不可见的数据。应对这种过度配合的一个方法就是通过降低模型的容量(参数数量)来降低模型的记忆能力。通过应用权重绑定(weight tying),我们删除了大量的参数。

除了权重绑定(weight tying)的正规化效果之外,我们提出了改进结果的另一个原因。那就是我们发现输出嵌入中的单词表示的质量远远高于无语言模型的输入嵌入中的表示。在一个权重绑定模型中,因为在每个训练迭代中绑定的嵌入参数更新与未解模型的输出嵌入的更新非常相似,所以绑定的嵌入与未解开的模型的输出嵌入相似。所以在绑定的模型中,我们在模型中使用单个高质量的嵌入矩阵。这有助于提高绑定模型性能(tied model)。

总结:这篇文章介绍了如何通过首先添加一个RNN,然后添加可变化的Dropout和权重绑定来改进一个非常简单的前馈神经网络语言模型。

近几个月来,我们已经看到RNN语言建模方面的最新进展。目前最新的结果由Melis等人最近的两篇论文。这些模型利用上面所示的大多数方法,并通过使用更好的优化技术,如新的正则化方法以及通过为现有模型找到更好的参数来扩展它们。这些方法中的一些将在本指南的第二部分中介绍。

本文由北邮@爱可可-爱生活老师推荐,@阿里云云栖社区组织翻译。

文章原标题《Neural-Language-Modeling-From-Scratch

作者:Ofir 目前作者正关注于自然语言处理领域。

博客:http://ofir.io

译者:袁虎 审阅:主题曲哥哥

文章为简译,更为详细的内容,请查看原文

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
零基础进行神经网络语言建模
本文从最简单的语言模型开始介绍,以优化模型性能为目标,由浅到深的介绍了神经网络模型在语言模型中的应用。
5454 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4398 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
10760 0
零基础进行神经网络语言建模
本文从最简单的语言模型开始介绍,以优化模型性能为目标,由浅到深的介绍了神经网络模型在语言模型中的应用。
1453 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
3185 0
《C语言编程——零基础初学者指南(第3版)》一导读
本书的读者对象 本书与众不同之处 本书的设计要素 轻松愉快地学习C语言 现在要做什么 看到朋友们都找到了合适的C语言编程工作,而自己却吃着闭门羹?很想学习C语言,却缺乏持续的动力?想用热门的程序设计语言给老旧不堪的电脑进行热身?本书就是你所需要的!
1209 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
1074 0
+关注
【方向】
欢迎各位对内容方向及质量提需求,我们尽量满足,将国外优质的内容呈现给大家!
696
文章
5
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载