Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

Open In Colab

使用多模態嵌入分析藝術風格

作者:Jacob Marks

Art Analysis Cover Image

影像等視覺資料資訊極其豐富,但其非結構化特性使其難以分析。

在本筆記本中,我們將探討如何使用多模態嵌入和計算屬性來分析影像中的藝術風格。我們將使用來自 🤗 Hub 的 WikiArt 資料集,並將其載入到 FiftyOne 中進行資料分析和視覺化。我們將以多種方式深入研究資料:

  • 影像相似性搜尋和語義搜尋:我們將使用 🤗 Transformers 中預訓練的 CLIP 模型為資料集中的影像生成多模態嵌入,並對資料進行索引以允許非結構化搜尋。

  • 聚類和視覺化:我們將使用嵌入對影像進行藝術風格聚類,並使用 UMAP 降維技術視覺化結果。

  • 獨特性分析:我們將使用嵌入根據每幅影像與其他影像在資料集中的相似程度為其分配一個獨特性分數。

  • 影像質量分析:我們將計算每幅影像的亮度、對比度和飽和度等影像質量指標,並檢視這些指標與影像藝術風格的相關性。

讓我們開始吧!🚀

要執行此筆記本,您需要安裝以下庫:

!pip install -U transformers huggingface_hub fiftyone umap-learn

為了實現閃電般的下載速度,請安裝 HF Transfer

pip install hf-transfer

並透過設定環境變數 HF_HUB_ENABLE_HF_TRANSFER 來啟用它。

import os
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
注意:此筆記本使用 transformers==4.40.0huggingface_hub==0.22.2fiftyone==0.23.8 進行測試。

現在讓我們匯入本筆記本所需的模組。

import fiftyone as fo  # base library and app
import fiftyone.zoo as foz  # zoo datasets and models
import fiftyone.brain as fob  # ML routines
from fiftyone import ViewField as F  # for defining custom views
import fiftyone.utils.huggingface as fouh  # for loading datasets from Hugging Face

我們將首先從 🤗 Hub 將 WikiArt 資料集載入到 FiftyOne 中。這個資料集也可以透過 Hugging Face 的 datasets 庫載入,但我們將使用 FiftyOne 的 🤗 Hub 整合直接從資料集伺服器獲取資料。為了加快計算速度,我們只下載前 $1,000$ 個樣本。

dataset = fouh.load_from_hub(
    "huggan/wikiart",  ## repo_id
    format="parquet",  ## for Parquet format
    classification_fields=["artist", "style", "genre"],  # columns to store as classification fields
    max_samples=1000,  # number of samples to load
    name="wikiart",  # name of the dataset in FiftyOne
)

列印資料集摘要以檢視其內容

>>> print(dataset)
Name:        wikiart
Media type:  image
Num samples: 1000
Persistent:  False
Tags:        []
Sample fields:
    id:       fiftyone.core.fields.ObjectIdField
    filepath: fiftyone.core.fields.StringField
    tags:     fiftyone.core.fields.ListField(fiftyone.core.fields.StringField)
    metadata: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.metadata.ImageMetadata)
    artist:   fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Classification)
    style:    fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Classification)
    genre:    fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Classification)
    row_idx:  fiftyone.core.fields.IntField

FiftyOne App 中視覺化資料集

session = fo.launch_app(dataset)

WikiArt Dataset

讓我們列出我們將要分析其風格的藝術家姓名。

>>> artists = dataset.distinct("artist.label")
>>> print(artists)
['Unknown Artist', 'albrecht-durer', 'boris-kustodiev', 'camille-pissarro', 'childe-hassam', 'claude-monet', 'edgar-degas', 'eugene-boudin', 'gustave-dore', 'ilya-repin', 'ivan-aivazovsky', 'ivan-shishkin', 'john-singer-sargent', 'marc-chagall', 'martiros-saryan', 'nicholas-roerich', 'pablo-picasso', 'paul-cezanne', 'pierre-auguste-renoir', 'pyotr-konchalovsky', 'raphael-kirchner', 'rembrandt', 'salvador-dali', 'vincent-van-gogh']

尋找相似藝術品

當你找到一件喜歡的藝術品時,很自然地會想找到相似的作品。我們可以透過向量嵌入來做到這一點!此外,透過使用多模態嵌入,我們將能夠找到與給定文字查詢(可以是繪畫描述,甚至是詩歌)非常相似的畫作。

讓我們使用 🤗 Transformers 中預訓練的 CLIP Vision Transformer (ViT) 模型為影像生成多模態嵌入。執行 FiftyOne Brain 中的 compute_similarity() 將計算這些嵌入並使用它們在資料集上生成相似性索引。

>>> fob.compute_similarity(
...     dataset,
...     model="zero-shot-classification-transformer-torch",  ## type of model to load from model zoo
...     name_or_path="openai/clip-vit-base-patch32",  ## repo_id of checkpoint
...     embeddings="clip_embeddings",  ## name of the field to store embeddings
...     brain_key="clip_sim",  ## key to store similarity index info
...     batch_size=32,  ## batch size for inference
... )
Computing embeddings...
 100% |███████████████| 1000/1000 [5.0m elapsed, 0s remaining, 3.3 samples/s]

或者,您可以直接從 🤗 Transformers 庫載入模型並直接傳入模型。

from transformers import CLIPModel
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
fob.compute_similarity(
    dataset, 
    model=model,
    embeddings="clip_embeddings", ## name of the field to store embeddings
    brain_key="clip_sim" ## key to store similarity index info
)

有關此功能及更多內容的全面指南,請檢視 FiftyOne 的 🤗 Transformers 整合

重新整理 FiftyOne 應用程式,選擇樣本網格中的影像複選框,然後點選照片圖示以檢視資料集中最相似的影像。在後端,點選此按鈕會觸發對相似性索引的查詢,以根據預先計算的嵌入查詢與所選影像最相似的影像,並在應用程式中顯示它們。

Image Similarity Search

我們可以用它來檢視哪些藝術品與給定的藝術品最相似。這對於尋找相似藝術品(推薦給使用者或新增到收藏中)或獲取新作品的靈感很有用。

但這還遠不止於此!由於 CLIP 是多模態的,我們還可以用它來執行語義搜尋。這意味著我們可以根據文字查詢搜尋影像。例如,我們可以搜尋“柔和的樹木”,然後看到資料集中所有與該查詢相似的影像。要做到這一點,請點選 FiftyOne App 中的搜尋圖示並輸入文字查詢。

Semantic Search

在幕後,文字被分詞,使用 CLIP 的文字編碼器進行嵌入,然後用於查詢相似性索引以查詢資料集中最相似的影像。這是一種強大的方法,可以根據文字查詢搜尋影像,並且對於查詢與特定主題或風格匹配的影像非常有用。這不僅限於 CLIP;您可以使用 🤗 Transformers 中任何能夠為影像和文字生成嵌入的類似 CLIP 的模型!

💡 為了對大型資料集進行高效的向量搜尋和索引,FiftyOne 原生集成了開源向量資料庫

透過聚類和視覺化揭示藝術主題

透過執行相似性搜尋和語義搜尋,我們可以開始更有效地與資料互動。但我們還可以更進一步,加入一些無監督學習。這將幫助我們識別 WikiArt 資料集中的藝術模式,從風格到主題,甚至那些難以用語言表達的圖案。

我們將透過兩種方式實現這一點:

  1. 降維:我們將使用 UMAP 將嵌入的維度降低到 2D,並在散點圖中視覺化資料。這將使我們能夠根據影像的風格、流派和藝術家檢視它們的聚類方式。
  2. 聚類:我們將使用 K-Means 聚類根據嵌入對影像進行聚類,並查看出現哪些組。

對於降維,我們將執行 FiftyOne Brain 中的 compute_visualization(),並傳入之前計算的嵌入。我們指定 method="umap" 來使用 UMAP 進行降維,但我們也可以使用 PCA 或 t-SNE。

>>> fob.compute_visualization(dataset, embeddings="clip_embeddings", method="umap", brain_key="clip_vis")
Generating visualization...

現在我們可以在 FiftyOne 應用程式中開啟一個面板,其中我們將看到資料集中每個影像的一個 2D 點。我們可以根據資料集中的任何欄位(例如藝術家或流派)為點著色,以檢視這些屬性被我們的影像特徵捕獲的強度。

UMAP Visualization

我們還可以對嵌入進行聚類,將相似的影像分組在一起——也許這些藝術作品的主要特徵並未被現有標籤捕獲,或者我們想識別出獨特的子流派。為了對資料進行聚類,我們需要下載 FiftyOne 聚類外掛

!fiftyone plugins download https://github.com/jacobmarks/clustering-plugin

再次重新整理應用程式,然後我們可以透過應用程式中的運算子訪問聚類功能。按下反引號鍵開啟運算子列表,輸入“cluster”並從下拉選單中選擇運算子。這將開啟一個互動式面板,我們可以在其中指定聚類演算法、超引數以及要聚類的欄位。為簡單起見,我們將使用 K-Means 聚類,包含 $10$ 個簇。

然後我們可以在應用程式中視覺化這些聚類,並檢視影像如何根據其嵌入分組在一起。

K-means Clustering

我們可以看到,一些聚類是針對藝術家的;另一些則是針對流派或風格的。還有一些則更抽象,可能代表著資料中不那麼顯而易見的子流派或其他分組。

識別最獨特的藝術作品

我們可以問一個關於我們資料集的有趣問題:每張影像有多麼獨特。這個問題對於許多應用都很重要,例如推薦相似影像、檢測重複項或識別異常值。在藝術領域,一幅畫的獨特性可能是決定其價值的重要因素。

雖然有無數種方法可以表徵獨特性,但我們的影像嵌入使我們能夠根據每個樣本與資料集中其他樣本的相似程度,定量地為每個樣本分配一個獨特性分數。具體來說,FiftyOne Brain 的 compute_uniqueness() 函式會檢視每個樣本的嵌入與其最近鄰之間的距離,並根據此距離計算一個介於 $0$ 到 $1$ 之間的分數。分數為 $0$ 意味著樣本平淡無奇或與其他樣本非常相似,而分數為 $1$ 意味著樣本非常獨特。

>>> fob.compute_uniqueness(dataset, embeddings="clip_embeddings")  # compute uniqueness using CLIP embeddings
Computing uniqueness...
Uniqueness computation complete

然後我們可以在嵌入面板中根據此進行著色,根據獨特性分數進行篩選,甚至按此排序以檢視資料集中最獨特的影像。

most_unique_view = dataset.sort_by("uniqueness", reverse=True)
session.view = most_unique_view.view()  # Most unique images

Most Unique Images

least_unique_view = dataset.sort_by("uniqueness", reverse=False)
session.view = least_unique_view.view()  # Least unique images

Least Unique Images

更進一步,我們還可以回答哪個藝術家傾向於創作最獨特的作品。我們可以計算每位藝術家所有藝術作品的平均獨特性分數。

>>> artist_unique_scores = {
...     artist: dataset.match(F("artist.label") == artist).mean("uniqueness") for artist in artists
... }

>>> sorted_artists = sorted(artist_unique_scores, key=artist_unique_scores.get, reverse=True)

>>> for artist in sorted_artists:
...     print(f"{artist}: {artist_unique_scores[artist]}")
Unknown Artist: 0.7932221632002723
boris-kustodiev: 0.7480731948424676
salvador-dali: 0.7368807620414014
raphael-kirchner: 0.7315448102204755
ilya-repin: 0.7204744626806383
marc-chagall: 0.7169373812321908
rembrandt: 0.715205220292227
martiros-saryan: 0.708560775790436
childe-hassam: 0.7018343391132756
edgar-degas: 0.699912746806587
albrecht-durer: 0.6969358680800216
john-singer-sargent: 0.6839955708720844
pablo-picasso: 0.6835137858302969
pyotr-konchalovsky: 0.6780653000855895
nicholas-roerich: 0.6676504687452387
ivan-aivazovsky: 0.6484361530090199
vincent-van-gogh: 0.6472004520699081
gustave-dore: 0.6307283287457358
pierre-auguste-renoir: 0.6271467146993583
paul-cezanne: 0.6251076007168186
eugene-boudin: 0.6103397516167454
camille-pissarro: 0.6046182609119615
claude-monet: 0.5998234558947573
ivan-shishkin: 0.589796389836674

看來,我們資料集中作品最獨特的藝術家是鮑里斯·庫斯托季耶夫!讓我們看看他的一些作品。

kustodiev_view = dataset.match(F("artist.label") == "boris-kustodiev")
session.view = kustodiev_view.view()

Boris Kustodiev Artwork

用視覺品質刻畫藝術

總結一下,讓我們回到基礎,分析資料集中影像的一些核心品質。我們將計算每張影像的亮度、對比度和飽和度等標準指標,並檢視這些指標與藝術作品的藝術風格和流派之間的關聯。

要執行這些分析,我們需要下載 FiftyOne 影像質量外掛

!fiftyone plugins download https://github.com/jacobmarks/image-quality-issues/

重新整理應用程式並再次開啟運算子列表。這次輸入 compute 並選擇其中一個影像質量運算子。我們將從亮度開始。

Compute Brightness

當運算子執行結束後,我們的資料集中將新增一個欄位,其中包含每張影像的亮度分數。然後我們可以在應用程式中視覺化這些資料。

Brightness

我們還可以根據亮度著色,甚至檢視它與資料集中其他欄位(如風格)的相關性。

Style by Brightness

現在對對比度和飽和度也做同樣的操作。以下是飽和度的結果:

Filter by Saturation

希望這能說明並非所有事情都歸結為將深度神經網路應用於您的資料。有時,簡單的指標同樣具有資訊量,並且可以為您的資料提供不同的視角🤓!

📚 對於更大的資料集,您可能需要委託操作以供稍後執行。

接下來是什麼?

在本筆記本中,我們探討了如何使用多模態嵌入、無監督學習和傳統影像處理技術來分析影像中的藝術風格。我們瞭解瞭如何執行影像相似性和語義搜尋、根據風格對影像進行聚類、分析影像的獨特性以及計算影像質量指標。這些技術可以應用於各種視覺資料集,從藝術收藏到醫學影像再到衛星影像。嘗試從 Hugging Face Hub 載入不同的資料集,看看你能發現什麼見解!

如果您想更深入地瞭解,可以嘗試以下額外分析:

  • 零樣本分類:使用 🤗 Transformers 中預訓練的視覺語言模型根據主題或內容對資料集中的影像進行分類,無需任何訓練資料。有關更多資訊,請檢視此零樣本分類教程
  • 影像字幕生成:使用 🤗 Transformers 中預訓練的視覺語言模型為資料集中的影像生成字幕。然後,將其用於主題建模或根據這些字幕的嵌入對藝術品進行聚類。有關更多資訊,請檢視 FiftyOne 的影像字幕生成外掛

📚 資源

FiftyOne 開源專案

FiftyOne 是用於構建高質量資料集和計算機視覺模型的領先開源工具包。FiftyOne 擁有超過 200 萬次下載量,受到全球開發人員和研究人員的信賴。

💪 FiftyOne 團隊歡迎開源社群的貢獻!如果您有興趣為 FiftyOne 做出貢獻,請檢視貢獻指南

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.