一文讀懂多模態(tài) embeddings
傳統(tǒng)上,AI研究被劃分為不同的領(lǐng)域:自然語言處理(NLP)、計算機(jī)視覺(CV)、機(jī)器人學(xué)、人機(jī)交互(HCI)等。然而,無數(shù)實際任務(wù)需要整合這些不同的研究領(lǐng)域,例如自動駕駛汽車(CV + 機(jī)器人學(xué))、AI代理(NLP + CV + HCI)、個性化學(xué)習(xí)(NLP + HCI)等。
盡管這些領(lǐng)域旨在解決不同的問題并處理不同的數(shù)據(jù)類型,但它們都共享一個基本過程。即生成現(xiàn)實世界現(xiàn)象的有用數(shù)值表示。
歷史上,這是手工完成的。這意味著研究人員和從業(yè)者會利用他們(或其他人)的專業(yè)知識,將數(shù)據(jù)顯式轉(zhuǎn)換為更有用的形式。然而,今天,這些可以通過另一種方式獲得。在本文中,我將討論多模態(tài)embeddings,并通過兩個實際用例分享它們的功能。
Embeddings
embeddings是通過模型訓(xùn)練隱式學(xué)習(xí)的數(shù)據(jù)的有用數(shù)值表示。例如,通過學(xué)習(xí)如何預(yù)測文本,BERT學(xué)習(xí)了文本的表示,這些表示對許多NLP任務(wù)很有幫助[1]。另一個例子是Vision Transformer(ViT),它在Image Net上進(jìn)行圖像分類訓(xùn)練,可以重新用于其他應(yīng)用[2]。
這里的一個關(guān)鍵點是,這些學(xué)習(xí)到的embeddings空間將具有一些底層結(jié)構(gòu),使得相似的概念彼此接近。如下面的玩具示例所示。
文本和圖像embeddings的表示
前面提到的模型的一個關(guān)鍵限制是它們僅限于單一數(shù)據(jù)模態(tài),例如文本或圖像。這阻止了跨模態(tài)應(yīng)用,如圖像字幕生成、內(nèi)容審核、圖像搜索等。但如果我們可以合并這兩種表示呢?
多模態(tài) Embeddings
盡管文本和圖像在我們看來可能非常不同,但在神經(jīng)網(wǎng)絡(luò)中,它們通過相同的數(shù)學(xué)對象(即向量)表示。因此,原則上,文本、圖像或任何其他數(shù)據(jù)模態(tài)都可以由單個模型處理。
這一事實是多模態(tài)embeddings的基礎(chǔ),它將多個數(shù)據(jù)模態(tài)表示在同一向量空間中,使得相似的概念位于相近的位置(獨立于它們的原始表示)。
多模態(tài)embeddings空間的表示
例如,CLIP將文本和圖像編碼到共享的embeddings空間中[3]。CLIP的一個關(guān)鍵見解是,通過對齊文本和圖像表示,模型能夠在任意一組目標(biāo)類上進(jìn)行零樣本圖像分類,因為任何輸入文本都可以被視為類標(biāo)簽(我們將在后面看到一個具體示例)。
然而,這個想法不僅限于文本和圖像。幾乎任何數(shù)據(jù)模態(tài)都可以以這種方式對齊,例如文本-音頻、音頻-圖像、文本-腦電圖、圖像-表格和文本-視頻。這解鎖了視頻字幕生成、高級OCR、音頻轉(zhuǎn)錄、視頻搜索和腦電圖到文本等用例[4]。
對比學(xué)習(xí)
對齊不同embeddings空間的標(biāo)準(zhǔn)方法是對比學(xué)習(xí)(CL)。CL的一個關(guān)鍵直覺是相似地表示相同信息的不同視圖[5]。
這包括學(xué)習(xí)表示,以最大化正對之間的相似性并最小化負(fù)對的相似性。在圖像-文本模型的情況下,正對可能是帶有適當(dāng)標(biāo)題的圖像,而負(fù)對可能是帶有不相關(guān)標(biāo)題的圖像(如下所示)。
對比訓(xùn)練中使用的正對和負(fù)對示例
CL的兩個關(guān)鍵方面促成了其有效性:
- 由于正對和負(fù)對可以從數(shù)據(jù)的固有結(jié)構(gòu)(例如,網(wǎng)絡(luò)圖像的元數(shù)據(jù))中策劃,CL訓(xùn)練數(shù)據(jù)不需要手動標(biāo)記,這解鎖了更大規(guī)模的訓(xùn)練和更強(qiáng)大的表示[3]。
- 它通過特殊的損失函數(shù)同時最大化正對和最小化負(fù)對的相似性,如CLIP所示[3]。
CLIP用于文本-圖像表示對齊的對比損失[3]
示例代碼:使用CLIP進(jìn)行零樣本分類和圖像搜索
在了解了多模態(tài)embeddings的工作原理后,讓我們看看它們可以做的兩個具體示例。在這里,我將使用開源的CLIP模型執(zhí)行兩個任務(wù):零樣本圖像分類和圖像搜索。
這些示例的代碼在GitHub倉庫中免費(fèi)提供:https://github.com/ShawhinT/YouTube-Blog/tree/main/multimodal-ai/2-mm-embeddings。
用例1:零樣本圖像分類
使用CLIP進(jìn)行零樣本圖像分類的基本思想是將圖像與一組可能的類標(biāo)簽一起傳遞給模型。然后,通過評估哪個文本輸入與輸入圖像最相似來進(jìn)行分類。
我們首先導(dǎo)入Hugging Face Transformers庫,以便可以在本地下載CLIP模型。此外,PIL庫用于在Python中加載圖像。
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
接下來,我們可以導(dǎo)入一個版本的clip模型及其相關(guān)的數(shù)據(jù)處理器。注意:處理器處理輸入文本的標(biāo)記化和圖像準(zhǔn)備。
# import model
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch16")
# import processor (handles text tokenization and image preprocessing)
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch16")
我們加載下面的貓的圖像,并創(chuàng)建兩個可能的類標(biāo)簽列表:“一張貓的照片”或“一張狗的照片”。
# load image
image = Image.open("images/cat_cute.png")
# define text classes
text_classes = ["a photo of a cat", "a photo of a dog"]
輸入的貓照片
接下來,我們將預(yù)處理圖像/文本輸入并將它們傳遞給模型。
# pass image and text classes to processor
inputs = processor(text=text_classes, images=image, return_tensors="pt",
padding=True)
# pass inputs to CLIP
outputs = model(**inputs) # note: "**" unpacks dictionary items
要進(jìn)行類預(yù)測,我們必須提取圖像logits并評估哪個類對應(yīng)于最大值。
# image-text similarity score
logits_per_image = outputs.logits_per_image
# convert scores to probs via softmax
probs = logits_per_image.softmax(dim=1)
# print prediction
predicted_class = text_classes[probs.argmax()]
print(predicted_class, "| Probability = ",
round(float(probs[0][probs.argmax()]),4))
>> a photo of a cat | Probability = 0.9979
模型以99.79%的概率準(zhǔn)確識別出這是一張貓的照片。然而,這是一個非常簡單的例子。讓我們看看當(dāng)我們將類標(biāo)簽更改為:“丑貓”和“可愛貓”時會發(fā)生什么。
>> cute cat | Probability = 0.9703
模型輕松識別出圖像確實是一只可愛的貓。讓我們做一些更具挑戰(zhàn)性的標(biāo)簽,例如:“貓表情包”或“非貓表情包”。
>> not cat meme | Probability = 0.5464
雖然模型對這個預(yù)測的信心較低,只有54.64%的概率,但它正確地暗示了圖像不是表情包。
用例2:圖像搜索
CLIP的另一個應(yīng)用基本上是用例1的逆過程。與其識別哪個文本標(biāo)簽與輸入圖像匹配,我們可以評估哪個圖像(在一組中)與文本輸入(即查詢)最匹配——換句話說,在圖像上執(zhí)行搜索。我們首先將一組圖像存儲在列表中。在這里,我有三張貓、狗和山羊的圖像。
# create list of images to search over
image_name_list = ["images/cat_cute.png", "images/dog.png", "images/goat.png"]
image_list = []
for image_name in image_name_list:
image_list.append(Image.open(image_name))
接下來,我們可以定義一個查詢,如“一只可愛的狗”,并將其與圖像一起傳遞給CLIP。
# define a query
query = "a cute dog"
# pass images and query to CLIP
inputs = processor(text=query, images=image_list, return_tensors="pt",
padding=True)
然后,我們可以通過提取文本logits并評估對應(yīng)于最大值的圖像來將最佳圖像與輸入文本匹配。
# compute logits and probabilities
outputs = model(**inputs)
logits_per_text = outputs.logits_per_text
probs = logits_per_text.softmax(dim=1)
# print best match
best_match = image_list[probs.argmax()]
prob_match = round(float(probs[0][probs.argmax()]),4)
print("Match probability: ",prob_match)
display(best_match)
>> Match probability: 0.9817
查詢“一只可愛的狗”的最佳匹配
我們看到(再次)模型在這個簡單示例中表現(xiàn)出色。但讓我們嘗試一些更棘手的例子。
query = "something cute but metal ??"
>> Match probability: 0.7715
查詢“可愛但金屬的東西??”的最佳匹配
query = "a good boy"
>> Match probability: 0.8248
查詢“一個好男孩”的最佳匹配
query = "the best pet in the world"
>> Match probability: 0.5664
查詢“世界上最好的寵物”的最佳匹配
盡管最后一個預(yù)測頗具爭議,但所有其他匹配都非常準(zhǔn)確。這可能是因為像這樣的圖像在互聯(lián)網(wǎng)上無處不在,因此在CLIP的預(yù)訓(xùn)練中被多次看到。
接下來可以做什么?
多模態(tài)embeddings解鎖了涉及多個數(shù)據(jù)模態(tài)的無數(shù)AI用例。在這里,我們看到了兩個這樣的用例,即使用CLIP進(jìn)行零樣本圖像分類和圖像搜索。像CLIP這樣的模型的另一個實際應(yīng)用是多模態(tài)RAG,它包括自動檢索多模態(tài)上下文到LLM。在本系列的下一篇文章中,我們將了解其內(nèi)部工作原理并回顧一個具體示例。
【參考文獻(xiàn)】
- [1] BERT:https://arxiv.org/abs/1810.04805
- [2] ViT:https://arxiv.org/abs/2010.11929
- [3] CLIP:https://arxiv.org/abs/2103.00020
- [4] Thought2Text: 使用大型語言模型(LLMs)從腦電圖信號生成文本:https://arxiv.org/abs/2410.07507
- [5] 對比學(xué)習(xí)視覺表示的簡單框架:https://arxiv.org/abs/2002.05709