画像類似性比較 CLIP または DINOv2

画像類似性比較 CLIP または DINOv2

人工知能の分野において、コンピューター ビジョンの 2 大巨頭は CLIP と DINOv2 です。 CLIP は画像理解の方法を変え、DINOv2 は自己教師学習に新しい方法をもたらしました。この記事では、CLIP と DINOv2 の強みと繊細さを定義する経緯を探ります。私たちの目的は、これらのモデルのうちどれが画像類似性タスクの世界で本当に優れているかを明らかにすることです。これら 2 つの巨人の戦いを目の当たりにし、どちらのモデルが勝利するかを見てみましょう。

CLIPにおける画像の類似性

CLIP を使用して 2 つの画像間の類似度を計算するのは、2 つのステップのみを必要とする簡単なプロセスです。最初に 2 つの画像の特徴を抽出し、次にそれらのコサイン類似度を計算します。

まず、必要なパッケージがインストールされていることを確認します。仮想環境をセットアップして使用することをお勧めします。

 #Start by setting up a virtual environment virtualenv venv-similarity source venv-similarity/bin/activate #Install required packages pip install transformers Pillow torch

次に、画像の類似性を計算し続けます。

 import torch from PIL import Image from transformers import AutoProcessor, CLIPModel import torch.nn as nn device = torch.device('cuda' if torch.cuda.is可用else "cpu") processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device) #Extract features from image1 image1 = Image.open('img1.jpg') with torch.no_grad(): inputs1 = processor(images=image1, return_tensors="pt").to(device) image_features1 = model.get_image_features(**inputs1) #Extract features from image2 image2 = Image.open('img2.jpg') with torch.no_grad(): inputs2 = processor(images=image2, return_tensors="pt").to(device) image_features2 = model.get_image_features(**inputs2) #Compute their cosine similarity and convert it into a score between 0 and 1 cos = nn.CosineSimilarity(dim=0) sim = cos(image_features1[0],image_features2[0]).item() sim = (sim+1)/2 print('Similarity:', sim)

類似画像 2 件

2 つの類似画像を例にすると、達成された類似度スコアは驚異的な 96.4% でした。

DINOv2における画像の類似性

DINOv2 を使用して 2 つの画像間の類似度を計算するプロセスは、CLIP と似ています。同じパッケージセットが必要であり、追加のインストールは必要ありません。

 from transformers import AutoImageProcessor, AutoModel from PIL import Image import torch.nn as nn device = torch.device('cuda' if torch.cuda.is_available() else "cpu") processor = AutoImageProcessor.from_pretrained('facebook/dinov2-base') model = AutoModel.from_pretrained('facebook/dinov2-base').to(device) image1 = Image.open('img1.jpg') with torch.no_grad(): inputs1 = processor(images=image1, return_tensors="pt").to(device) outputs1 = model(**inputs1) image_features1 = outputs1.last_hidden_state image_features1 = image_features1.mean(dim=1) image2 = Image.open('img2.jpg') with torch.no_grad(): inputs2 = processor(images=image2, return_tensors="pt").to(device) outputs2 = model(**inputs2) image_features2 = outputs2.last_hidden_state image_features2 = image_features2.mean(dim=1) cos = nn.CosineSimilarity(dim=0) sim = cos(image_features1[0],image_features2[0]).item() sim = (sim+1)/2 print('Similarity:', sim)

CLIP の例と同じ画像ペアを使用した場合、DINOv2 を使用して 93% の類似度スコアが得られました。

COCOデータセットを使用してテスト済み

パフォーマンスの評価に入る前に、COCO データセットの検証セットの画像を使用して、CLIP と DINOv2 の結果を比較してみましょう。私たちが使用するプロセスは次のとおりです。

  • データセットを反復処理して、すべての画像の特徴を抽出します。
  • 埋め込みを FAISS インデックスに保存します。
  • 入力画像の特徴を抽出します。
  • 最も類似した 3 つの画像を取得します。

FAISS について詳しく知りたい方は、こちらの記事をご覧ください。最初に、pip install faiss-[gpu|cpu] コマンドを使用してインストールしてください。

パート 1: 特徴抽出と 2 つのインデックスの作成:

 import torch from PIL import Image from transformers import AutoProcessor, CLIPModel, AutoImageProcessor, AutoModel import faiss import os import numpy as np device = torch.device('cuda' if torch.cuda.is_available() else "cpu") #Load CLIP model and processor processor_clip = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") model_clip = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device) #Load DINOv2 model and processor processor_dino = AutoImageProcessor.from_pretrained('facebook/dinov2-base') model_dino = AutoModel.from_pretrained('facebook/dinov2-base').to(device) #Retrieve all filenames images = [] for root, dirs, files in os.walk('./val2017/'): for file in files: if file.endswith('jpg'): images.append(root + '/'+ file) #Define a function that normalizes embeddings and add them to the index def add_vector_to_index(embedding, index): #convert embedding to numpy vector = embedding.detach().cpu().numpy() #Convert to float32 numpy vector = np.float32(vector) #Normalize vector: important to avoid wrong results when searching faiss.normalize_L2(vector) #Add to index index.add(vector) def extract_features_clip(image): with torch.no_grad(): inputs = processor_clip(images=image, return_tensors="pt").to(device) image_features = model_clip.get_image_features(**inputs) return image_features def extract_features_dino(image): with torch.no_grad(): inputs = processor_dino(images=image, return_tensors="pt").to(device) outputs = model_dino(**inputs) image_features = outputs.last_hidden_state return image_features.mean(dim=1) #Create 2 indexes. index_clip = faiss.IndexFlatL2(512) index_dino = faiss.IndexFlatL2(768) #Iterate over the dataset to extract features X2 and store features in indexes for image_path in images: img = Image.open(image_path).convert('RGB') clip_features = extract_features_clip(img) add_vector_to_index(clip_features,index_clip) dino_features = extract_features_dino(img) add_vector_to_index(dino_features,index_dino) #store the indexes locally faiss.write_index(index_clip,"clip.index") faiss.write_index(index_dino,"dino.index")

パート2: 画像の類似性検索:

 import faiss import numpy as np import torch from transformers import AutoImageProcessor, AutoModel, AutoProcessor, CLIPModel from PIL import Image import os #Input image source='laptop.jpg' image = Image.open(source) device = torch.device('cuda' if torch.cuda.is_available() else "cpu") #Load model and processor DINOv2 and CLIP processor_clip = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") model_clip = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device) processor_dino = AutoImageProcessor.from_pretrained('facebook/dinov2-base') model_dino = AutoModel.from_pretrained('facebook/dinov2-base').to(device) #Extract features for CLIP with torch.no_grad(): inputs_clip = processor_clip(images=image, return_tensors="pt").to(device) image_features_clip = model_clip.get_image_features(**inputs_clip) #Extract features for DINOv2 with torch.no_grad(): inputs_dino = processor_dino(images=image, return_tensors="pt").to(device) outputs_dino = model_dino(**inputs_dino) image_features_dino = outputs_dino.last_hidden_state image_features_dino = image_features_dino.mean(dim=1) def normalizeL2(embeddings): vector = embeddings.detach().cpu().numpy() vector = np.float32(vector) faiss.normalize_L2(vector) return vector image_features_dino = normalizeL2(image_features_dino) image_features_clip = normalizeL2(image_features_clip) #Search the top 5 images index_clip = faiss.read_index("clip.index") index_dino = faiss.read_index("dino.index") #Get distance and indexes of images associated d_dino,i_dino = index_dino.search(image_features_dino,5) d_clip,i_clip = index_clip.search(image_features_clip,5)

結果

4 つの異なる画像を入力として使用して検索すると、次の結果が生成されました。

CLIP と DINOv2

この小さなサブセットでは、DINOv2 がわずかに優れたパフォーマンスを示しているようです。

DISC21データセットのベンチマーク

それぞれのパフォーマンスを比較するために、この記事で説明されているのと同じ方法論に従います: https://medium.com/aimonks/image-similarity-with-dinov2-and-faiss-741744bc5804。上記のスクリプトを繰り返して特徴を抽出し、画像の類似性を計算します。

データセット

CLIP と DINOv2 を比較するために、画像類似性検索用に特別に作成された DISC21 データセットを選択しました。サイズが 350 GB と大きいため、150,000 枚の画像のサブセットを使用します。

使用される指標

指標に関しては、次のことを計算します。

  • 精度: 正しく予測された画像の数と画像の総数の比率。
  • トップ 3 精度: 類似する上位 3 つの画像に正しい画像が見つかった回数と画像の総数の比率。
  • 計算時間: データセット全体を処理するために必要な時間。

ベンチマーク結果

(1)特徴抽出

  • CLIP: 1 秒あたり 70.7 枚の画像を処理
  • DINOv2: 1秒あたり69.7枚の画像を処理

(2)精度とトップ3の精度

精度とトップ3の精度

(3)分析結果

どちらのモデルも画像を正しく予測しました。

すべてのモデルが正しい画像を見つけることができませんでした:

CLIP のみが正しく画像を予測し、DINOv2 は上位 3 つを予測しました。

DINOv2 のみが正しく画像を予測しました:

分析する

DINOv2 は明らかにリードしており、明らかに難しいデータセットで 64% という驚異的な精度を達成しました。対照的に、CLIP は 28.45% というより控えめな精度を示しました。

計算効率の点では、両方のモデルは非常に類似した特徴抽出時間を示します。このバランスにより、この点でいずれかのモデルに明確な優位性がもたらされるわけではありません。

制限

このベンチマークは貴重な洞察を提供しますが、その限界を認識する必要があります。評価は、150,000 枚の画像のプールと比較した 1,448 枚の画像のサブセットに対して実行されます。データセット全体のサイズが 210 万枚の画像であることを考えると、リソースを節約するには焦点を絞る必要があります。

MetaAI が DISC21 データセットをモデルのベンチマークとして使用したことは注目に値します。これが DINOv2 に有利な点を与えた可能性があります。しかし、COCO データセットでのテストでは興味深い詳細が明らかになりました。DINOv2 は画像内の主要な要素を識別する機能が強化されており、CLIP は入力画像内の特定の詳細に焦点を当てる機能を示しています (バス画像を参照)。

最後に、CLIP と DINOv2 の埋め込み次元の違いを考慮する必要があります。 CLIP は 512 の埋め込み次元を使用しますが、DINOv2 は 768 を使用します。別のオプションとして、埋め込み寸法が一致するより大きな CLIP モデルを使用することがありますが、速度が犠牲になることに注意してください。小さなサブセットでの簡単なテストでは、わずかなパフォーマンスの向上が見られましたが、DINOv2 で実証されたパフォーマンス レベルには達しませんでした。

<<:  製造業における AI 活用事例 10 選

>>:  AIがデータ分析を拡張し、効率化する方法

ブログ    

推薦する

エッジコンピューティング時代の到来は AI にどのような影響を与えるのでしょうか?

[[270834]]近年、人工知能はテクノロジー界で注目されている分野です。中国では、Megvii...

...

...

...

...

ビッグデータがなくてもディープラーニングは可能でしょうか?中小企業のトレーニングのための新しいソリューション、大規模モデル

海外メディアの報道によると、AI専門家のアンドリュー・ン氏はIEEEに対し、ディープラーニングの今後...

大型モデルが最高95.8%の精度で「人肉検索」を実施!研究著者:OpenAIはGoogle Metaに注意喚起された

新しい研究(ETH チューリッヒによる)では次のことがわかりました。大規模モデルの「人間による検索」...

...

プログラマーの 90% が職を失いつつあり、Google AI によって書かれた機械学習コードはプログラマーよりも優れている!

ロボットはいくつの業界を置き換えることができるでしょうか? 初期の介護士から、後の編集者 (静かに悲...

AIが「迷惑メール」をフィルタリングし、ユーザーが価値あるメールを素早く見つけられるようにする

現在、世界中で毎日送信される 3,000 億通の電子メールのうち、少なくとも半分はスパムです。電子メ...

Reddit で話題: 言葉では言い表せない写真に透かしを追加することに特化したアプリが AI によって解読されました!

ベルギーの通信会社は、10代の若者向けに「.comdom」というセキュリティアプリをリリースした。こ...

いつ仕事を辞めるかを予測できる 9 つの AI 活用例

[51CTO.com 速訳] 人工知能は今や脂身の多い肉となり、誰もがそれを利用し、人工知能の真髄を...

ディープラーニングを用いた医療画像解析: ファイル形式

[[198733]]今年 3 月に開催された NVIDIA の GTC 2017 カンファレンスでは...

米商務省の新規制:承認なしに中国とセキュリティの脆弱性を共有することを禁止、マイクロソフトの異議は無効

最近、米国商務省産業安全保障局(BIS)は、サイバーセキュリティ分野に関する最新の輸出管理規制を正式...