姓名:郭金 学号:17101223407
转载自英语原文:http://research.googleblog.com/2017/11/tangent-source-to-source-debuggable.html
【嵌牛导读】:Google Brain 今日开源了一款 Python 库,名为 Tangent,专门用于实现自动微分功能。
【嵌牛鼻子】:AI、Tangent、Python
【嵌牛提问】: 我们要如何为普通Python代码生成导数?
【嵌牛正文】:
相较于现有机器学习资源训,Tangent 属于一套源到源系统,其使用 Python f 函数并生成另一新 Python 函数以计算 f 梯度。通过这种方式,用户能够更好地理解梯度计算流程,并轻松完成用户级梯度编辑与调试任务。Tangent 亦拥有以下机器学习模型调试与设计能力:
轻松调试您的反向传播 快速梯度调整
正向模式自动差异化
高效 Hessian 矢量产品
代码优化
在今天的文章中,我们将对 Tangent API 作出概述。文章内容涵盖如何在 Python 中利用 Tangent 生成易于解释、调试以及修改的梯度代码。
神经网络(简称 NN)已经在图像、视频、音频以及文本类机器学习模型领域取得了巨大成功。而让我们得以训练出能够在此类任务中带来良好表现的神经网络的基本抽象思路,则源自 30 年前即已诞生的概念,即反向模式自动微分(亦被称为反向传播)——其中包括两次神经网络通过流程。首先,我们运行“正向传播”以计算每个节点的输出值。之后,我们运行“反向传播”以计算一系列层数,从而确定如何更新权重以提高模型的准确性。
要对神经网络进行训练并面向新型架构加以研究,要求我们以正确、高效且便捷的方式实现导数计算任务。如果我们的模型训练效果不佳,或者尝试构建自己尚不了解的新鲜事物,则必然需要有能力对其作出调试。所谓自动微分,或者简称“autodiff”,是指一项用于计算计算机程序内负责表示某些数学函数的导数的技术手段。目前,几乎全部机器学习库都在使用自动微分技术。
现有各类资源库在实现自动微分方面,主要采用追踪程序执行(立足于 TF Eager、PyTorch 以及 Autograd 等运行时内),或者构建动态数据流图形而后对图形加以微分(进行提前微分,TensorFlow 即采取此种方法)的方式。相比之下,Tangent 则可直接对 Python 源代码进行提前自动微分,并以输出结果的方式生成 Python 源代码。
如此一来,大家将能够像读取其它程序一样,直接读取自动导数代码。Tangent 不仅适用于希望利用 Python 编写模型的研究人员与学生,同时亦能够在不牺牲灵活性与速度表现的前提下读取并调试自动生成的导数代码。大家可以轻松检查并调试您利用 Tangent 编写的模型,且无需使用任何特殊工具或者间接性方式。Tangent 能够对接 Python 生态系统内庞大且不断增加的各类功能子集,提供其它 Python 机器学习库所不具备的额外 autodiff 特性,性能出色且可与 TensorFlow 及 NumPy 相兼容。
Python 代码自动微分
那么我们要如何为普通 Python 代码生成导数?以 tf.exp 或 tf.log 为代表的各类数学函数中皆包含导数,我们可以通过编写此类函数建立反向传播。同样的,语法片段(例如子例程、条件与循环等)也可拥有对应的反向传播版本。Tangent 中包含为每项 Python 语法生成导数代码的对应方法,同时亦囊括大量面向 NumPy 与 TensorFlow 函数的调用选项。Tangent 拥有一个单函数 API:
以下流程图展示了在 Python 函数中调用 tangent.grad 时会发生怎样的情况:
如果您打算输出自己的导数,则可运行:
从底层角度来看,tangent.grad 会首先提取您传递给它的 Python 函数源代码。Tangent 拥有大量 Python 语法导数配方库,同时亦支持 TensorFlow Eager 函数。函数 tangent.grad 随后会以反向顺序遍历您的代码,查找匹配的反向传播配方,并将其浯对导数函数末尾。这种逆序处理方式拥有自己的特定名称:反向模式自动微分。
以上 df 函数仅适用于标量(非数组)输入内容。Tangent 亦支持:
利用 TensorFlow Eager 函数 ,以处理数字数组 子例程 控制流
虽然我们选择 TensorFlow Eager 支持作为起点,但 Tangent 绝不仅限于一种或者多种特定库——我们乐于将更多 PyTorch 或者 MXNet 导数配方添加到 Tangent 库当中。
未来展望
Tangent 目前在 github.com/google/tangent 上以开源形式公开,感兴趣的朋友可以前往下载并进行安装。Tangent 目前仍处于实验性阶段,因此在实际使用中可能存在一些错误。希望大家能够在 GitHub 上向我们报告您发现的问题,我们将尽最大努力加以解决。
我们努力在 Tangent 当中为 Python 语言的更多要素(例如闭包、内联函数定义、类以及更多 NumPy 与 TensorFlow 函数)添加支持。我们也希望在未来逐步实现更为先进的自动微分与编译器功能,例如内存与计算间的自动权衡、自动性更高的优化以及 lambda 提升。
我们有意携手技术社区共同推进 Tangent 的发展。我们欢迎您提交修复与功能性质的 pull 请求。感谢您的参与!
致谢
Bart van Merriënboer 在实习期间为 Tangent 项目的各个方面作出了卓越贡献,Dan Moldovan 领导了 TF Eager 集成、基础设施与基准测试等工作。此外,感谢谷歌 Brain 团队对本文编撰工作的支持,同时特别感谢 Sanders Kleinfeld、Matt Johnson 以及 Aleks Haecky 在技术层面对本文提供的宝贵贡献。