Flexible und leistungsstarke Tensoroperationen für lesbare und zuverlässige Code.
Unterstützt Numpy, Pytorch, TensorFlow, Jax und andere.
torch.compile , Unterstützung des Array-API-Standards und mehrFür den Fall, dass Sie überzeugende Argumente benötigen, um Zeit zu legen, um etwas über Einsum und Einops zu lernen ... Tim Rocktäschel
Bessere Code mit Pytorch und Einops schreiben? Andrej Karpathy
Langsam aber sicher sickert Einops in jede Ecke und die Winne meines Codes ein. Wenn Sie sich um die dimensionalen Tensoren von Bazillion schlurfen, könnte dies Ihr Leben verändern, Nasim Rahaman
Weitere Testimonials
Schlicht und einfach:
pip install einops Tutorials sind die bequemste Möglichkeit, einops in Aktion zu sehen
Kapil Sachdeva verzeichnete ein kleines Intro in Einops.
einops hat eine minimalistische, aber mächtige API.
Drei Kernvorgänge (EINOPS -Tutorial zeigt die Deckungsstapel, Umgestaltung, Transposition, Squeeze/Unquice, Wiederholung, Fliesen, Verkettung, Ansicht und zahlreiche Reduzierungen)
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 ) Spätere Ergänzungen zur Familie sind pack und unpack (besser als Stack/Split/Conatenate):
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' )Schließlich bietet Einops Einsum eine Unterstützung von mehrlebigen Namen:
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 ist eine generische lineare Schicht, perfekt für MLP -Mixer und ähnliche Architekturen.
Einops liefert Schichten ( einops führt eine separate Version für jedes Framework), die entsprechende Funktionen widerspiegeln
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 ),
)Keine Flach mehr benötigt!
Zusätzlich sind Fackelschichten als skript-möglich und kompilierbar. Operationen sind fackel.comPile-ABLEA, aber aufgrund von Einschränkungen von Torch.jit.Script nicht skript-möglich.
einops steht für Einstein-inspirierte Notation für Operationen (obwohl "Einstein-Operationen" attraktiver und leichter zu erinnern ist).
Die Notation wurde lose durch Einstein -Summierung (insbesondere durch numpy.einsum -Operation) inspiriert.
einops -Notation verwenden?! y = x . view ( x . shape [ 0 ], - 1 )
y = rearrange ( x , 'b c h w -> b (c h w)' ) Während diese beiden Zeilen in einem Kontext den gleichen Job machen, liefert der zweite Informationen über Eingabe und Ausgabe. Mit anderen Worten, einops konzentriert sich auf die Schnittstelle: Was ist Eingabe und Ausgabe , nicht wie die Ausgabe berechnet wird.
Die nächste Operation sieht ähnlich aus:
y = rearrange ( x , 'time c h w -> time (c h w)' )Aber es gibt dem Leser einen Hinweis: Dies ist keine unabhängige Bilde, die wir verarbeiten, sondern eine Sequenz (Video).
Semantische Informationen erleichtern den Code leichter zu lesen und zu warten.
Überdenken Sie das gleiche Beispiel:
y = x . view ( x . shape [ 0 ], - 1 ) # x: (batch, 256, 19, 19)
y = rearrange ( x , 'b c h w -> b (c h w)' )Die zweite Zeile prüft, dass die Eingabe vier Dimensionen aufweist, aber Sie können auch bestimmte Dimensionen angeben. Das ist im Gegensatz dazu nur, Kommentare zu Formen zu schreiben, da Kommentare Fehler nicht verhindern, nicht getestet und ohne Code -Überprüfung dazu neigen, veraltet zu sein
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 )Im Folgenden haben wir mindestens zwei Möglichkeiten, den Tiefenbetrieb zu definieren
# 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 )Es gibt mindestens vier weitere Möglichkeiten, dies zu tun. Welches wird vom Framework verwendet?
Diese Details werden ignoriert, da dies normalerweise keinen Unterschied macht, aber einen großen Unterschied machen kann (z. B. wenn Sie in der nächsten Stufe gruppierte Konvolutionen verwenden) und dies in Ihrem Code angeben möchten.
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 )Diese Beispiele haben gezeigt, dass wir keine separaten Operationen für 1D/2D/3D -Pooling verwenden. Diese sind alle auf einheitliche Weise definiert.
Space-to-Depth und Tiefe-to-Space werden in vielen Frameworks definiert, aber wie wäre es mit Breite zu Höhe? Bitte schön:
rearrange ( x , 'b c h (w w2) -> b c (h w2) w' , w2 = 2 )Auch einfache Funktionen werden durch verschiedene Frameworks unterschiedlich definiert
y = x . flatten () # or flatten(x) Angenommen, die Form von x war (3, 4, 5) , dann hat y Form ...
(60,)(3, 20) einops funktioniert in allen Frameworks genauso.
Beispiel: tile gegen repeat verursachen viel Verwirrung. Um das Bild entlang der Breite zu kopieren:
np . tile ( image , ( 1 , 2 )) # in numpy
image . repeat ( 1 , 2 ) # pytorch's repeat ~ numpy's tileMit Einops müssen Sie nicht entschlüsseln, welche Achse wiederholt wurde:
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 .)Testimonials bieten die Perspektive der Benutzer auf dieselbe Frage.
Einops funktioniert mit ...
Zusätzlich können Einops mit jedem Framework verwendet werden, das den Python -Array -API -Standard unterstützt, der gehört
DevContainer wird bereitgestellt, diese Umgebung kann lokal oder auf Ihrem Server oder in GitHub -Codenspazialen verwendet werden. Beginnen Sie, um mit DevContainers in VS Code zu beginnen, klonen Sie ein, klicken Sie auf "Wiedereröffnung in DevContainer".
Ab der nächsten Version verteilen Einops Tests als Teil des Pakets. Tests ausführen:
# pip install einops
python -m einops.tests.run_tests numpy pytorch jax --pip-install numpy pytorch jax ist ein Beispiel, eine Teilmenge von Testsable -Frameworks kann bereitgestellt werden. Jedes Rahmen wird gegen Numpy getestet, daher ist es eine Voraussetzung für Tests.
Angeben --pip-install installiert die Anforderungen in aktuellem Virtualenv und sollte weggelassen werden, wenn die Abhängigkeiten lokal installiert werden.
Dokumente erstellen/testen:
hatch run docs:serve # Serving on http://localhost:8000/ Bitte verwenden Sie den folgenden Bibtex -Datensatz
@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 arbeitet mit Python 3.8 oder höher.