If you often work on deep learning projects, you know that utter hassle of having two models that use different frameworks. Sometimes you have to just go ahead and reimplement a complex Tensorflow model in PyTorch, and you might feel like you’re wasting time!
如果您经常从事深度学习项目,那么您会很麻烦拥有两个使用不同框架的模型。 有时您必须继续并在PyTorch中重新实现复杂的Tensorflow模型,您可能会觉得自己在浪费时间 !
EagerPy, created by Raube, Bethge & Brendel et al (2020) to the rescue!
由Raube,Bethge和Brendel等人(2020)创建的EagerPy进行了救援!
EagerPy allows us to implement “code that works natively with PyTorch, Tensorflow, JAX, and NumPy.” Virtually everything in this post builds on Raube et al’s explanation of EagerPy.
EagerPy允许我们实现“可与PyTorch,Tensorflow,JAX和NumPy一起使用的代码。” 实际上,本文中的所有内容都基于Raube等人对EagerPy的解释。
The easiest way to conceptualize how EagerPy works is to think of Keras.
概念化EagerPy是如何工作的,最简单的办法是考虑Keras的。
So, you know how Keras works on either a Tensorflow OR Theano backend? Well, EagerPy does something similar, except it does it for eager execution, instead of a graph-based approach.
因此,您知道Keras如何在Tensorflow或Theano后端上工作吗? 好吧,EagerPy做了类似的事情,除了它是为渴望执行而做的,而不是基于图的方法。
For context, deep learning frameworks are divided into graph-based approaches and eager execution. Eager execution uses a “define-by-run” approach, which means we can build “graphs on the fly” (as opposed to having to build the entire graph at once).
对于上下文,深度学习框架分为基于图的方法和渴望执行。 急切的执行使用“按运行定义”方法,这意味着我们可以动态构建“图形”(而不必一次构建整个图形)。
Tensorflow 2和PyTorch之间的差异 (Differences Between Tensorflow 2 and PyTorch)
The differences between Tensorflow 2 and PyTorch can be divided into semantic and syntactic differences.
Tensorflow 2和PyTorch之间的差异可以分为语义和语法差异。
First, semantic differences. A fundamental feature of a neural network is that it requires us to compute the gradient and backpropagate so that we can adjust the weights. PyTorch and Tensorflow 2 do this differently.
首先,语义上的差异。 神经网络的基本特征是它需要我们计算梯度和反向传播,以便我们可以调整权重。 PyTorch和Tensorflow 2的执行方式有所不同。
PyTorch involves three separate functions: requires_grad_(), zero_grad() and backward(). Tensorflow uses a “more high-level GradientTape context manager.”
PyTorch涉及三个独立的函数:require_grad _(),zero_grad()和Backward()。 Tensorflow使用“更高级的GradientTape上下文管理器”。
At the syntactic level, there are differences in the names of variables, classes, and functions.
在语法级别,变量,类和函数的名称有所不同。
If not for EagerPy, we would need to use NumPy to allow these different deep learning frameworks to work together. This often requires “expensive memory copies between CPU (NumPy) and GPU (PyTorch, TensorFlow, JAX) and vice versa.”
如果不是EagerPy,我们将需要使用NumPy来允许这些不同的深度学习框架协同工作。 这通常需要“在CPU(NumPy)和GPU(PyTorch,TensorFlow,JAX)之间进行昂贵的内存复制,反之亦然。”
EagerPy provides a “unified API” that “works natively” with each framework. The mapping between frameworks is done without extra “computational overhead.”
EagerPy提供了一个“统一的API” , 可与每个框架“本地工作” 。 框架之间的映射无需额外的“计算开销”。
EagerPy “keeps references to the original native framework-specific tensors” and “delegates all operations to the respective framework.”
EagerPy“保留对原始本地框架特定张量的引用”,并“将所有操作委托给相应框架”。
设计与实施 (Design and Implementation)
Raube et al share two primary purposes of EagerPy and two secondary purposes.
Raube等人拥有EagerPy的两个主要目的和两个次要目的。
The primary purposes:
主要目的:
- provide a “unified API” for eager execution 提供渴望执行的“统一API”
- maintain the “native performance of underlying frameworks” 保持“基础框架的本机性能”
The secondary purposes:
次要目的:
- provide a “fully chainable API” 提供“完全可链接的API”
- provide “type-checking support” 提供“类型检查支持”
Unified API
统一API
For many functions, like “sum” and “log”, unifying the APIs is as simple as calling the corresponding function in JAX, Tensorflow or PyTorch. For computing the gradient, amongst the three frameworks, PyTorch uses the most low-level API (requires the most function calls and gives the user the most control). Tensorflow uses GradientTape as mentioned earlier, and JAX uses the most high-level API.
对于许多函数,例如“ sum”和“ log”,统一API就像在JAX,Tensorflow或PyTorch中调用相应的函数一样简单。 为了计算梯度,在这三个框架中,PyTorch使用了最底层的API(需要最多的函数调用并为用户提供最大的控制权)。 Tensorflow使用如前所述的GradientTape,而JAX使用最高级的API。
The unified EagerPy API “reimplements” the JAX method of computing the gradient in PyTorch and Tensorflow.
统一的EagerPy API“重新实现”了在PyTorch和Tensorflow中计算梯度的JAX方法。
A cool thing about EagerPy is its “test suite.” After you make a pull request to add a function or class to EagerPy, the test suite makes sure that your addition is consistent across the frameworks (PyTorch, Tensorflow, and JAX) and documentations.
关于EagerPy的一件很酷的事情是它的“测试套件”。 在发出向EagerPy添加函数或类的请求请求之后,测试套件将确保您的添加在框架(PyTorch,Tensorflow和JAX)和文档之间保持一致。
Native Performance
本机性能
As we discussed earlier, if not for EagerPy, unifying two given deep learning frameworks would have to be done through NumPy. This process would use excessive memory, compared to native performance.
正如我们之前所讨论的,如果不是针对EagerPy,则必须通过NumPy统一两个给定的深度学习框架。 与本机性能相比,此过程将使用过多的内存。
Fully Chainable API
完全可链接的API
We often want to perform several functions sequentially, such as “sum”, “square”, “multiply,” With the chainable API, we can do something like x.sum().square().multiply().
我们经常希望依次执行几个功能,例如“ sum”,“ square”,“ multiply”。使用可链接的API,我们可以执行x.sum()。square()。multiply()之类的操作。
Type Checking
类型检查
Neither Tensorflow, PyTorch nor JAX provides type annotations. A type annotation allows you to ensure that a value is of a certain type. For example, when declaring a function, you can do something like “argument: annotation.” If the input type is wrong, EagerPy will raise an error based on your annotation.
Tensorflow,PyTorch或JAX都不提供类型注释。 类型注释使您可以确保值是特定类型的。 例如,在声明函数时,您可以执行“ argument:注解”之类的操作。 如果输入类型错误,EagerPy将基于您的注释引发错误。
例子 (Examples)
Raube et al provide the following code example — implementing a framework-agnostic norm function in EagerPy.
Raube等人提供了以下代码示例—在EagerPy中实现与框架无关的规范函数 。
import eagerpy as ep def norm(x):
x = ep.astensor(x) # native tensor to EagerPy tensor
result = x. square().sum().sqrt()
return result.raw # EagerPy tensor to native tensor
用例 (Use Cases)
Raube et al provide the example of Foolbox, an adversarial attacks library that supports multiple deep learning frameworks, originally by using a NumPy interface. This repo has been reimplemented to be run natively, using EagerPy, thus saving lots of memory.
Raube等人提供了Foolbox的示例,该库是一个对抗攻击库,最初使用NumPy接口来支持多个深度学习框架。 此仓库已被重新实现为使用EagerPy在本地运行,从而节省了大量内存。
下一步 (Next Steps)
You should definitely experiment with the git repository and here is the associated documentation. The documentation includes lots of starter code that you can play with.
您绝对应该尝试使用git存储库 ,这是相关的文档 。 该文档包含许多您可以使用的入门代码。
This is a pretty exciting code base, and I’m sure it would benefit from pull requests for expanded functionality. So do check it out!
这是一个非常令人兴奋的代码库,我确信它将受益于对扩展功能的请求。 因此,请检查一下!
Thanks for reading!
谢谢阅读!