兩座塔,一個會合處
你已經知道如何把一張圖嵌入向量、如何把一句話嵌入向量。開啟現代多模態 AI 的問題其實出奇地簡單:我們能不能把兩者放進同一個空間,讓一張柯基的照片落在「一隻柯基」這幾個字附近? 這正是視覺語言預訓練的全部前提。我們訓練兩個編碼器——一座視覺塔(通常是 ViT)與一座文字塔——只要求當圖片與描述指向同一件事時,它們的輸出彼此一致。
這種雙編碼器設計正是 CLIP 出名的原因。關鍵在於:兩座塔在前向傳播時從不交談——它們只在最後透過一個相似度分數會合。這讓推論很便宜(每張圖的嵌入只要預先算一次),也讓檢索變得輕而易舉:要找最佳描述,取最近的文字向量即可。
两个向量的点积作为其余弦相似度的示意图。
對比目標
引擎是一個對稱的圖文對比損失。取一個批次的 N 對圖片與描述,計算每張圖與每句描述之間全部 N×N 的相似度。對角線上的 N 對是正樣本;對角線外的 N²−N 對是負樣本。這個損失——對列與對行各做一次交叉熵——把每個正樣本推到它所在列與行中所有負樣本之上。這正是你在對比學習中見過的 InfoNCE 目標,只是現在跨模態套用,而非跨資料增強。
对称的图文对比损失:两个方向各是一个 N 类 softmax,唯一的正样本是真实配对,并由温度 tau 锐化。
img_e = l2norm(vision(images)) # (N, d) txt_e = l2norm(text(captions)) # (N, d) logits = img_e @ txt_e.T / tau # (N, N), tau = temperature labels = arange(N) # positives are on the diagonal loss = (ce(logits, labels) + ce(logits.T, labels)) / 2
資料換來什麼:零樣本遷移
在數億組吵雜的網路圖文對上訓練後,模型學到一種開放詞彙的對齊,是任何固定標籤集都給不了的。要在完全沒有任務專屬訓練的情況下分類一張圖,你把候選類別寫成句子(「一張 {貓} 的照片」),用文字塔嵌入它們,再挑最近的那個。這就是零樣本視覺語言分類,它之所以可行,是因為這個嵌入空間編碼的是語意,而非封閉的分類體系。
- 把每個類別寫成自然語言提示;對每個類別集成多個提示模板,能可量測地提升準確率。
- 用文字塔把所有類別提示嵌入一次,快取成一個分類器權重矩陣。
- 推論時嵌入圖片,與每個類別向量做點積——softmax 給出大致校準的分數。
零样本分类选取其文本提示嵌入与图像嵌入余弦相似度最高的类别。
模態差距
這裡有個讓「共享空間」說法謙卑下來的意外。如果你真的把訓練好的 CLIP 的圖片嵌入與文字嵌入畫出來,它們並不會交錯——而是各自坐在兩個分明的圓錐裡,被一道清楚的間隔分開。這就是模態差距。對比訓練只需要相符的對相對上比不符的對更近;它從不強迫圖片與文字在絕對位置上佔據同一塊區域。這道差距一部分在初始化時就被埋下,又被損失保留下來。
對比對齊做不到的事
雙編碼器給你一個全域的匹配分數,卻沒有細粒度的推理。它無法告訴你柯基在哪裡、數不出腿的數量、讀不了圖中的一段文字,也答不出「狗在貓的左邊還是右邊?」。它的語言端是個淺層編碼器,不是生成器——它根本生不出一個句子。要得到描述、對話與推理,我們需要把一個強大的語言模型接到視覺特徵上。那座橋就是下一篇的主題。