عمليات الموتر المرنة والقوية للرمز القابل للقراءة والموثوقة.
يدعم Numpy و Pytorch و TensorFlow و Jax وغيرها.
torch.compile بدون تدفقفي حال كنت بحاجة إلى مقنعات مقنعة لتخصيص وقت للتعرف على Einsum و Einops ... Tim Rocktäschel
كتابة رمز أفضل مع Pytorch و Einops؟ Andrej Karpathy
ببطء ولكن بثبات ، تتسرب Einops إلى كل زاوية وركن من الكود الخاص بي. إذا وجدت نفسك تتجول حول الموتر الأبعاد البازيليون ، فقد يغير هذا حياتك ناسيم رهامان
المزيد من الشهادات
عادي وبسيط:
pip install einops البرامج التعليمية هي الطريقة الأكثر ملاءمة لرؤية einops في العمل
سجل Kapil Sachdeva مقدمة صغيرة إلى Einops.
لدى einops واجهة برمجة تطبيقات الحد الأدنى ولكنها قوية.
ثلاث عمليات متوفرة (يوضح تعليمي 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 Einsum دعمًا للأسماء المتعددة:
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.compile-able ، ولكنها ليست قادرة على البرنامج النصي بسبب قيود torch.jit.script.
تعني einops التدوين المستوحى من آينشتاين للعمليات (على الرغم من أن "عمليات آينشتاين" أكثر جاذبية وأسهل في تذكرها).
استلهم التدوين بشكل فضفاض من تجميع آينشتاين (على وجه الخصوص من خلال عملية 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 مع أي إطار يدعم معيار API Array Array ، والذي يتضمن
يتم توفير DevContainer ، ويمكن استخدام هذه البيئة محليًا ، أو على الخادم الخاص بك ، أو داخل مساحات GitHub. للبدء مع DevContainers في VS Code ، استنساخ repo ، وانقر فوق "إعادة فتح في 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 أو أحدث.