Fəsil 02 · 8 dəq oxu

Representation-lar və embedding-lər

Representation-lar və embedding-lər

Əvvəlki fəsildə necə öyrəndiyini gördük: loss-u azaltmaq üçün parametrləri dəyişir. Bəs network əslində nəyi öyrənir? Cavab budur: representation-ları. Hər layer girişi yeni ədədlər toplusuna çevirir. Training irəlilədikcə bu ədədlər tapşırıq üçün vacib olanı saxlayır, qalanını isə atır. Bu fəsil həmin daxili ədədlərin, xüsusən də -lərin necə qurulduğunu və necə istifadə olunduğunu izah edir. Bu mövzu kitabın sonrakı hissələrinin demək olar hamısının təməlidir: kimi görür, retrieval sistemləri axtarır, multimodal model-lər isə şəkli və mətni eyni fəzasında görüşdürür.

Representation nədir

Pişik şəkillərini tanıyan götürək. Giriş xam piksel dəyərləridir, çıxış isə "pişik" və ya "it" ehtimalıdır. Aralıq layer-lərdə nə baş verir? Erkən layer-lər kənarları və rəng keçidlərini, ortadakılar tük, göz, qulaq kimi hissələri tutur. Son layer-lər isə "pişikliyi" kodlaşdıran abstrakt xüsusiyyətlərə çatır. Bu xüsusiyyətləri heç kim əl ilə təyin etməyib. Loss-u azaltmağın ən yaxşı yolu belə olduğu üçün onlar özləri meydana çıxıb.

Bunun iki mühüm nəticəsi var:

  • Representation tapşırıqdan asılıdır. Model loss-un tələb etdiyini öyrənir. Pişik və iti ayırmağa öyrədilmiş model şəkildəki mətni oxumağı öyrənməyəcək, çünki buna ehtiyac yoxdur.
  • Yaxşı representation köçürülə bilir. Milyonlarla şəkil üzərində öyrənilmiş xüsusiyyətlər yeni, kiçik tapşırıq üçün də faydalıdır. Transfer learning və bütövlükdə ideyası buna əsaslanır: model bir dəfə geniş data üzərində ümumi representation öyrənir, sonra onu konkret tapşırığa uyğunlaşdırırıq.

Embedding: diskret şeyləri vektora çevirmək

Şəkil artıq ədədlərdən ibarətdir. Söz, istifadəçi və ya məhsul id-si isə ədəd deyil. Onları necə network-ə vermək olar? Ən sadə yol one-hot vektordur: 50 000 sözlük lüğətdə hər söz 50 000 ölçülü vektordur, yalnız bir mövqedə 1, qalanlarda 0. Bu təmsil həm israfçıdır, həm də heç nə ifadə etmir: "pişik" və "it" arasındakı məsafə "pişik" və "demokratiya" arasındakı məsafə ilə eynidir.

hər diskret elementə öyrənilən sıx vektor verir, adətən bir neçə yüz və ya bir neçə min ölçülü. Texniki olaraq bu sadəcə cədvəldir: [lüğət_ölçüsü, embedding_ölçüsü] shape-li matris. Hər sətir bir elementin vektorudur.

emb = torch.nn.Embedding(num_embeddings=50_000, embedding_dim=768)
vectors = emb(torch.tensor([17, 4021, 9]))   # shape: [3, 768]

Bu matris digər kimi ilə öyrənilir. Başlanğıcda vektorlar təsadüfidir. Training-dən sonra isə oxşar rolda işlənən elementlərin vektorları bir-birinə yaxın olur. Heç kim model-ə "pişik və it oxşardır" deməyib. Oxşar context-lərdə işləndikləri üçün loss-u azaltmağın ən asan yolu onlara oxşar vektorlar verməkdir.

Oxşarlığı ölçmək

fəzasında "yaxın" nə deməkdir? Üç ölçü geniş yayılıb:

dot(a, b)     = Σ aᵢ · bᵢ
cosine(a, b)  = dot(a, b) / (‖a‖ · ‖b‖)
L2(a, b)      = √ Σ (aᵢ − bᵢ)²
  • Dot product həm istiqaməti, həm də uzunluğu nəzərə alır. Uzun vektor-lar daha böyük bal alır.
  • Cosine similarity yalnız istiqamətə baxır. Nəticə −1 ilə 1 arasındadır. Mətn üçün ən çox istifadə olunan ölçü budur.
  • L2 məsafəsi fəzadakı düz xətt məsafəsidir. Kiçik dəyər daha oxşar deməkdir.

Vektor-lar normalize olunubsa, yəni hər birinin uzunluğu 1-dirsə, üç ölçü eyni sıralamanı verir: cosine dot product-a bərabər olur, L2 isə cosine ilə monoton bağlıdır (L2² = 2 − 2·cosine). Buna görə praktikada çox vaxt normalize edilir və sürətli dot product istifadə olunur. Bir qayda vacibdir: model hansı ölçü ilə train olunubsa, axtarışda da onu istifadə edin. Model-in sənədləşməsi adətən bunu açıq göstərir.

word2vec: context-dən məna

gücünü geniş auditoriyaya 2013-cü ildə word2vec göstərdi. İdeya köhnə bir linqvistik müşahidəyə əsaslanır: sözün mənasını onun qonşuları müəyyən edir. word2vec sadə tapşırıqla öyrədilir: sözə baxıb ətrafındakı sözləri proqnozlaşdır, ya da əksinə. Bu tapşırığı yaxşı yerinə yetirmək üçün model oxşar context-lərdə işlənən sözlərə oxşar vektorlar verməli olur.

Nəticə gözlənilməz dərəcədə strukturlu çıxdı. fəzasındakı istiqamətlər məna daşıyırdı. Məşhur nümunə budur:

vec("king") − vec("man") + vec("woman") ≈ vec("queen")

Fəzada "cins" istiqaməti, "paytaxt" istiqaməti, "keçmiş zaman" istiqaməti yaranmışdı. Bu nümunə bir qədər şişirdilib və hər zaman bu qədər təmiz işləmir. Amma əsas ideya bu gün də doğrudur: fəzası mənanı həndəsəyə çevirir.

word2vec-in ciddi məhdudiyyəti var: hər sözə bir vektor verir. "Bank" sözü həm maliyyə qurumu, həm də çay sahili ola bilər, amma vektoru eynidir.

Contextual embedding-lər

Həll contextual -lərdir: sözün vektoru ətrafındakı mətndən asılı olaraq hesablanır. Bunu edir, onu növbəti fəsildə ətraflı görəcəyik. Proses belədir: hər əvvəlcə statik cədvəlindən vektor alır, sonra bu vektor layer-dən layer-ə ötürülərək context-dəki digər məlumatı ilə zənginləşir. Son layer-də "bank" vektoru "kredit" sözünün yanında bir yerə, "çayın sahili" ifadəsinin yanında isə tamam başqa yerə düşür.

Bu, baxışı dəyişir. artıq lüğətdəki sabit giriş deyil, model-in konkret mətni necə başa düşdüyünün anlıq görüntüsüdür.

Contrastive learning: oxşarlığı birbaşa öyrətmək

daxili vektor-ları zəngindir, amma onları birbaşa axtarış üçün istifadə etmək çox vaxt zəif nəticə verir. Səbəb odur ki, model növbəti proqnozlaşdırmaq üçün öyrədilib, "bu iki mətn eyni şeydən danışırmı?" sualına cavab vermək üçün yox. Representation tapşırıqdan asılıdır. Oxşarlıq istəyiriksə, oxşarlığı öyrətməliyik.

Contrastive learning bunu edir. Data cüt-lərdən ibarətdir: sual və onun cavabı, başlıq və mətn, eyni şəklin iki fərqli kəsiyi. Hər cüt bir positive-dir. Məqsəd positive cütün bir-birinə yaxınlaşdırmaq, əlaqəsiz nümunələrin (negative-lərin) isə uzaqlaşdırmaqdır.

Ən geniş yayılmış loss InfoNCE-dir. O, tanış bir şeyə bənzəyir: əslində . Hər sual üçün bütün namizəd cavablarla oxşarlıq hesablanır. Bu oxşarlıqlar logit rolunu oynayır, düzgün cavab isə "düzgün class"-dır:

logits[i][j] = cosine(q_i, d_j) / τ
loss = cross_entropy(logits, labels = [0, 1, 2, ..., B−1])

τ -dir. O, paylanmanın nə qədər kəskin olacağını idarə edir və adətən 0.01–0.1 arasında seçilir.

Negative-ləri haradan almalı? Ən zərif həll in-batch negatives-dir: B cütlük batch-da hər sual üçün öz cavabı positive, qalan B−1 cavab isə negative sayılır. Negative-lər pulsuz əldə olunur və batch böyüdükcə tapşırıq çətinləşir. Contrastive model-lərin çox böyük batch-larla train olunmasının səbəbi budur. Keyfiyyəti daha da artırmaq üçün hard negative-lər əlavə olunur: düzgün cavaba bənzəyən, amma əslində səhv olan nümunələr. Məsələn, eyni mövzuda olan, amma suala cavab verməyən sənəd. Model ən çox məhz bu ayrımı öyrənməkdən faydalanır.

Mətn embedding model-ləri

Praktikada bu ideyalar text model-lərində birləşir. Bunlar mətn parçasını qəbul edib bir vektor qaytaran model-lərdir. Tipik resept belədir: encoder və ya kiçik götürülür, vektor-ları bir vektora yığılır (pooling: ortalama və ya xüsusi vektoru), sonra model milyonlarla mətn cütü üzərində contrastive loss ilə train edilir.

Model seçərkən bir neçə şeyə baxın:

  • Domain və dil. Ümumi veb mətni üzərində train olunmuş model hüquq və ya tibb terminologiyasında, eləcə də az resurslu dillərdə zəif işləyə bilər. Bunu yalnız öz data-nız üzərində ölçməklə bilmək olar.
  • Asimmetrik tapşırıqlar. Qısa sual və uzun sənəd eyni növ mətn deyil. Bir çox model sual və sənəd üçün fərqli prefix və ya instruction tələb edir. Onları buraxsanız, keyfiyyət hiss olunacaq qədər düşür.
  • Maksimal uzunluq. Limitdən uzun mətn kəsilir və kəsilən hissə düşmür.
  • Ölçü və qiymət. Daha böyük vektor daha çox yaddaş və daha yavaş axtarış deməkdir.

Public leaderboard-lar (məsələn, MTEB) yaxşı başlanğıc nöqtəsidir, amma son qərar öz data-nız üzərində kiçik evaluation-a əsaslanmalıdır.

Ortaq multimodal fəzalar

Contrastive learning yalnız mətnlə məhdudlaşmır. CLIP (2021) internetdən toplanmış yüz milyonlarla şəkil–başlıq cütü üzərində iki encoder-i birlikdə train etdi: biri şəkil üçün, biri mətn üçün. Hər iki encoder vektor-larını eyni fəzaya yazır. Şəkil və onun başlığı yaxın, əlaqəsizlər isə uzaq düşür.

Nəticədə "qarda oynayan it" mətninin vektoru ilə həmin səhnəni göstərən şəklin vektoru yaxın olur. Bu, mətnlə şəkil axtarmağa, heç bir əlavə training olmadan şəkilləri classify etməyə (class adlarını mətn kimi embed edib ən yaxınını seçməklə) və generative model-lərə mətnlə istiqamət verməyə imkan yaradır. Sonrakı hissələrdə vision-language model-lər və generasiyaya nəzarət mövzusunda bu ideyaya qayıdacağıq. Fərqli modallıqları ortaq fəzada görüşdürmək model-ə dünyanı "anlamaq" qabiliyyəti verməyin əsas yollarından biridir.

Ölçü, normalization və praktik qeydlər

ölçüsü tutumla qiymət arasında balansdır. 384 ölçülü vektor ucuz və sürətlidir. 3072 ölçülü vektor daha incə fərqləri tuta bilər, amma hər vektor 8 dəfə çox yer tutur. On milyonlarla sənəddə bu fərq gigabaytlarla ölçülür.

Bəzi müasir model-lər Matryoshka representation learning ilə train olunur. Bu halda vektorun əvvəlki hissəsi ən vacib məlumatı daşıyır və vektoru kəsib, məsələn, 3072 ölçünün yalnız ilk 256-sını saxlamaq mümkündür. Keyfiyyət bir az düşür, qənaət isə böyük olur. Başqa bir yol quantization-dır: float32 əvəzinə int8 və ya hətta tək bit saxlamaq. Bunu fəslində daha ətraflı görəcəyik.

Bir neçə praktik qayda:

  • Fərqli model-lərin vektor-larını heç vaxt müqayisə etməyin. Hər model-in öz fəzası var və onlar uyğun gəlmir. Model-i dəyişsəniz, bütün kolleksiyanı yenidən embed etməlisiniz.
  • Normalization-ı bir yerdə və ardıcıl edin: ya hər vektoru saxlamazdan əvvəl, ya da heç vaxt.
  • Cosine similarity-nin mütləq dəyərinə çox etibar etməyin. 0.8 bir model-də "çox oxşar", digərində "orta" ola bilər. Sıralama mütləq dəyərdən daha etibarlıdır.

Növbəti addımlar üçün təməl

Bu fəsildə qurulan ideyalar kitab boyu dəfələrlə qayıdacaq. Növbəti fəsildə contextual representation-lara necə çevirdiyini görəcəyik. Retrieval hissəsində isə contrastive yolla öyrədilmiş sənəd axtarışının mərkəzinə keçəcək: sual vektoru ilə sənəd vektor-ları arasındakı oxşarlıq sistemlərinin əsasını təşkil edir. Orada indi gördüyümüz suallar praktik problemə çevriləcək: hansı model, hansı ölçü, hansı oxşarlıq ölçüsü və öz domain-iniz üçün bunu necə ölçmək.

Tapşırıqlar

  1. Açıq text model-i ilə 20 cümlə embed edin: 4 mövzunun hər birindən 5 cümlə. Cosine similarity matrisini hesablayıb heatmap kimi çəkin. Mövzular blok-lar şəklində görünürmü? Ən çaşdırıcı cütü tapıb səbəbini izah edin.
  2. Eyni vektor-lar üzərində dot product, cosine və L2 ilə ən yaxın qonşuları tapın. Əvvəlcə normalize etmədən, sonra normalize edərək. Sıralamaların harada fərqləndiyini və normalization-dan sonra niyə üst-üstə düşdüyünü göstərin.
  3. Kiçik sual–cavab dataset-i üzərində in-batch negatives ilə InfoNCE loss-u yazın (cross_entropy və oxşarlıq matrisi kifayətdir). Batch size-ı 8, 32 və 128 edərək training-dən sonra retrieval accuracy-ni müqayisə edin. Hər hal üçün 0.05 və 0.5 götürüb nəticəni şərh edin.