本篇文章3509字,读完约9分钟
杜伟、小船这一新的python框架对库开发人员和客户都有很大的好处。 近年来,深度学习行业的进展与深度学习框架的开发同步进行。 这些框架为自动微分和gpu加速提供了高度高效的api,用相对较少的简单代码实现了非常多的复杂强大的深度学习模型。 最初,theano、caffe、mxnet、tensorflow、cntk等许多受欢迎的深度学习框架采用了基于图的方法。 客户必须先定义静态数据流图表,然后有效地在微分、编译和gpu上运行它。 因此,预先知道整个计算图有助于实现高性能。 但是,这种方法很难实现具有模型调试和rnn等转换图的动态模型。 因此,比较这种方法的局限性,深度学习模型的eager execution成为深度学习研究行业的主流方法。 客户不再需要预先构建静态数据流图,eager execution框架本身可以提供define-by-run的api,从而可以快速构建临时动态图。 现在两个主要的深度学习框架pytorch和tensorflow采用了eager execution方法。 在本文中,来自德国图宾根大学和图宾根伯恩斯坦计算神经科学中心的研究者可以扩展eager execution,制作自动且符合pytorch、tensorflow、jax、numpy的代码。 eagerpy既对库开发人员又对顾客有用 论文地址: arxiv/abs/2008.04175v1项目地址: github/jonasrauber/eagerpyeagerpy可以编写独立于框架的( framework-agnostic )代码 这样,首先对新的库开发人员来说,不仅要选择和支持这些主要的深度学习框架,或者重新实现各个框架的库。 其次,对于这些库的采用者来说,也可以更容易地在深度学习框架之间切换,而无需锁定到特定的第三方库。 不仅如此,个别框架的采用者也可以从eagerpy中受益 接下来我们来看看eagerpy的具体设计与实现 eagerpy的设计和eagerpy的构筑考虑了4个设计目标 两个首要目标是为需要执行操作的人提供统一的api,保持底层框架的原始性能。 这两个主要目标定义了eagerpy是什么,因此是设计的核心。 与底层框架特定的api相比,完全可链接的api和全面的类型检查支持这两个附加目标使eagerpy的采用变得容易和安全。 尽管进行了这些变更和改良,研究者还是设法不损害不必要的熟练度( familiarity )。 只要有意义,eagerpy api就遵循numpy、pytorch和jax设置的标准。 统一的api为了实现语法上的一致性,研究者以适当的方式定义抽象tensor类,使用实例变量保留本机张量( native tensor ),在各自支持的框架中实现特定的子类, 许多操作(如sum和log )都像调用底层框架一样简单。 对于其他操作,员工人数稍多。 最难的是统一自动微分api pytorch采用了低级autograd api,允许此api,但也需要正确控制反向传输。 tensorflow采用基于渐变磁带的更高级的api jax采用基于微分函数的相当高级的api 因此,为了统一这些,eagerpy模仿了jax的高级功能api,用pytorch和tensorflow重新实现。 eagerpy用value_and_grad_fn ( )函数打开。 此外,还可以创建所有受支持的框架和自动执行的代码,因此不仅需要语法,还需要语义统一。 为了保证这一点,eagerpy附带了一个大测试套件,用于验证不同框架的特定子类之间的一致性。 所有pull-request都自动运行,必须通过才能合并新代码。 测试套件也可以作为受支持的操作和参数组合的最终参考。 这样可以在实践中引出测试驱动程序开发过程,而不会在文档和实现之间产生矛盾。 原始性能没有eagerpy,想要与不同深度的学习框架交互的代码必须用numpy实现。 这需要在cpu(numpy )和gpu(pytorch、tensorflow、jax )之间进行昂贵的内存复制,反之亦然。 此外,虽然多个计算只在cpu上执行,但是为了避免这种情况,eagerpy仅保存对原来帧的特定张量的引用(例如gpu上的pytorch张量),将所有操作委托给相应的帧。 这几乎不产生计算开销。 多个运算(如完全可链接的api总和和平方)使用张量返回一个张量。 通常,这些运算是按顺序调用的。 例如,使用平方和平方根计算l2范数 在eagerpy中,所有的运算都是张量对象可以使用的方法 这使您可以按它们的自然顺序( x.square().sum().sqrt ( ) )链接操作。 相反,例如,numpy需要相反的操作程序np.sqrt(np.square(x).sum ( ) )。 类型检查在python3.5中,python语法的扩展实现了类型注释的支持( van rossum等,年)。 即使有类型注释,python也是动态类型化的编程语言,当前运行时忽略了所有类型注释。 但是,在执行代码之前,可以在静态代码拆卸器中检查这些类型的注释。 eagerpy是具有所有参数和返回值的全面类型的注释,使用mypy(lehtosalo等人,年)检查这些注释。 这有助于捕获eagerpy的漏洞。 否则,就不会发现这些漏洞。 eagerpy客户可以输入自己的代码注释,并根据eagerpy的函数签名( function signature )自动检查代码,从而进行进一步优化。 这些很重要,因为tensorflow、numpy和jax现在本身没有提供类型注释。 EAGER的代码实例分析下面的代码1是通用EAGER范数函数,可以用任何帧中的本机张量调用,返回的范数依然用作同一帧中的本机张量。 代码1 :与框架无关的范数函数 eagerpy和原生张量之间的转换原生张量可以是pytorch gpu或cpu张量,如代码2所示:代码2 :原生pytorch张量 也可以是tensorflow张量,如代码3所示:代码3 :本机tensorflow张量 可以是jax数组,如下面的代码4所示。 代码4 :本机jax数组 可以是numpy数组,如代码5所示。 代码5 :本机numpy数组 无论是哪种原生张量,一般都使用ep.astensor转换为适当的eagerpy张量。 此过程通过采用正确的eagerpy张量类来自动封装本机张量。 另外,最初的本机张量一般可以利用. raw属性进行访问 完整示例如下代码6所示: eagerpy和本机张量的转换 函数中一般将所有的输入变换为eagerpy张量 这可以单独调用ep.astensor,但如果采用ep.astensors,代码会更简洁。 要实现与框架无关的通用函数,请使用上述转换函数定义与简单框架无关的函数,如代码8所示。 代码8 :与简单框架无关的范数函数。 范数函数用tensorflow张量调用,如下述代码9所示。 此外,如果用eagerpy张量调用函数,如上面的代码8所示,则ep.astensor调用只返回其输入。 但是,最后一行代码的result.raw调用仍然提取底层本机张量。 一般来说,实现的通用函数优选能够透明地操作任意的本机张量和eagerpy张量。 也就是说,返回类型应该总是与输入类型一致。 这在foolbox等库中非常有用,可以采用用户,解决eagerpy和本机张量。 因此,eagerpy提供了上述转换函数的两个派生函数。 可以分别在ep.astensor_和ep.astensors_中返回可以恢复输入类型的反转函数。 如果astensor_的输入是本机张量,则restore_type与. raw相同。 如果原始输入是eagerpy张量,则restore_type不调用. raw。 因此,我们可以对任何输入创建透明的改良版框架无关通用函数。 最后,使用ep.astensors_转换和恢复多个输入,如下代码11所示。 最近,kdd发表了最佳论文、最佳学生论文等多项奖项。 其中,最佳学生论文奖由杜克大学李昂、杨幻和、陈怡然和北航段逸骁、杨建磊获得。 为了让网民更详细地理解这篇论文,9月3日最新一期机器的芯线论文共享向我们介绍了被邀请为最好的学生论文的李昂。 © the end转载请联系本公众号接受授权投稿或要求报道: content@jiqizhixin原标题:“符合api统一、清洁、pytorch、tf,新型eagerpy实现多框架无缝连接。