开发者社区> 玄学酱> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

从原理到实战 英伟达教你用PyTorch搭建RNN(上)

简介:
+关注继续查看

从 Siri 到谷歌翻译,深度神经网络大步推动了机器对自然语言的理解。

迄今为止,大多数模型把语言看作是字词的平面序列(flat sequence),使用时间递归神经网络(recurrent neural network)来处理。但语言学家认为,这并不是看待语言的最佳方式,应把其理解为由短语组成的的分层树状结构( hierarchical tree of phrases)。由于对该类结构的支持,大量深度学习研究投入到结构递归神经网络(recursive neural network)之中。在业内,这些模型有非常难以执行、运行起来效率低下的名声。

但对于今年 Facebook 开源的新深度学习框架 PyTorch ,业内人士人认为它的一大贡献是:搭建结构递归神经网络以及其它复杂自然语言处理模型,变得更简便。

结构递归神经网络,是展示 PyTorch 灵活性的一个不错的例子。但同时,PyTorch 是一个对于各类深度学习任务有完备功能的框架,虽然特别适于计算机视觉问题。它诞生于 Facebook AI 研究院 FAIR 的研究人员之手,PyTorch 把 Torch7 中高效、灵活的 GPU 加速后端算法库,和直觉性的 Python 前端结合到一起,并具有快速创建原型机的能力、高度可读性的代码、以及对于各类深度学习模型的支持。

SPINNing Up

本文将带领大家在 PyTorch 上,实现一个有 recurrent tracker 和 TreeLSTM 节点的结构递归神经网络,即 SPINN。对于相当多的主流深度学习框架,这是一个很难搭建的自然语言处理模型。这里我描述的实现部分做了 batch,所以能够利用 GPU 加速的性能,比不用 batch 的版本要快得多。

SPINN 模型的全称是“Stack-augmented Parser-Interpreter Neural Network”,它作为一种解决了自然语言推理任务的方案,随 Bowman et al. (2016) 论文面世,当时使用的是斯坦福的 SNLI 数据集。

这里的任务,是把成对的语句分类为三组类别:假设第一个句子是对某幅用户无法看到的图像的准确注解,第二个句子同样是对该图像的注解,那么第二句话到底是 (a) 绝对准确 (b) 可能准确还是 (c) 绝对不准确的?举个例子,假设第一句话是 “two dogs are running through a field”(两条狗穿过一片农田)。那么,让这组语句“绝对正确”的句子可以是““there are animals outdoors”(户外有动物);让它们“可能准确”的,可以是“some puppies are running to catch a stick”(一群幼犬跑着去接一个木棒);让它们“绝对不准确”的可以是 “the pets are sitting on a couch”(宠物们坐在沙发上)。

导致 SPINN 诞生的研究,为实现其目标要在决定句子之间的关系之前,把每句话编码为固定长度的矢量表达(还有其他方式,比如注意力模型)。

数据集包含机器生成的语法树( syntactic parse trees),后者把每句话里的词组合为短语和子句,每一个都有独立涵义,并且有两个词或 sub-phrases 组成。许多语言学家认为,人类理解语言,是通过把涵义以层级(hierarchical)方式组合起来,就像这样的树状结构。因此,创建一个以同样方式运作的神经网络或许是必要的。下面的例子是一个数据集里的句子,它的语法树以括号结构表示:


  ( ( The church ) ( ( has ( cracks ( in ( the ceiling ) ) ) ) . ) )


用支持语法树结构的神经网络对这个句子编码,方法之一是创建一个神经网络层 Reduce,把词组(以 GloVe 这样的 word embedding 来表示)或短语组合起来,然后将这一层循环应用,把上一个 Reduce 操作的结果,作为句子的编码:


X = Reduce(“the”, “ceiling”)
Y = Reduce(“in”, X)
... etc.


但如果,我想让神经网络以更“人性化”的方式运作呢?能从左到右阅读,保持语境,同时使用语法树把短语组合起来?或者,如果我想要训练一个神经网络,让它在看到这句子时,基于读到的词语创建它自己的语法树?这是一个同样的语法树,只是写出来的方式稍稍有区别:


  The church ) has cracks in the ceiling ) ) ) ) . ) )


第三种方法,仍然是一回事:


WORDS:  The church   has cracks in the ceiling         .
PARSES: S   S      R S   S      S  S   S       R R R R S R R


我所做的,仅仅是去除括号,用“S” 代表“shift”来标记词语, 并用“R”代表“reduce”替代右括号。现在,信息可作为操作堆栈(stack) 和类似堆栈的 buffer 的一系列指令从左读到右,与上文描述的循环方式有同样的结果:

  1. 将文本导入 buffer。

  2. 从 buffer 的首词“The” pop 出去,把 push 入栈,这时“The”应该在“church”前面。

  3. Pop 最上面的两个堆栈值,应用 Reduce,把结果 push 入栈。

  4. 从 buffer pop 出“has”,push 到入栈,随后 “cracks”,再“in”,再“the”,再“ceiling”。

  5. 重复四次:pop 最前面的两个堆栈值,应用 Reduce,push 结果。

  6. 从缓存 pop 出“.”再 push 入栈。

  7. 重复两次:pop 最前面的两个堆栈值,应用 Reduce,push 结果。

  8. Pop 剩下的堆栈值,作为句子编码返回。

我还想维持语境,照顾到其他信息——句子中系统已读取的部分,并在句子的之后部分上进行 Reduce 操作。所以,我将把两个参数(two-argument)的 Reduce 函数,用三个参数的函数来替代,后者导入左子树、右子树短语以及当前语境状态。该状态由第二个神经网络层生成——一个名为 Tracker 的循环单位。给定现有句子语境状态,Tracker 在堆栈操作的每一步生成一个新状态(读取每个词语和右括号之后),buffer 最顶端的 entry b 和堆栈中最顶端的两个 entries s1、s2:


context[t+1] = Tracker(context[t], b, s1, s2)


可以想象一下用你最喜欢的编程语言写这些东西:对于需要处理的每个句子,它会从 buffer 中加载下一个词,运行 Tracker,检查是否要 push 入栈或者进行 Reduce,操作后不断重复,直到整个句子处理完毕。当应用在单个句子上面,这个过程由大且复杂的深度神经网络运行,网络上的两个可训练层一遍遍按照 stack manipulation 规定的方式执行。

但如果你对 TensorFlow、Theano 等传统深度学习框架很熟悉,你就知道执行这类动态过程有多么费劲。这值得我们花点时间多想想,为什么它们处理这种任务力不从心,以及 PyTorch 是否能提供不一样的东西。

图理论

从原理到实战 英伟达教你用PyTorch搭建RNN(上)

本质上,深度神经网路只是有海量参数的复杂函数。深度学习的目标也仅仅是通过计算 partial derivatives(梯度)、衡量损失来优化这些参数。如果该函数以计算图结构来表示,反着运行能去除计算梯度的不必要工作。所有现代深度学习框架都是基于这一反向传播概念,作为结果,每个框架都需要找到一种方式来表示计算图。

大多数的主流深度学习框架,比如 TensorFlow、Theano、Keras 以及 Torch7 的 nngraph 算法库,它们的计算图都是事先创建好的静态物体。该图由看起来像是数学表达的代码来定义,但它的变量其实是还没有赋予任何数值的占位符(placeholder)。由占位符标量组成的图,编译为一个函数,然后重复在训练数据 batch 上运行,生成输出和梯度。

这种静态计算图在 CNN 上的效果很好,后者的结构一般是固定的。但对于许多应用,开发者需要让神经网络图的机构能随数据修改。在自然语言处理中,研究人员通常希望把时间递归神经网络展开,最好输入有多少词,就有多少时间步(timestep)。上文提到的 SPINN 模型的 stack manipulation,非常倚赖控制流,比如“for”和“if”statement,来定义某个特定句子的计算图结构。在更复杂的例子里,你也许想要搭建结构取决于子网络输出的模型。

有的想法可以被硬塞进静态图系统,但不是全部 ,而且几乎总是以更糟的透明度、看不懂的代码作为代价。框架需要给计算图添加代表了编程基本指令(loops and conditionals)的特殊节点,用户需要学习、使用这些节点,而不是程序语言中的 “for”和“if” statement。这是因为任何程序员使用的控制流 statement  均只能使用一次,在创建图时写死(hard coding)一条计算通道。

比如说,词语(从初始状态 h0 开始)中的矢量上,运行一个时间递归神经网络(rnn_unit)需要 tf.while_loop,一个特殊的控制流节点。在 TensorFlow 运行时获取词语长度需要一个额外特殊节点,这是由于代码运行的时候它只是一个占位符。


# TensorFlow
# (this code runs once, during model initialization)
# “words” is not a real list (it’s a placeholder variable) so
# I can’t use “len”
cond = lambda i, h: i < tf.shape(words)[0]
cell = lambda i, h: rnn_unit(words[i], h)
i = 0
_, h = tf.while_loop(cond, cell, (i, h0))


一个在根本上与之区别的方式,是动态计算图,这在几十年前的学界就已展开研究,又被称为“define-by-run”。哈佛大学研发出来的 Kayak 、autograd,以及研究导向的框架 Chainer and DyNet 都基于动态计算图。在这样的框架中,计算图在运行时才被创建出来或重新创建。进行前馈通道运算的代码,也为反向传播创建所需的数据结构。该方式生成更直观的代码,因为控制流使用标准的“for”和“if”来写。修补漏洞也变得更简单,因为运行时的断点、堆栈踪迹(stack trace)让你直接找到写的代码,而不是执行引擎里的编译函数。同样变量长度的时间递归神经网络,可用简单的 Python “for”循环在动态框架里实现。


# PyTorch (also works in Chainer)
# (this code runs on every forward pass of the model)
# “words” is a Python list with actual values in it
h = h0
for word in words:
   h = rnn_unit(word, h)


PyTorch  是第一个在性能、灵活性上媲美静态图框架的 “define-by-run”深度学习框架。这使它适合于开发几乎所有模型,从标准的卷积网络到最离谱的强化学习想法。下篇中,我们将一起看看 SPINN 的代码实现。




====================================分割线================================

本文作者:三川
本文转自雷锋网禁止二次转载,原文链接

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

相关文章
React系列二十二 - 云音乐项目实战
项目地址:https://github.com/coderwhy/hy-react-web-music 如果觉得不错,或者对你有帮助,点一个star~ coderwhy
29 0
从零到一搭建 react 项目系列之(一)
从零到一搭建 react 项目系列之(一)
23 0
从零到一搭建 react 项目系列之(六)
本篇主要介绍 react-router-v4 搭建。
32 0
使用IntelliJ Idea新建SpringBoot项目
简单给大家介绍一下我来创建SpringBoot项目使用的工具,本人使用IntelliJ Idea来创建项目,利用其中的Spring Initializr工具来快速创建项目。
2819 0
【Spring】基于IntelliJ IDEA搭建Maven
转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自【大学之旅_谙忆的博客】 IntelliJ IDEA下载地址: https://www.jetbrains.com/idea/download/ IntelliJ IDEA分为社区版和商业版,社区版免费,商业版功能强大很多。
1089 0
Spring Boot 项目构建 之 使用 Spring Boot 构建应用(Building an Application with Spring Boot)
Table of contents What you’ll build What you’ll need How to complete this guide Build with Gradle Build with Maven Build with Spring Tool Suit...
2016 0
+关注
玄学酱
这个时候,玄酱是不是应该说点什么...
20683
文章
438
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载