RoFormer: Döner Pozisyon Gömmeli Gelişmiş Transformatör

RoFormer: Döner Pozisyon Gömmeli Gelişmiş Transformatör

Transformer tabanlı modeller, karmaşık metinleri ayrıştırma ve yorumlama yetenekleriyle ünlüdür. Geleneksel konumsal kodlama yöntemlerinin sınırlarını gösterdiği görevler olan kelimelerin sırasını ve bağlamını anlamaya dayanırlar. Bu boşluğa hitap eden, Döner Konum Gömme (RoPE) tarafından desteklenen ROFORMER modeli, konumsal kodlamaya yaklaşımımızı yeniden tanımlıyor.

Geleneksel Konumsal Kodlama

Transformatörler, metni bir dizi simge olarak ele alır ve daha fazla verimlilik için dizilerin paralel işlenmesine olanak tanır. Ancak bu güç, kendi zorluklarını da beraberinde getirdi: modelin sembolik düzene içkin agnostisizmi. Yanıt Konumsal kodlamaydı; her jetona sıra konumunu belirten benzersiz bir imza sağlıyordu.

Mutlak Konum Gömmeleri

Başlangıçta, BERT gibi modeller mutlak konum yerleştirmeleri, bir dizideki her konuma sabit bir vektör atayarak kullanıyordu. Bu yöntem, basit olmasına rağmen, doğası gereği dizi uzunluğu değişikliklerine uyum sağlama veya belirteçler arasındaki göreli mesafeleri vurgulama yeteneğinden yoksundur, bu da pek çok dilsel yapıyı anlamak için kritik öneme sahiptir.

Göreceli Konum Yerleştirmeleri

Dilin dinamik doğasını yakalamak için, belirteçlerin mutlak konumları yerine aralarındaki mesafeye odaklanan göreceli konum yerleştirmeleri tanıtıldı. Kavramsal avantajlarına rağmen, bu yerleştirmeler hesaplama karmaşıklığı getirdi ve Transformers'ın öz-dikkat mekanizmasına sorunsuz bir şekilde entegre olmayı başaramadı ve bu da onların etkinliğini sınırladı.

ROFORMER ve Döner Pozisyon Gömme

Mevcut konumsal kodlama stratejilerinin sınırlamalarının farkında olan ROFORMER, mutlak ve göreceli konum bilgilerinin faydalarını ilgili dezavantajları olmadan birleştiren bir yaklaşım olan Döner Konum Gömmeyi (RoPE) sunar.

Döner Pozisyon Gömme

RoPE, konum bilgisini dönme matrislerini kullanarak kodlayarak modelin yalnızca bir tokenın nerede olduğunu değil aynı zamanda bir dizideki diğer tokenlarla nasıl ilişkili olduğunu anlamasını sağlar.

Reformer.pngCredit: ArXiv

Jeton konumlarını, sıralı ilişkilerini işaretlemek için döndürülen çok boyutlu bir uzaydaki noktalar olarak ele alan geometrik bir mercek aracılığıyla çalışır. Bu rotasyon, modelin kendi kendine dikkat mekanizması içerisinde hem mutlak hem de göreceli konumsal ipuçlarını korumasına ve kullanmasına olanak tanır.

RoPE'nin Uygulanması

RoPE'nin uygulanması, her jetonun konumunun bir rotasyon matrisine kodlanmasını ve bu matrisin Transformer'ın öz-dikkat mekanizması içinde uygulanmasını içerir. Bu süreç, konumsal bilgilerin esnek, dinamik bir şekilde yorumlanmasına, değişen dizi uzunluklarına uyum sağlanmasına ve önemli bir hesaplama yükü olmadan belirteç ilişkilerinin özünün yakalanmasına olanak tanır.

Öncelikle döner yerleştirmeleri oluşturmak için bir fonksiyona ihtiyacınız olacak, ardından bu yerleştirmeleri modelinize entegre edeceksiniz. Aşağıdaki örnekte Keras'ta özel katmanlar oluşturmaya aşina olduğunuz varsayılmaktadır.

Adım 1: Döner Gömme İşlevini Tanımlayın

Bu işlev, maksimum dizi uzunluğu ve yerleştirmelerin boyutluluğu göz önüne alındığında döner yerleştirmeleri oluşturur.

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))

Bu çizgi, konum endekslerine dayalı olarak üstel olarak ölçeklendirilmiş frekansların tersini hesaplar. Bu frekanslar, döner yerleştirmeler için sinüzoidal desenlerin oluşturulmasında kullanılır ve bu, dizilerdeki göreceli konum bilgilerinin kodlanmasına yardımcı olur. Bu mekanizma, doğal dil işleme veya zaman serisi analizi gibi öğelerin sırasını ve göreceli konumunu anlamanın çok önemli olduğu görevlerde özellikle faydalıdır.

Ayrıntılı olarak:

  • tf.range(0, dim, 2, dtype=tf.float32), 0'dan başlayarak `dim'e (hariç) kadar, 2'şer adım adım ilerleyen bir değer aralığı oluşturur. 'dtype=tf.float32' bağımsız değişkeni şunu belirtir: bu tensörün elemanlarının 32 bitlik kayan noktalı sayılar olduğu. Örneğin "dim" 8 ise bu, "[0, 2, 4, 6]" sonucunu verir.

  • Daha sonra "tf.range" tarafından üretilen tensör, yerleştirmelerin boyutluluğuna ("dim") bölünür. Bu işlem, bu endeksleri 0 ile 1 arasındaki bir aralığa ölçeklendirir ("dim" çift ise hariçtir, "dim" tek ise biraz kapsayıcıdır, çünkü aralık adımı tüm diğer değerleri atlar). Örneğe "dim" = 8 ile devam edersek, 8'e bölmek "[0,0, 0,25, 0,5, 0,75]" sonucunu verir.

  • '10000 ** (...)' işlemi, daha önce ölçeklenen tensördeki her öğenin üssünü 10.000 artırır. 10.000 tabanı biraz keyfidir ancak frekansların geniş bir aralıkta değişmesini sağlamak için seçilmiştir, bu da modelin farklı konumlar arasında daha etkili bir şekilde ayrım yapmasına yardımcı olur. "[0.0, 0.25, 0.5, 0.75]" için, her birine güç işlemi uygulanır ve daha yüksek öğeler için çok daha büyük değerler elde edilir.

  • Son olarak bir önceki adımdaki değerlerin tersi (1/x) alınarak ters frekans elde edilir. Ters frekanslar daha yüksek endeksler için daha küçüktür; bu, dizideki daha ilerideki öğelerin daha küçük frekanslara sahip olacağı anlamına gelir ve bu da konumlarının modele nasıl kodlanacağını etkiler. Bu, yerleştirmelerin, modelin dikkat mekanizmaları aracılığıyla göreceli konumların çıkarılabileceği şekilde ölçeklendirilmesine olanak tanır.

Satır:

freqs = tf.einsum('i,j->ij', t, inv_freq)

TensorFlow'un, Einstein toplama gösterimini kullanarak tensör işlemlerinin kısa ve etkili bir şekilde ifade edilmesine olanak tanıyan bir araç olan "tf.einsum" fonksiyonunu kullanır.

Bu işlem, 't' ve 'inv_freq' vektörlerinin dış çarpımını etkili bir şekilde hesaplar ve sonuçta her bir öğenin '(i, j)', 't'nin 'i'inci öğesinin ve ''nin çarpımı olduğu bir matris elde edilir. 'inv_freq'in j'-th öğesi. Bu matris ("frekanslar"), döner gömmeler için sinüzoidal desenleri oluşturmak için kullanılan frekansları temsil eder.

Adım 2: Döner Gömmeler için Özel Keras Katmanı

Şimdi giriş tensörüne döner yerleştirmeler uygulayan özel bir Keras katmanı oluşturalım. Bu katman, giriş tensörünün '(toplu_boyut, sıra_uzunluğu, yerleştirme_dim)' şeklinde olduğunu varsayar.

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

'Embddings = self.rotary_embeddings[:seq_len]' satırı, geçerli giriş dizisi uzunluğuna dayalı olarak önceden hesaplanmış döner yerleştirmelerin uygun alt kümesini seçer. Dizilerin uzunluğu bir partiden diğerine değişebildiğinden, bu dilimleme işlemi yalnızca gerçek dizi uzunluğuna karşılık gelen yerleştirmelerin kullanılmasını sağlar.

"Gömmeler" değişkeni artık "(seq_len, embedding_dim)" şeklinde bir tensör barındırıyor; burada "seq_len" geçerli toplu işteki dizilerin uzunluğu ve "embedding_dim" yerleştirmelerin boyutluluğudur. Bu tensör, "seq_len"e kadar dizideki her konum için döner konumsal yerleştirmeleri içerir.

'emb = tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)' konumsal frekansların sinüs ve kosinüs dönüşümlerini tek bir tensörde birleştirir:

-tf.cos(freqs) ve tf.sin(freqs), kosinüs ve sinüs dönüşümlerini sırasıyla 'freqs' tensörüne uygular. "Frekanslar" tensörü, giriş dizisindeki her konum ve gömme alanının her boyutu için, dizi konumları ve gömme boyutlarının ters frekanslarına göre hesaplanan frekans değerlerini içerir. Sinüs ve kosinüs fonksiyonları eleman bazında uygulanarak "frekler" ile aynı şekle sahip iki tensör elde edilir. Bu dönüşümler, konumun konumsal ilişkilerin döngüsel doğasını yakalayacak şekilde kodlanmasına yardımcı olarak modelin göreceli konumları anlama yeteneğini kolaylaştırır.

-tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1) kosinüs ve sinüs dönüştürülmüş tensörleri son eksen boyunca ('axis=-1' ile gösterilir) birleştirir. Bu tensörlerin yan yana birleştirilmesi, "frekans" tensörünün boyutsallığını etkili bir şekilde iki katına çıkarır; ilk yarı, her konum için kosinüsle dönüştürülmüş değerleri ve ikinci yarı, sinüsle dönüştürülmüş değerleri temsil eder. Birleştirme, her konumsal kodlamanın hem sinüs hem de kosinüs bilgilerini içermesini sağlar; bu da konumsal sinyallerin hem genliği hem de fazı hakkındaki bilgilerin korunmasına olanak tanır.

  • Birleştirilmiş tensör 'yerleştirme' artık giriş konumları için tüm döner yerleştirmeleri barındırıyor. 'Göm'ün şekli, ilk iki boyutunda (sıra konumlarına ve gömme boyutlarına karşılık gelen) 'frekler' ile aynı olacaktır, ancak son boyutu, hem sinüs hem de kosinüs değerlerini hesaba katarak iki kat daha büyük olacaktır. Bu yerleştirmeler, konumsal bilgiyi rotasyonel olarak eşit bir şekilde ekleyerek giriş yerleştirmelerini modüle etmek için kullanılır.

-cos_emb = yerleştirmeler[:, Yok, :self.dim // 2]:

  1. İlk iki nokta üst üste : "bu boyuttaki tüm öğeleri seç" anlamına gelir; bu durumda bu, dizideki tüm konumları ifade eder.

  2. Tensörü 3 boyutlu hale getiren ek bir boyut eklemek için 'Yok' kullanılır. Bu genellikle belirli sayıda boyutta girdi bekleyen belirli işlemlerle uyumluluğu sağlamak için yapılır. Örneğin 3 boyutlu başka bir tensörle eleman bazında çarpma işlemi yapılırken şekillerin yayın kurallarına göre hizalanması gerekir.

  3. :self.dim // 2, son eksendeki boyutların ilk yarısını seçer. "Gömme_boyutu" hem sinüs hem de kosinüs değerlerini içerecek şekilde iki katına çıkarıldığından, 2'ye bölmek, yerleştirmelerin yalnızca kosinüs bileşenlerini etkili bir şekilde seçer.

Adım 3: Keras Modeli ile Entegrasyon

'RotaryEmbeddingLayer'ı tanımladıktan sonra Keras modelinize entegre edebilirsiniz. Bu katman, yerleştirmelerinize dikkat katmanlarına veya sonraki model katmanlarına beslenmeden önce uygulanmalıdır.

Döner yerleştirmelerin bir modele nasıl entegre edileceğine dair basitleştirilmiş bir örnek:

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()

Code Labs Academy © 2025 Her hakkı saklıdır.