Τα μοντέλα που βασίζονται σε μετασχηματιστές φημίζονται για την ικανότητά τους να αναλύουν και να ερμηνεύουν πολύπλοκο κείμενο. Βασίζονται στην κατανόηση της σειράς και του πλαισίου των λέξεων - εργασίες στις οποίες οι παραδοσιακές μέθοδοι κωδικοποίησης θέσης έχουν δείξει τα όριά τους. Αντιμετωπίζοντας αυτό το κενό, το μοντέλο ROFORMER, που υποστηρίζεται από την Ενσωμάτωση περιστροφικής θέσης (RoPE), επαναπροσδιορίζει την προσέγγισή μας στην κωδικοποίηση θέσης.
Παραδοσιακή κωδικοποίηση θέσης
Οι μετασχηματιστές αντιμετωπίζουν το κείμενο ως μια σειρά από διακριτικά και επιτρέπουν παράλληλη επεξεργασία ακολουθιών για μεγαλύτερη αποτελεσματικότητα. Ωστόσο, αυτή η δύναμη έφερε την πρόκληση: ο εγγενής αγνωστικισμός του μοντέλου σε συμβολική τάξη. Η κωδικοποίηση θέσης ήταν η απάντηση, παρέχοντας σε κάθε διακριτικό μια μοναδική υπογραφή που υποδηλώνει τη θέση της ακολουθίας.
Ενσωματώσεις απόλυτης θέσης
Αρχικά, μοντέλα όπως το BERT χρησιμοποιούσαν ενσωματώσεις απόλυτης θέσης, εκχωρώντας ένα σταθερό διάνυσμα σε κάθε θέση σε μια ακολουθία. Αυτή η μέθοδος, αν και απλή, εγγενώς στερείται της ικανότητας προσαρμογής σε παραλλαγές μήκους ακολουθίας ή να δίνει έμφαση στις σχετικές αποστάσεις μεταξύ των διακριτικών, κρίσιμες για την κατανόηση πολλών γλωσσικών κατασκευών.
Ενσωματώσεις σχετικής θέσης
Για να αποτυπωθεί η δυναμική φύση της γλώσσας, εισήχθησαν ενσωματώσεις σχετικής θέσης, εστιάζοντας στην απόσταση μεταξύ των διακριτικών και όχι στις απόλυτες θέσεις τους. Παρά το εννοιολογικό τους πλεονέκτημα, αυτές οι ενσωματώσεις εισήγαγαν υπολογιστική πολυπλοκότητα και απέτυχαν να ενσωματωθούν απρόσκοπτα στον μηχανισμό αυτοπροσοχής των Transformers, περιορίζοντας την αποτελεσματικότητά τους.
ROFORMER και Ενσωμάτωση περιστροφικής θέσης
Αναγνωρίζοντας τους περιορισμούς των υφιστάμενων στρατηγικών κωδικοποίησης θέσης, η ROFORMER εισάγει το Rotary Position Embedding (RoPE), μια προσέγγιση που συνδυάζει τα πλεονεκτήματα των πληροφοριών απόλυτης και σχετικής θέσης χωρίς τα αντίστοιχα μειονεκτήματά τους.
Ενσωμάτωση περιστροφικής θέσης
Το RoPE κωδικοποιεί πληροφορίες θέσης χρησιμοποιώντας πίνακες περιστροφής, επιτρέποντας στο μοντέλο να κατανοήσει όχι μόνο πού βρίσκεται ένα διακριτικό, αλλά και πώς σχετίζεται με κάθε άλλο διακριτικό σε μια ακολουθία.
Credit: Original Paper
Λειτουργεί μέσω ενός γεωμετρικού φακού, αντιμετωπίζοντας τις συμβολικές θέσεις ως σημεία σε έναν πολυδιάστατο χώρο που περιστρέφονται για να επισημάνουν τις διαδοχικές σχέσεις τους. Αυτή η περιστροφή επιτρέπει στο μοντέλο να διατηρεί και να εκμεταλλεύεται τόσο απόλυτες όσο και σχετικές ενδείξεις θέσης εντός του μηχανισμού αυτοπροσοχής του.
Εφαρμογή RoPE
Η εφαρμογή RoPE περιλαμβάνει την κωδικοποίηση της θέσης κάθε διακριτικού σε μια μήτρα περιστροφής και την εφαρμογή αυτής της μήτρας εντός του μηχανισμού αυτοπροσοχής του Μετασχηματιστή. Αυτή η διαδικασία επιτρέπει μια ευέλικτη, δυναμική ερμηνεία των πληροφοριών θέσης, που εξυπηρετεί ποικίλα μήκη ακολουθίας και συλλαμβάνει την ουσία των αλληλεπιδράσεων διακριτικών χωρίς σημαντική υπολογιστική επιβάρυνση.
Πρώτα, θα χρειαστείτε μια συνάρτηση για τη δημιουργία των περιστροφικών ενσωματώσεων και, στη συνέχεια, θα ενσωματώσετε αυτές τις ενσωματώσεις στο μοντέλο σας. Το παρακάτω παράδειγμα υποθέτει ότι είστε εξοικειωμένοι με τη δημιουργία προσαρμοσμένων επιπέδων στο Keras.
Βήμα 1: Ορίστε τη λειτουργία περιστροφικής ενσωμάτωσης
Αυτή η συνάρτηση δημιουργεί τις περιστροφικές ενσωματώσεις δεδομένου του μέγιστου μήκους ακολουθίας και της διάστασης των ενσωματώσεων.
from tensorflow.keras.layers import Layer
import numpy as np
def get_rotary_embedding(dim, max_seq_len):
inv_freq = 1.0 / (10000 ** (tf.range(0, dim, 2, dtype=tf.float32) / dim))
t = tf.range(max_seq_len, dtype=tf.float32)
freqs = tf.einsum('i,j->ij', t, inv_freq)
emb = tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)
return emb
inv_freq = 1.0 / (10000 ** (tf.range(0, dim, 2, dtype=tf.float32) / dim))
Αυτή η γραμμή υπολογίζει το αντίστροφο των εκθετικά κλιμακούμενων συχνοτήτων με βάση τους δείκτες θέσης. Αυτές οι συχνότητες χρησιμοποιούνται για τη δημιουργία ημιτονοειδών μοτίβων για περιστροφικές ενσωματώσεις, κάτι που βοηθά στην κωδικοποίηση των σχετικών πληροφοριών θέσης σε ακολουθίες. Αυτός ο μηχανισμός είναι ιδιαίτερα χρήσιμος σε εργασίες όπου η κατανόηση της σειράς και της σχετικής τοποθέτησης των στοιχείων είναι ζωτικής σημασίας, όπως στην επεξεργασία φυσικής γλώσσας ή στην ανάλυση χρονοσειρών.
Λεπτομερώς:
-
Το
tf.range(0, dim, 2, dtype=tf.float32)
δημιουργεί ένα εύρος τιμών που ξεκινούν από το 0 έως τοdim
(αποκλειστικά), με βήμα 2. Το όρισμαdtype=tf.float32
καθορίζει ότι τα στοιχεία αυτού του τανυστή είναι αριθμοί κινητής υποδιαστολής 32 bit. Εάν, για παράδειγμα, το "dim" είναι 8, αυτό θα παράγει "[0, 2, 4, 6]". -
Ο τανυστής που παράγεται από το
tf.range
διαιρείται στη συνέχεια με τη διάσταση (dim
) των ενσωματώσεων. Αυτή η λειτουργία κλιμακώνει αυτούς τους δείκτες σε ένα εύρος μεταξύ 0 και 1 (αποκλειστικά εάν το "dim" είναι άρτιο, ελαφρώς περιλαμβάνοντας εάν το "dim" είναι περιττό, επειδή το βήμα εύρους παρακάμπτει κάθε άλλη τιμή). Συνεχίζοντας το παράδειγμα με «dim» = 8, διαιρώντας με το 8 αποδίδει «[0.0, 0.25, 0.5, 0.75]». -
Η λειτουργία
10000 ** (...)
αυξάνει 10.000 στην ισχύ κάθε στοιχείου στον προηγουμένως κλιμακούμενο τανυστή. Η βάση των 10.000 είναι κάπως αυθαίρετη, αλλά επιλέγεται για να διασφαλίσει ότι οι συχνότητες ποικίλλουν σε ένα ευρύ φάσμα, γεγονός που βοηθά το μοντέλο να διαφοροποιεί τις διαφορετικές θέσεις πιο αποτελεσματικά. Για «[0.0, 0.25, 0.5, 0.75]», θα εφαρμόσει τη λειτουργία ισχύος σε καθένα, με αποτέλεσμα τιμές πολύ μεγαλύτερες για υψηλότερα στοιχεία. -
Τέλος, η αντίστροφη συχνότητα προκύπτει λαμβάνοντας το αντίστροφο (1/x) των τιμών από το προηγούμενο βήμα. Οι αντίστροφες συχνότητες είναι μικρότερες για υψηλότερους δείκτες, που σημαίνει ότι τα στοιχεία περαιτέρω στην ακολουθία θα έχουν μικρότερες συχνότητες, επηρεάζοντας τον τρόπο με τον οποίο οι θέσεις τους κωδικοποιούνται στο μοντέλο. Αυτό επιτρέπει στις ενσωματώσεις να κλιμακώνονται με τρόπο όπου οι σχετικές θέσεις μπορούν να συναχθούν μέσω των μηχανισμών προσοχής του μοντέλου.
Η γραμμή:
freqs = tf.einsum('i,j->ij', t, inv_freq)
χρησιμοποιεί τη συνάρτηση «tf.einsum» του TensorFlow, ένα εργαλείο που επιτρέπει τη συνοπτική και αποτελεσματική έκφραση των πράξεων τανυστή χρησιμοποιώντας τον συμβολισμό άθροισης Αϊνστάιν.
Αυτή η πράξη υπολογίζει αποτελεσματικά το εξωτερικό γινόμενο των διανυσμάτων «t» και «inv_freq», καταλήγοντας σε έναν πίνακα όπου κάθε στοιχείο «(i, j)» είναι το γινόμενο του «i»-ου στοιχείου του «t» και του « j-ο στοιχείο του
inv_freq`. Αυτός ο πίνακας («συχνότητες») αντιπροσωπεύει τις συχνότητες που χρησιμοποιούνται για τη δημιουργία των ημιτονοειδών μοτίβων για τις περιστροφικές ενσωματώσεις.
Βήμα 2: Προσαρμοσμένο στρώμα Keras για περιστροφικές ενσωματώσεις
Τώρα, ας δημιουργήσουμε ένα προσαρμοσμένο επίπεδο Keras που εφαρμόζει περιστροφικές ενσωματώσεις στον τανυστή εισόδου. Αυτό το επίπεδο προϋποθέτει ότι ο τανυστής εισόδου έχει σχήμα «(μέγεθος_παρτίδας, μήκος_ακολουθίας, ενσωμάτωση_μείωσης)".
class RotaryEmbeddingLayer(Layer):
def __init__(self, dim, max_seq_len, **kwargs):
super().__init__(**kwargs)
self.dim = dim
self.max_seq_len = max_seq_len
self.rotary_embeddings = get_rotary_embedding(dim, max_seq_len)
def call(self, inputs):
seq_len = tf.shape(inputs)[1]
embeddings = self.rotary_embeddings[:seq_len]
cos_emb = embeddings[:, None, :self.dim // 2]
sin_emb = embeddings[:, None, self.dim // 2:]
# Decompose inputs into sine and cosine components
inputs_cos = inputs[..., :self.dim // 2]
inputs_sin = inputs[..., self.dim // 2:]
# Apply rotary embeddings
rotated_cos = inputs_cos * cos_emb - inputs_sin * sin_emb
rotated_sin = inputs_sin * cos_emb + inputs_cos * sin_emb
return tf.concat([rotated_cos, rotated_sin], axis=-1)
def get_config(self):
config = super().get_config()
config.update({
"dim": self.dim,
"max_seq_len": self.max_seq_len
})
return config
Η γραμμή embeddings = self.rotary_embeddings[:seq_len]
επιλέγει το κατάλληλο υποσύνολο προ-υπολογισμένων περιστροφικών ενσωματώσεων με βάση το τρέχον μήκος ακολουθίας εισόδου. Δεδομένου ότι το μήκος των αλληλουχιών μπορεί να ποικίλλει από τη μια παρτίδα στην άλλη, αυτή η λειτουργία τεμαχισμού διασφαλίζει ότι χρησιμοποιούνται μόνο οι ενσωματώσεις που αντιστοιχούν στο πραγματικό μήκος της ακολουθίας.
Η μεταβλητή "embeddings" έχει τώρα έναν τανυστή σχήματος "(seq_len, embedding_dim)", όπου "seq_len" είναι το μήκος των ακολουθιών στην τρέχουσα παρτίδα και "embedding_dim" είναι η διάσταση των ενσωματώσεων. Αυτός ο τανυστής περιέχει τις περιστροφικές ενσωματώσεις θέσης για κάθε θέση στην ακολουθία μέχρι το seq_len
.
Το emb = tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)
συνδυάζει μετασχηματισμούς ημιτονοειδούς και συνημιτόνου των συχνοτήτων θέσης σε έναν απλό τανυστή:
-«tf.cos(freqs)» και «tf.sin(freqs)» εφαρμόζουν τους μετασχηματισμούς συνημιτόνου και ημιτόνου, αντίστοιχα, στον τανυστή «freqs». Ο τανυστής «συχνοτήτων» περιέχει τιμές συχνότητας για κάθε θέση στην ακολουθία εισόδου και κάθε διάσταση του χώρου ενσωμάτωσης, που υπολογίζονται με βάση τις θέσεις της ακολουθίας και τις αντίστροφες συχνότητες των διαστάσεων ενσωμάτωσης. Οι συναρτήσεις ημιτονοειδούς και συνημιτόνου εφαρμόζονται βάσει στοιχείων, με αποτέλεσμα δύο τανυστές του ίδιου σχήματος με τις «συχνότητες». Αυτοί οι μετασχηματισμοί βοηθούν στην κωδικοποίηση της θέσης με τρόπο που αποτυπώνει την κυκλική φύση των σχέσεων θέσης, διευκολύνοντας την ικανότητα του μοντέλου να κατανοεί τις σχετικές θέσεις.
-tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)
συνενώνει τους τανυστές συνημιτόνου και ημιτονοειδούς μετασχηματισμένους κατά μήκος του τελευταίου άξονα (σημειώνεται με άξονας=-1
). Η συνένωση αυτών των τανυστών δίπλα-δίπλα διπλασιάζει αποτελεσματικά τη διάσταση του τανυστή «συχνοτήτων», με το πρώτο μισό να αντιπροσωπεύει τιμές μετασχηματισμένες με συνημιτονικό και το δεύτερο μισό να αντιπροσωπεύει τιμές μετασχηματισμένου ημιτονοειδούς για κάθε θέση. Η συνένωση διασφαλίζει ότι κάθε κωδικοποίηση θέσης περιέχει πληροφορίες τόσο ημιτονοειδούς όσο και συνημιτονοειδούς, γεγονός που επιτρέπει τη διατήρηση πληροφοριών τόσο για το πλάτος όσο και για τη φάση των σημάτων θέσης.
-Το συνενωμένο τανυστή «emb» κρατά τώρα τις πλήρεις περιστροφικές ενσωματώσεις για τις θέσεις εισόδου. Το σχήμα του "emb" θα είναι το ίδιο με το "freqs" στις δύο πρώτες του διαστάσεις (που αντιστοιχούν σε θέσεις ακολουθίας και διαστάσεις ενσωμάτωσης), αλλά η τελευταία του διάσταση θα είναι διπλάσια, λαμβάνοντας υπόψη τις τιμές τόσο του ημιτονοειδούς όσο και του συνημιτονοειδούς. Αυτές οι ενσωματώσεις χρησιμοποιούνται για τη διαμόρφωση των ενσωματώσεων εισόδου προσθέτοντας πληροφορίες θέσης με περιστροφικά ισοδύναμο τρόπο.
-cos_emb = ενσωματώσεις[:, Καμία, :self.dim // 2]
:
-
Η πρώτη άνω και κάτω τελεία
:
σημαίνει "επιλογή όλων των στοιχείων σε αυτήν τη διάσταση", η οποία, σε αυτήν την περίπτωση, αναφέρεται σε όλες τις θέσεις της ακολουθίας. -
Το «Καμία» χρησιμοποιείται για την προσθήκη μιας πρόσθετης διάστασης, καθιστώντας τον τανυστή τρισδιάστατο. Αυτό γίνεται συχνά για να διασφαλιστεί η συμβατότητα με ορισμένες λειτουργίες που αναμένουν εισόδους συγκεκριμένου αριθμού διαστάσεων. Για παράδειγμα, όταν εκτελείτε πολλαπλασιασμό βάσει στοιχείων με έναν άλλο τανυστή που είναι τρισδιάστατος, τα σχήματα πρέπει να ευθυγραμμίζονται σύμφωνα με τους κανόνες μετάδοσης.
-
:self.dim // 2
, επιλέγει το πρώτο μισό των διαστάσεων στον τελευταίο άξονα. Δεδομένου ότι ηενσωμάτωση_διάστασης
διπλασιάζεται για να περιλαμβάνει τιμές ημιτονοειδούς και συνημιτονοειδούς, η διαίρεση με το 2 επιλέγει αποτελεσματικά μόνο τα στοιχεία συνημιτόνου των ενσωματώσεων.
Βήμα 3: Ενοποίηση με ένα μοντέλο Keras
Αφού ορίσετε το «RotaryEmbeddingLayer», μπορείτε να το ενσωματώσετε στο μοντέλο Keras. Αυτό το στρώμα θα πρέπει να εφαρμοστεί στις ενσωματώσεις σας προτού τις τροφοδοτήσετε σε στρώματα προσοχής ή σε οποιαδήποτε επόμενα στρώματα μοντέλου.
Ακολουθεί ένα απλοποιημένο παράδειγμα του τρόπου ενσωμάτωσης των περιστροφικών ενσωματώσεων σε ένα μοντέλο:
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Embedding, Dense
max_seq_len = 512
embedding_dim = 64
inp = Input(shape=(max_seq_len,))
x = Embedding(input_dim=10000, output_dim=embedding_dim)(inp)
x = RotaryEmbeddingLayer(dim=embedding_dim, max_seq_len=max_seq_len)(x)
# Add your model's layers here, e.g., Transformer blocks
x = Dense(1, activation='sigmoid')(x)
model = Model(inputs=inp, outputs=x)
model.summary()