Execution TensorFlow推出Eager 紧跟未来深度学习框架需求 (executive)
雷锋网按:Google的TensorFlow是AI学习者中使用率最高、名气也最大的深度学习框架,但由于TensorFlow最早是基于Google的需求开发的,在实际使用上也会存在如 文档乱、调试难 等诸多缺点,而且开发时间比较早未能及时对一些新的需求进行反应(据雷锋网了解,由于缺乏类似PyTroch、DyNet的动态图功能,Lecun就不止一次吐槽过TensorFlow是“过时的深度学习框架”(yesterday deep learning framework)),而针对用户的需求,Google也在对TensorFlow不断改进。在10月31日,Google为TensorFlow引入了动态图机制Eager Execution,而Google Brain Team的工程师Asim Shankar和Wolff Dobson也在Google官方博客发文详细阐述了这一功能带来的变化,雷锋网摘编如下:
同时Google还举了一些使用 Eager Execution 的直观例子,例如使用两个矩阵相乘的代码是这样编写的:
使用 print 或者 Python 调试器检查中间结果也非常直接。
梯度与自定义梯度
大多数 TensorFlow 用户对自动微分感兴趣。因为每次调用期间可能会产生不同的运算,因此我们将所有的正向运算录到一个“磁带”上,并在计算梯度时进行反向运算。计算了梯度之后,这个“磁带”就没用了。
这一API与 autoGRAD 包非常类似,例子如下:
在这里,gradients_function 先调用了一个预先定义的 Python 函数 square() 作为参数,并返回一个 Python 可调用函数 grad 来计算相对于输入的 square() 的偏导数。如以上例子中当输入为 3.0 时, square() 的计算结果为9,而 grad(3.0) 为对 square() 进行偏导,其计算结果为 6。
同样,我们也可以调用 gradient_function 计算 square 的二阶导数。
此外,用户也可能需要为运算或函数自定义梯度。这一功能可能有用,例如,它可以为一系列运算提供了更高效或者数值更稳定的梯度。
以下是一个自定义梯度的例子。我们先来看函数 log(1 + e^x),它通常用于计算交叉熵和对数似然。
上述例子中,当 x=0 时,梯度计算表现良好。然而由于数值的不稳定性,当 x=100 时则会返回`nan` 。使用上述函数的自定义梯度可用于分析简化梯度表达式。
使用 Eager 和 Graphs
Eager execution 使开发和调试互动性更强,但是 TensorFlow graphs 在分布式训练、性能优化和生产部署中也有着诸多优势。
当启用 eager execution 时,执行运算的代码同时还可以构建一个描述 eager execution 未启用状况的计算图。要将模型转换成图形,只需在新的 Python 进程中运行同样的代码即可。这一做法可以从检查点保存和修复模型变量值,这允许我们在 eager(命令式)和 graph(声明式)编程之间轻松转换。通过这种方式可以轻松地将启用 eager execution 开发出的模型导出到生产部署中。
在不久的将来,我们将提供工具来选择性地将模型的某些部分转换为图形。这样就可以融合部分计算(如自定义RNN单元的内部),以实现高性能并同时保持eager execution的灵活性和可读性。
新功能势必带来代码编写上的变化。Google还很贴心地给出了几个Tips:
更多内容可参阅 Google博客 。
原创文章,未经授权禁止转载。详情见 转载须知 。