Ο συμβολισμός άθροισης Αϊνστάιν είναι ένας συνοπτικός και ισχυρός τρόπος αναπαράστασης λειτουργιών τανυστή, που χρησιμοποιείται συχνά στη φυσική και τη μηχανική μάθηση. Μας επιτρέπει να γράφουμε σύνθετους υπολογισμούς σε τανυστές σε συμπαγή μορφή. Θα καλύψουμε τα βασικά για την άθροιση του Αϊνστάιν, πώς να το χρησιμοποιήσετε στην Python με το Numpy και το Tensorflow και θα δώσουμε παραδείγματα για να επεξηγήσουμε τη χρήση του.
Βασικά στοιχεία της άθροισης του Αϊνστάιν
Ο συμβολισμός άθροισης Αϊνστάιν (Einsum) βασίζεται στην ιδέα της άθροισης επαναλαμβανόμενων δεικτών σε εκφράσεις τανυστού. Βασίζεται στους ακόλουθους δύο κανόνες:
1. Άθροισμα σε επαναλαμβανόμενους δείκτες: Εάν ένας δείκτης εμφανίζεται δύο φορές σε έναν όρο, αθροίζεται σε
2. Ελεύθεροι δείκτες: Οι δείκτες που εμφανίζονται μόνο μία φορά είναι ελεύθεροι δείκτες και αντιπροσωπεύουν τους άξονες του τανυστή εξόδου
Ας το επεξηγήσουμε αυτό με το παράδειγμα του πολλαπλασιασμού δύο πινάκων Α και Β: ο προκύπτων πίνακας C ορίζεται ως
Στην Python, και οι δύο βιβλιοθήκες Numpy και Tensorflow παρέχουν μια συνάρτηση einsum.
Numpy
import numpy as np
# Define two matrices A and B
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# Perform matrix multiplication using einsum
C = np.einsum('ij,jk->ik', A, B)
print(C)
# [[19 22]
# [43 50]]
Στο παραπάνω παράδειγμα, το ij,jk->ik
είναι η συμβολοσειρά einsum:
Το «ij» αντιπροσωπεύει τους δείκτες του πίνακα Α
Το «jk» αντιπροσωπεύει τους δείκτες του πίνακα Β
Το ->ik
καθορίζει τους δείκτες του πίνακα εξόδου C
Η πράξη αθροίζεται πάνω από τον δείκτη j
Ο ίδιος κώδικας στο Tensorflow θα μοιάζει
import tensorflow as tf
# Define two matrices A and B
A = tf.constant([[1, 2], [3, 4]], dtype=tf.float32)
B = tf.constant([[5, 6], [7, 8]], dtype=tf.float32)
# Perform matrix multiplication using einsum
C = tf.einsum('ij,jk->ik', A, B)
print(C)
# tf.Tensor(
# [[19. 22.]
# [43. 50.]], shape=(2, 2), dtype=float32)
Περισσότερα παραδείγματα
Εσωτερικό γινόμενο διανυσμάτων
Το εσωτερικό γινόμενο (σημείο γινόμενο) δύο διανυσμάτων a και b ορίζεται ως
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.einsum('i,i->', a, b)
print(c) # Output: 32
Εξωτερικό προϊόν διανυσμάτων
Το εξωτερικό γινόμενο δύο διανυσμάτων a και b δίνεται από:
C = np.einsum('i,j->ij', a, b)
print(C)
# Output
# [[4 5 6]
# [8 10 12]
# [12 15 18]]
Μεταφορά μιας μήτρας
Η μετάθεση ενός πίνακα Α μπορεί να ληφθεί με την εναλλαγή των δεικτών του
A_transpose = np.einsum('ij->ji', A)
print(A_transpose)
# Output
# [[1. 3.]
# [2. 4.]]
Trace of a Matrix
Το ίχνος ενός πίνακα Α είναι το άθροισμα των διαγώνιων στοιχείων του:
trace = np.einsum('ii->', A)
print(trace)
# Output: 5.0
Πολλαπλασιασμός Matrix παρτίδας
Το Einsum είναι ιδιαίτερα χρήσιμο για παρτίδες. Ας υποθέσουμε ότι έχουμε μια παρτίδα πινάκων Α και Β και θέλουμε να πολλαπλασιάσουμε τους αντίστοιχους πίνακες στην παρτίδα:
A = np.random.rand(3, 2, 2)
B = np.random.rand(3, 2, 2)
# Perform batch matrix multiplication
C = np.einsum('bij,bjk->bik', A, B)
print(C)
Εδώ, το «b» αντιπροσωπεύει τη διάσταση παρτίδας.
Πλεονεκτήματα του συμβολισμού Einsum
1. Συνοπτικότητα: Ο συμβολισμός Einsum είναι συμπαγής και μπορεί να αναπαριστά περίπλοκες πράξεις συνοπτικά
2. Ευελιξία: Μπορεί να χειριστεί μια μεγάλη ποικιλία λειτουργιών τανυστή χωρίς ρητή αναμόρφωση ή μεταφορά συστοιχιών
3. Αποδοτικότητα: Πολλές βιβλιοθήκες βελτιστοποιούν τις λειτουργίες einsum εσωτερικά, οδηγώντας δυνητικά σε καλύτερη απόδοση.