当前位置: 首页 > 科技观察

自然语言处理领域的核心:序列学习_0

时间:2023-03-21 21:07:47 科技观察

生活中的一切事物都是与时间相关的,都形成一个序列。对于序列数据(文本、语音、视频等)我们可以使用神经网络并导入整个序列,但是这样我们的数据输入大小是固定的,局限性是显而易见的。如果重要的时序签名事件恰好落在输入窗口之外,则会出现更大的问题。所以我们需要的是:一个可以读取任意长度序列元素的神经网络(比如一个视频就是一系列的图片,我们每次给神经网络一张图片);一个有记忆的神经网络,可以记住好几次以前的事件,这些问题和要求催生了很多不同的递归神经网络。图1:长短期记忆(LSTM)单元。LSTM有四个输入权重和四个循环权重。窥视孔是存储单元和门之间的额外连接,但它们无助于提高性能,因此经常被忽略。递归神经网络如果我们想让常规的神经网络解决两个数相加的问题,那么我们只需要输入两个数,然后训练两个数之和的预测即可。如果现在有3个数要加,那么我们可以:扩展网络架构,增加输入和权重,重新训练;将第一个输出(即两个数之和)和第三个数作为输入,返回给网络。解决方案(2)显然更好,因为我们希望避免重新训练整个网络(网络已经“知道”如何将两个数字相加)。如果我们的任务变成:首先将两个数相加,然后将两个不同的数相减,那么这个解决方案就不会很好地工作。即使我们使用额外的权重,也不能保证正确的输出。相反,我们可以尝试“修改程序”,把网络从“加法”改成“减法”。这是通过对隐藏层进行加权(见图2)来实现的,这样网络的内核就会随着每个新输入的变化而变化。网络会学习把两个数相加后的程序从“加法”改成“减法”,问题就迎刃而解了。我们甚至可以通过将两个数字和一个表示数学运算“加法”、“减法”或“乘法”的“特殊”数字传递给网络来推广这种方法。在实践中,这可能并不完美,但可以得到大致正确的结果。但是这里的主要问题不是得到正确的结果,而是我们可以训练循环神经网络来学习任何输入序列产生的特殊输出,这是非常强大的。例如,我们可以教网络学习单词序列。SoumithChintala和WojciechZaremba写了一篇关于使用RNN进行自然语言处理的优秀博客。RNN也可用于生成序列。AndrejKarpathy撰写了这篇[有趣且生动的博客],展示了可以模仿各种类型的词级RNN,从莎士比亚到Linux源代码,再到给孩子命名。LongShortTermMemory(LSTM)长短期记忆单元使用权重为常量1.0的自连接线性单元。这使得流入自循环(前向传播)或梯度(反向传播)的值保持不变(输入或误差乘以1.0仍然是原始值;前一个时间步的输出或误差也与下一个时间步相同的输出),所以所有的值和梯度都可以在需要的时候准确地回调。这个自循环单元,记忆单元,提供记忆功能,可以存储信息,对之前的几个时间步长有效。这对很多任务都极其有效,比如文本数据,LSTM可以存储前一段的信息,并将这些信息应用到当前段落的序列中。另外,深度网络中一个很常见的问题叫做“梯度消失”问题,即随着层数的增加,梯度越来越小。有了LSTM中的记忆单元,就有了连续的梯度流(误差保持原来的值),从而消除了梯度消失的问题,可以学习长达数百个时间步长的序列。然而,有时我们想要丢弃旧信息并用更新、更相关的信息取而代之。同时,我们不想发布无效信息来干扰网络的其余部分。为了解决这个问题,LSTM单元有一个遗忘门,它会删除自循环单元中的信息,而不会将信息释放到网络中(见图1)。遗忘门将记忆单元中的值乘以0到1之间的数字,其中0表示忘记,1表示保持原样。具体值由当前输入和LSTM单元在上一个时间步的输出决定。在其他时候,记忆单元需要在多个时间步长内保持不变,因此LSTM添加了另一个门,即输入门(或写门)。当输入门关闭时,不会有新的信息流入,原有的信息就会受到保护。另一个门将记忆单元的输出值乘以一个介于0(擦除输出)和1()之间的数字,这在多个记忆相互竞争时很有用:一个记忆单元可能会说:“我的记忆很重要!所以我现在要释放它”,但是网络可能会说:“你的记忆很重要,但现在还有其他更重要的记忆细胞,所以我会为你的输出门分配一个小值,并为输出门分配一个大值其他大门。那样他们就会赢。”LSTM单元的连接方式乍一看似乎很复杂,需要一些时间才能理解。但是当您查看各个组件时,该结构实际??上与普通的循环神经网络没有什么不同——输入和循环权重流向所有门,连接到自循环记忆单元。为了更深入地了解LSTM并了解整个架构,我建议阅读:LSTM:ASearchSpaceOdyssey和原始LSTM论文。词嵌入(WordEmbedding)图3:食谱的二维词嵌入空间,这里我们局部放大了“南欧”的聚类想象一下“猫”和所有其他与“猫”相关的词,你可能会想“小猫”,“猫科动物”。想想一些不太相似但比“汽车”更相似的东西,例如“狮子”、“老虎”、“狗”、“动物”或动词“咕噜咕噜”、“喵喵叫”、“睡觉”等。再想象一个三维空间,我们把“猫”字放在中间。上面提到的词中,类似于“猫”,空间位置也比较接近;例如,“kitty”、“feline”离中心很近;“虎”和“狮”稍远;“狗”远一点;而“汽车”不知道去哪里。有关二维空间中词嵌入的示例,请参见图3。如果我们用一个向量来表示空间中的每一个词,那么每个向量由3个坐标组成,比如“cat”是(0,0,0),“kitty”可能是(0,1,0,2,-0,3)而“汽车”是(10,0,-15)。这个向量空间就是词嵌入空间,每个词对应的三个坐标可以作为算法的输入数据。一个典型的词嵌入空间包含数千个词和数百个维度,人类很难直观地理解,但相似词接近的规则仍然成立。对于机器来说,这是一个很好的单词表示,可以改进自然语言处理。如果您想了解有关词嵌入的更多信息以及如何将它们应用于创建“理解”语言的模型,我建议您阅读:使用Torch的深度神经网络理解自然语言,作者SoumithChintala和WojciechZaremba。编码-解码让我们暂时停止自然语言处理,想象一下西红柿,想象一下适合西红柿的配料或菜肴。如果您的想法与互联网上最常见的食谱相似,您可能会想到奶酪和萨拉米香肠之类的东西;巴马干酪、罗勒、通心粉;或其他成分,如橄榄油、百里香和欧芹。(如果你把它当作中国人,那一定是鸡蛋)。这些食材主要是意大利和地中海美食。同样是西红柿,如果您正在吃墨西哥菜,您可能会想到豆类、玉米、辣椒、香菜或鳄梨。您刚刚想到的是将“番茄”一词的表示形式转换为新的表示形式:“墨西哥食物中的西红柿”。“编码器”做同样的事情。它通过改变词汇表的表示,将输入的词汇一个一个地转化为新的“思维向量”。就像将上下文“墨西哥菜”添加到“西红柿”一样,这是“编码-解码”架构的第一步。编码-解码架构的第二步是基于不同的语言在词嵌入空间中具有相似的几何结构,即使用来描述同一事物的词是完全不同的。比如在德语中,“cat”是“Katze”,dog是“Hund”,这与英语完全不同,但两个词的关系确实是一样的。Karze和Hund的关系就跟Car和Dog的关系一样。也就是说,即使词汇本身不同,但背后的“思维向量”确实是一样的。当然,也有一些词是其他语言难以表达的(比如中文的“元粉”),但这种情况比较少见,一般是成立的。基于以上思路,我们可以搭建一个解码网络。我们将英语编码器产生的“思想向量”传递给德语解码器。德语解码器会将这些思想向量或关系转换映射到德语词嵌入空间,然后生成一个句子,保持英语句子中的关系。所以我们有一个可以做翻译的网络,这个想法还在发展,结果还不完美,但是改进的很快,很快就会成为最好的翻译方式。