灵活且强大的张量操作,用于可读和可靠的代码。
支持Numpy,Pytorch,Tensorflow,Jax等。
torch.compile ,对阵列API标准的支持等等如果您需要令人信服的论据,以搁置时间来了解Einsum和Einops ... TimRocktäschel
用Pytorch和Einops编写更好的代码? Andrej Karpathy
慢慢地但可以肯定的是,Einops正在渗入我的代码中的每个角落。如果您发现自己在数十亿个尺寸的张量周围改组,这可能会改变您的生活NASIM RAHAMAN
更多推荐
简单而简单:
pip install einops教程是看到einops行动中的最方便的方式
Kapil Sachdeva记录了Einops的小型介绍。
einops具有简约而强大的API。
提供了三个核心操作(EINOPS教程显示了这些覆盖,重塑,换位,挤压/毫无气压,重复,瓷砖,连接,视图和大量降低)
from einops import rearrange , reduce , repeat
# rearrange elements according to the pattern
output_tensor = rearrange ( input_tensor , 't b c -> b c t' )
# combine rearrangement and reduction
output_tensor = reduce ( input_tensor , 'b c (h h2) (w w2) -> b h w c' , 'mean' , h2 = 2 , w2 = 2 )
# copy along a new axis
output_tensor = repeat ( input_tensor , 'h w -> h w c' , c = 3 )后来对家庭的添加是pack和unpack功能(比堆栈/拆分/连接的功能更好):
from einops import pack , unpack
# pack and unpack allow reversibly 'packing' multiple tensors into one.
# Packed tensors may be of different dimensionality:
packed , ps = pack ([ class_token_bc , image_tokens_bhwc , text_tokens_btc ], 'b * c' )
class_emb_bc , image_emb_bhwc , text_emb_btc = unpack ( transformer ( packed ), ps , 'b * c' )最后,einops提供了多字母名称的支持:
from einops import einsum , pack , unpack
# einsum is like ... einsum, generic and flexible dot-product
# but 1) axes can be multi-lettered 2) pattern goes last 3) works with multiple frameworks
C = einsum ( A , B , 'b t1 head c, b t2 head c -> b head t1 t2' ) EinMix是一个通用线性层,非常适合MLP混合器和类似的体系结构。
EINOPS提供层( einops为每个框架保留一个单独的版本),以反映相应的功能
from einops . layers . torch import Rearrange , Reduce
from einops . layers . tensorflow import Rearrange , Reduce
from einops . layers . flax import Rearrange , Reduce
from einops . layers . paddle import Rearrange , Reduce from torch . nn import Sequential , Conv2d , MaxPool2d , Linear , ReLU
from einops . layers . torch import Rearrange
model = Sequential (
...,
Conv2d ( 6 , 16 , kernel_size = 5 ),
MaxPool2d ( kernel_size = 2 ),
# flattening without need to write forward
Rearrange ( 'b c h w -> b (c h w)' ),
Linear ( 16 * 5 * 5 , 120 ),
ReLU (),
Linear ( 120 , 10 ),
)不再需要更平坦!
此外,火炬层是可以脚本且可编译的。操作是torch.com的,但由于torch.jit.script的限制而无法脚本。
einops代表爱因斯坦(Einstein)的操作符号(尽管“爱因斯坦的操作”更具吸引力,更容易记住)。
符号受到爱因斯坦总结的启发(尤其是由numpy.einsum操作)的启发。
einops符号? y = x . view ( x . shape [ 0 ], - 1 )
y = rearrange ( x , 'b c h w -> b (c h w)' )虽然这两条线在某些情况下执行相同的工作,但第二行提供了有关输入和输出的信息。换句话说, einops专注于接口:输入和输出是什么,而不是计算输出的方式。
下一个操作看起来相似:
y = rearrange ( x , 'time c h w -> time (c h w)' )但这为读者提供了提示:这不是我们正在处理的独立图像,而是序列(视频)。
语义信息使代码易于阅读和维护。
重新考虑同一示例:
y = x . view ( x . shape [ 0 ], - 1 ) # x: (batch, 256, 19, 19)
y = rearrange ( x , 'b c h w -> b (c h w)' )第二行检查输入是否具有四个维度,但是您也可以指定特定的维度。这是反对仅写有关形状的评论,因为评论不能阻止错误,没有测试,没有代码审查往往过时
y = x . view ( x . shape [ 0 ], - 1 ) # x: (batch, 256, 19, 19)
y = rearrange ( x , 'b c h w -> b (c h w)' , c = 256 , h = 19 , w = 19 )下面我们至少有两种定义深度操作的方法
# depth-to-space
rearrange ( x , 'b c (h h2) (w w2) -> b (c h2 w2) h w' , h2 = 2 , w2 = 2 )
rearrange ( x , 'b c (h h2) (w w2) -> b (h2 w2 c) h w' , h2 = 2 , w2 = 2 )至少有四种方法可以做到这一点。框架使用了哪一个?
这些细节被忽略了,因为通常没有什么区别,但是它会产生很大的不同(例如,如果您在下一阶段使用分组的卷积),并且您想在代码中指定这一点。
reduce ( x , 'b c (x dx) -> b c x' , 'max' , dx = 2 )
reduce ( x , 'b c (x dx) (y dy) -> b c x y' , 'max' , dx = 2 , dy = 3 )
reduce ( x , 'b c (x dx) (y dy) (z dz) -> b c x y z' , 'max' , dx = 2 , dy = 3 , dz = 4 )这些示例表明,我们不为1D/2D/3D池使用单独的操作,这些操作都以统一的方式定义。
在许多框架中定义了对深度和深度空间的空间,但是宽度到高度如何?干得好:
rearrange ( x , 'b c h (w w2) -> b c (h w2) w' , w2 = 2 )即使是简单的功能也通过不同的框架来定义不同
y = x . flatten () # or flatten(x)假设x的形状为(3, 4, 5) ,然后y具有形状...
(60,)(3, 20) einops在所有框架中都以相同的方式工作。
示例: tile与repeat会引起很多混乱。沿宽度复制图像:
np . tile ( image , ( 1 , 2 )) # in numpy
image . repeat ( 1 , 2 ) # pytorch's repeat ~ numpy's tile使用Einops,您无需解密重复哪个轴:
repeat ( image , 'h w -> h (tile w)' , tile = 2 ) # in numpy
repeat ( image , 'h w -> h (tile w)' , tile = 2 ) # in pytorch
repeat ( image , 'h w -> h (tile w)' , tile = 2 ) # in tf
repeat ( image , 'h w -> h (tile w)' , tile = 2 ) # in jax
repeat ( image , 'h w -> h (tile w)' , tile = 2 ) # in cupy
... ( etc .)推荐提供了用户对同一问题的看法。
Einops与...合作
此外,EINOPS可以与支持Python Array API标准的任何框架一起使用,其中包括
提供了devcontainer,可以在本地,服务器或github代码中使用此环境。首先从VS代码中的DevContainers开始,请克隆回购,然后单击“在Devcontainer中重新打开”。
从下一个版本开始,EINOPS将分发测试作为软件包的一部分。进行测试:
# pip install einops
python -m einops.tests.run_tests numpy pytorch jax --pip-install numpy pytorch jax是一个示例,可以提供任何可测试框架的子集。每个框架都针对Numpy进行了测试,因此这是测试的要求。
指定--pip-install将在当前Virtualenv中安装要求,如果依赖关系在本地安装,则应省略。
构建/测试文档:
hatch run docs:serve # Serving on http://localhost:8000/ 请使用以下Bibtex记录
@inproceedings{
rogozhnikov2022einops,
title={Einops: Clear and Reliable Tensor Manipulations with Einstein-like Notation},
author={Alex Rogozhnikov},
booktitle={International Conference on Learning Representations},
year={2022},
url={https://openreview.net/forum?id=oapKSVM2bcj}
}
einops与Python 3.8或更高版本一起工作。