獨家 | 圖片主題建模?為什么不呢?!
作者:Maarten Grootendorst
翻譯:陳超
校對:趙茹萱
主題建模是一種允許用戶在無監督情況下,在海量數據當中尋找主題的一系列技術合集、在這些文件內容當中嘗試建模并跑EDA模型的時候是非常冒險的一種行為。
之前我發明了一個主題建模技術叫做BERTopic,這種技術可以利用BERT和基于類的TF-IDF來創建密集的類用于易解釋主題。
一段時間之后,我開始思考它在其他領域的可解釋性,比如計算機視覺。如果我們可以將其應用于圖片主題建模那將是一件多么酷的事情呀!
圖片主題建模,你需要做的一切。圖片來自作者
這件事確實花了一些時間,但是若干實驗之后,我想到了解決方法:Concept!
Concept是一個同時介紹圖片和文本主題建模概念的包。然而,由于主題通常指的是文本或者口語,它通常不能很好地涵蓋圖片組的含義。我們這里將圖片組和文字都定義為概念。
概念的logo。圖片來自作者
因此,Concept包可以做Concept建模,這種建模是一種統計模型,用于在圖片集合以及相應文件當中發現抽象的概念。
概念模型是圖片和文本主題建模的泛化
為了讓你更好地了解,以下是從概念建模當中抽取的概念:
由概念建模生成的多模態概念。圖片來自作者
如同你注意到的,我們可以通過他們的文本表征和視覺表征來解釋這些概念。真正的概念建模可以通過結合這些表征來提取。
概念建模允許一種概念的多模態表征
一圖勝千言。但是如果我們給圖片增加文字呢?兩類交流方法的協同作用(synergy)可以豐富概念的解釋和理解。
概念建模指南
Concept是一種利用CLIP和基于BERTopic技術來對圖片和文本進行概念建模的工具。
(https://colab.research.google.com/drive/1XHwQPT2itZXu1HayvGoj60-xAXxg9mqe?usp=sharing)
在本文當中,我將帶大家了解如何用Concept包構建你自己的概念模型。你可以跟隨上方的Google Colab notebook鏈接一起學習。
第一步:安裝Concept包
我們可以通過PyPI輕松安裝Concept:
pip install concept
第二步:準備好圖片
為了進行概念建模,我們需要一些圖片來聚類。我們將在UNsplash上下載25,000張圖片,這些圖片已經被Sentence-Transformers包整理好了。
import os import glob import zipfile from tqdm import tqdm from sentence_transformers import util # Download 25k images from Unsplash img_folder = 'photos/' if not os.path.exists(img_folder) or len(os.listdir(img_folder)) == 0: os.makedirs(img_folder, exist_ok=True) photo_filename = 'unsplash-25k-photos.zip' if not os.path.exists(photo_filename): #Download dataset if does not exist util.http_get('http://sbert.net/datasets/'+photo_filename, photo_filename) #Extract all images with zipfile.ZipFile(photo_filename, 'r') as zf: for member in tqdm(zf.infolist(), desc='Extracting'): zf.extract(member, img_folder) # Load image paths img_names = list(glob.glob('photos/*.jpg')) view rawload_images.py hosted with ? by GitHub
準備好圖片之后,我們就可以在沒有任何文本的情況下在Concept包中使用它。然而,這并不會構建任何文本化的表征。所以下一步是準備我們的文本。
第三步:準備好文本
Concept有趣的地方在于,任何文本都可以喂給這個模型。理想狀況下,我們想把跟手邊圖片最相關的文本喂給模型。我們通常會對我們圖片中的細節產生一些理解。
然而,事實卻并不總是如此順利。所以為了闡明目的,我們需要給模型喂英文詞典當中的一堆詞:
import random import nltk nltk.download("wordnet") from nltk.corpus import wordnet as wn all_nouns = [word for synset in wn.all_synsets('n') for word in synset.lemma_names() if "_" not in word] selected_nouns = random.sample(all_nouns, 50_000) view rawprepare_text.py hosted with ? by GitHub
在上述文本當中,我們以兩個原因納入了50,000個隨機名詞。第一,不需要將英文詞典上出現的所有名詞都納入進來,因為我們可以假定50,000詞應該表征了充分的實體。第二,這可以加速計算過程,因為我們需要從更少的單詞當中提取嵌入。
從實踐角度來看,如果你有已知與圖片相關的文本數據,用他們替代名詞即可。
第四步:訓練模型
下一步就是訓練模型啦!像通常一樣,我們相對直接一點兒。只需將每個圖片的路徑和我們選擇的名詞提供給模型:
from concept import ConceptModel concept_model = ConceptModel() concepts = concept_model.fit_transform(img_names, docs=selected_nouns) view rawtrain_concept.py hosted with ? by GitHub
Concept變量包括了每幅圖的預測概念。
劃線的概念模型是Openai的CLIP,這是一個訓練大量圖片和文本對的神經網絡。這意味著模型在生成嵌入時受益于使用GPU。
最后,運行concept_model.frequency來看一下包括概念頻率的數據框。
注意:使用Concept(embedding_model="clip-ViT-B-32-multilingual-v1")來選擇一個支持50+種語言的模型!
預訓練圖片嵌入
對那些想要嘗試這個demo但是沒有GPU使用權限的人來說,我們可以從sentence-Transformers站點來加載預訓練的圖像嵌入:
import pickle from sentence_transformers import util # Load pre-trained image embeddings emb_filename = 'unsplash-25k-photos-embeddings.pkl' if not os.path.exists(emb_filename): #Download dataset if does not exist util.http_get('http://sbert.net/datasets/'+emb_filename, emb_filename) with open(emb_filename, 'rb') as fIn: img_names, image_embeddings = pickle.load(fIn) img_names = [f"photos/{path}" for path in img_names] view rawpretrained_embeddings.py hosted with ? by GitHub
之后,我們將預訓練的嵌入添加到模型中并訓練它:
from concept import ConceptModel # Train Concept using the pre-trained image embeddings concept_model = ConceptModel() concepts = concept_model.fit_transform(img_names, image_embeddings=image_embeddings, docs=selected_nouns) view rawpretrained_modeling.py hosted with ? by GitHub
第五步:概念可視化
現在是有趣的部分,對概念進行可視化!
就像之前提到的,最終的概念是多模態的,也就是說包括了視覺和文本化雙重本質。我們需要找到一種方式來從單一視角來表征兩者。
為了做到這一點,我們選取了一些最能表征每個概念的一組圖片,并找到最能表征這些圖片的名詞。
通常,我們會以如下直觀方式創建可視化:
fig = concept_model.visualize_concepts() view rawvisualize.py hosted with ? by GitHub
九個最常用的概念可視化。圖片來自作者
我們數據集當中的大部分圖片斗魚大自然有關。然而,如果我們再深入看一看更多有趣的概念:
更常見的概念,標記概念多樣性。圖片來自作者
以上結果為如何在概念建模中直觀地思考概念提供了一個漂亮的例子。我們不僅可以通過圖片集來看可視化表征,也可以通過文本表征來幫助我們更深入地理解我們可以在這些概念當中發現的內容。
第六步:檢索概念
我們可以通過嵌入一個檢索術語以及發現表征類的最佳特征來快速檢索特定概念。舉例來看,我們檢索沙灘(beach)這個術語來看看我們能找到什么。為了做到這一點,我們可以簡單地運行以下代碼:
>>> search_results =concept_model.find_concepts("beach") >>> search_results [(100, 0.277577825349102), (53, 0.27431058773894657), (95, 0.25973751319723837), (77, 0.2560122597417548), (97, 0.25361988261846297)] view rawsearch.py hosted with ? by GitHub
每一個元組包含兩個值,第一個是概念類,另一個是檢索術語相似性。返回前五個最相似的主題。
現在,讓我們對概念進行可視化來看看這個檢索函數是如何工作的:
fig = concept_model.visualize_concepts(concepts=[concept for concept, _ in search_results])
view rawvisualize_search.py hosted with ? by GitHub
檢索術語“beach”。圖片來自作者
我們可以看到,結果概念與我們的檢索術語非常相似!多模態的模型本質使得我們可以輕易地檢索到概念和圖片。
第七步:算法概覽
對于那些對概念機制感興趣的朋友,以下為創造結果概念的方法抽象概覽:
概念算法概覽。圖片來自作者
1. 嵌入圖片和文件
我們通過使用OpenAI的CLIP模型將圖片和文件嵌入相同的向量空間開始。這允許我們在圖片和文本面前比較。文件包括文字,短語,句子等。一切你覺得可以表征概念類的最佳方式。
2. 概念聚類
使用UMAP+HDBSCAN,我們可以聚類圖片特征并創建視覺和語義相似的類。我們指的是那些表征多模態本質的概念類。
3. 概念表征
為了表征這些概念類,我們選取與每個概念最相關的圖片,叫做范例(exemplar)。依賴于概念類的大小,每個類里范例的數量可能會超過幾百,因此需要一個過濾器。
我們使用MMR來選擇那些與概念特征最相關但是彼此之間仍然充分不相似的圖片。這樣,我們可以盡可能多地來展示這個概念。選中的圖片將合稱為單圖來創建單個可視化表征。
4. 多模態
最后,我們提取文本特征并與創建的概念類特征進行比較。使用余弦相似性,我們選出那些最相關的特征。將多模態引入概念表征之中。
注意:使用 c-TF-IDF的 concept_model = ConceptModel(ctfidf=True) 提取文本表征也是一種選擇。
感謝您的閱讀!
如果你想我一樣對AI,數據科學或者心理學感興趣,請在LinkedIn
(https://www.linkedin.com/in/mgrootendorst/)
上添加我或者關注我的Twitter(https://twitter.com/MaartenGr)。
你可以在下方找到Concept包,以及它的文件:
概念建模:文本和圖片主題建模(https://github.com/MaartenGr/Concept)
概念文檔(https://maartengr.github.io/Concept/)
原文標題:
Topic Modeling on Images? Why Not?!
原文鏈接:
https://towardsdatascience.com/topic-modeling-on-images-why-not-aad331d03246
*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。
三維掃描儀相關文章:三維掃描儀原理