靈活且強大的張量操作,用於可讀和可靠的代碼。
支持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或更高版本一起工作。