Multimodala modeller — grunderna
Kunna förklara hur bild, text och ljud kan mötas i ett gemensamt vektorrum.
Förkunskaper
Intuition
Idén är enkel: träna två kodare så att de lägger ihörande saker på samma ställe.
En bildkodare gör om en bild till en vektor. En textkodare gör om en text till en vektor. Träna dem tillsammans på miljontals (bild, bildtext)-par med regeln: vektorn för en bild ska ligga nära vektorn för dess egen text och långt från alla andras.
När det är gjort kan du:
- söka bilder med text — koda frågan, hitta närmaste bildvektorer,
- klassificera utan träningsdata — koda «en bild av en katt», «en bild av en hund» och se vilken som ligger närmast,
- koppla ihop modaliteter som aldrig sågs tillsammans, om båda kopplats till text.
Samma recept fungerar för ljud och text (CLAP), video och text, och i princip vilka två strömmar som helst där det finns naturligt parade data.
Formellt
Kontrastiv förlust (InfoNCE). I en batch med par normaliseras alla vektorer till längd 1, och likhetsmatrisen blir . Förlusten är korsentropi åt båda hållen — rätt text för varje bild och rätt bild för varje text:
Temperaturen lärs in och hamnar typiskt runt 0,01. Batchstorleken är avgörande: de övriga paren är de negativa exemplen, så större batch ger hårdare och mer informativ träning. CLIP tränades med batchstorlek 32 768.
Tre begränsningar som är lätta att missa:
- Påsen-med-begrepp. Ett delat rum fångar vad som finns i bilden, inte hur det förhåller sig. «Hunden jagar katten» och «katten jagar hunden» hamnar nästan på samma ställe. Kompositionalitet är en känd svaghet.
- Ingen räkning. «Tre äpplen» och «fem äpplen» skiljer sig knappt.
- Ärvd skevhet. Rummet speglar webbdatan det tränades på, inklusive dess stereotyper — och därmed också sökresultaten.
Två arkitekturfamiljer, olika syften:
| Tvåtorn (CLIP) | Sammanfogad (LLaVA) | |
|---|---|---|
| Kodare | separata, jämförs med skalärprodukt | bildpatchar projiceras in i språkmodellens tokenström |
| Klarar | sökning i stor skala, förkoda index | resonemang och fritt svar om bilden |
| Kostnad per fråga | mycket låg | hög |
De konkurrerar inte — i praktiken används CLIP för att hitta och en VLM för att resonera om det som hittades.
Kod
import numpy as np, torch
from transformers import CLIPModel, CLIPProcessor
m = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
pro = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
def bildvektorer(bilder):
with torch.no_grad():
v = m.get_image_features(**pro(images=bilder, return_tensors="pt"))
return torch.nn.functional.normalize(v, dim=-1).numpy()
def textvektor(text):
with torch.no_grad():
v = m.get_text_features(**pro(text=[text], return_tensors="pt", padding=True))
return torch.nn.functional.normalize(v, dim=-1).numpy()[0]
INDEX = bildvektorer(bilder) # (N, 512), normaliserade
def sok(fraga, k=5):
q = textvektor(f"ett foto av {fraga}") # promptmallen höjer träffsäkerheten
s = INDEX @ q # cosinuslikhet
return [(i, float(s[i])) for i in np.argsort(-s)[:k]]
# Klassificering utan träningsdata
klasser = ["en katt", "en hund", "en häst"]
T = np.stack([textvektor(f"ett foto av {k}") for k in klasser])
print(klasser[int(np.argmax(bildvektorer([bild])[0] @ T.T))])
# Kompositionalitetstestet — kör det på din egen data innan du litar på rummet
a, b = textvektor("hunden jagar katten"), textvektor("katten jagar hunden")
print(round(float(a @ b), 3)) # ~0.95 — modellen ser knappt skillnaden
Sista raden är värd att köra en gång: den visar tydligare än någon förklaring varför ett delat vektorrum inte är en förståelse av scenen.
Behärskning innebär
- Förklarar kontrastiv inlärning över två modaliteter
- Söker mellan modaliteter med ett gemensamt rum
- Känner till vad ett delat rum inte klarar
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- arXiv — Learning Transferable Visual Models From Natural Language Supervision (CLIP) — arXiv (öppen åtkomst; licens per artikel)
- Hugging Face — dokumentation (Apache-2.0) — Apache-2.0
- Dive into Deep Learning (CC BY-SA 4.0) — CC BY-SA 4.0