メタAIのもう一つの革命的な大規模モデル — 画像特徴抽出のためのDINOv2

DINOv2 Another revolutionary large-scale model of meta AI for image feature extraction.

DINOv2は、画像特徴抽出のための最高の自己教示ViTベースのDLモデルの1つです

イントロダクション

Mete AIは、画像から視覚的な特徴を自動的に抽出する新しいバージョンの画像特徴抽出モデルDINOv2を発表しました。これは、データとモデルのスケーリングに関して、特にコンピュータビジョン領域でAI分野におけるもう一つの革命的な進歩です。

ai.facebook.comによるDINOv2のデモ

動機-なぜ私たちは気にする必要があるのでしょうか?

DINOv2は、微調整を必要とせずに優れたパフォーマンスを発揮する自己教示モデルです。さらに、以下の多数のコンピュータビジョンタスクのバックボーンとして使用することができます:

  • 分類、細分類-例えば、猫対犬、犬種の識別など
  • 画像検索-例えば、インターネット上の大量の画像から自分のバッグに似たバッグを見つける。
  • 意味的画像セグメンテーション-画像内の各ピクセルにラベルまたはカテゴリを関連付けます。
  • ビデオ理解-オブジェクト、アクション、イベント、シーン、さらにはより高レベルの概念など、ビデオの様々な側面を自動的に認識および解釈します。
  • 単眼深度推定-画像内のオブジェクトが前景にあるか背景にあるかを予測します。
  • 画像クラスタリング-同じクラスタ内の画像が互いに類似しているように画像をグループ化します。
  • コンテンツベースのレコメンデーションシステム-画像の表現に基づいてユーザーにアイテムを推奨します。

DINOv2は、Segment Anythingをはじめとする最近のコンピュータビジョンの研究を補完します。Segment Anythingは、多様なセグメンテーションタスクに対するゼロショットの汎用性に焦点を当てたプロンプト可能なセグメンテーションシステムです。

私の前の投稿にて、Segment Anything Model (SAM)をご覧いただけます。

Meta AIが1億枚のマスクでトレーニングされた革命的な画像セグメンテーションモデルを発表

セグメントアニシングモデル(SAM)-画像セグメンテーションのための最高のDLモデル

towardsdatascience.com

方法論

論文の主な貢献は以下の通りです:

  • 大規模でキュレーションされたトレーニングデータセットの作成
  • トレーニングアルゴリズムと実装の改善
  • 機能的な蒸留パイプラインの設計

大規模でキュレーションされたトレーニングデータセットの作成

大規模なディープラーニングモデルには大量のトレーニングデータが必要です。そのため、著者らは以下のフィギュアに示す自動パイプラインを作成してキュレーションされたトレーニングデータセットを取得しました。

キュレーションされた画像作成のワークフロー[1]

彼らは、約25のサードパーティデータセットのコレクションから一連のシード画像を選択し、このシード画像を拡張することを目的としました。ここでの作業のやり方は次のとおりです。まず、彼らはインターネットから大量の非キュレーションされた画像(約12億枚のユニークな画像)をスクレイプしました。その後、ImageNet-22kで事前にトレーニングされた自己教示ViT-H/16ネットワークを使用して画像の埋め込みを作成しました。次に、画像間の余弦類似度を距離測度として使用して重複画像をフィルタリングし、冗長性を減らし多様性を増やしました。重複した画像が大規模な非キュレーションされたデータセットから削除された後、キュレーションされた画像に似た画像を抽出する画像検索ステージを実行しました。最終的に、この方法により、12億枚の非キュレーションされた画像データベースから1億4200万枚のキュレーションされた画像を作成することができました。

トレーニングアルゴリズムの改善

DINOv2は、スチューデント-ティーチャーメカニズムを使用しています。これは、より小さなニューラルネットワーク(スチューデント)が、より大きくまたは複雑なニューラルネットワーク(ティーチャー)の動作を模倣するように学習するトレーニング技術です。スチューデントとティーチャーは、Vision Transformerアーキテクチャ(ViT)[2]に基づいています。損失に関して、スチューデント-ティーチャーの特徴の類似性に対してクロスエントロピー損失を使用しています。画像のローカルおよびグローバルな特徴を学習するために、異なるレベルの学習を使用しました。グローバルな学習については、同じ画像に対するランダムクロップデータ拡張を使用しました。ローカル特徴学習については、入力パッチにランダムにマスクを適用することで、スチューデントに適用し、ティーチャーには適用しないパッチレベル学習を使用しました。さらに、Sinkhorn-knopバッチ正規化などの異なる正規化技術を実行しました。詳細については、論文を参照してください。

蒸留パイプライン。

大規模なモデルを使用して予測(推論)を行う場合、強力なハードウェアが必要です。この制限を克服するために、彼らは大規模なモデルを小さなモデルに圧縮しました。知識蒸留[5]は、与えられた入力セットの両方の出力間のいくつかの距離を最小化することによって、大規模なモデルの出力を小さなモデルで再現することを目的としています。トレーニングアルゴリズムは、大型モデルを小型モデルに簡単に圧縮できる自己蒸留に基づいています。

結果

彼らは、8つの異なるコンピュータービジョンタスクでモデルのパフォーマンスを評価し、他の方法と比較しました。

以下のグラフでは、DINOv2モデルの結果は濃い青色で、他の自己監督方法は薄いオレンジ色で、弱監督方法は濃いピンク色で強調されています。破線の水平線は最も優れた弱監督モデルです。

結果は、DINOv2モデルが自己監督学習の先端技術を大幅に改善し、弱監督機能と比較可能なパフォーマンスに達したことを示しています。

DINOv2 vs other SOTA models [1]

結論

要約すると、DINOv2はMeta AIチームからの別の革命的なモデルです。微調整を必要とせず、さまざまなコンピュータービジョンモデルのバックボーンとして使用できます。 DINOv2は、自己監督メカニズムを使用し、任意の画像コレクションから学習できます。

DINOv2デモ-ファイングレインド画像分類

この部分では、DINOv2が実際のケースシナリオでどのように機能するかをデモンストレーションしようと思います。ファイングレインド画像分類タスクを作成します。

分類ワークフロー:

  • PyTorchデータセットからFood101データセットをダウンロードします。
  • 小さなDINOv2からトレインとテストデータセットから特徴を抽出します
  • 抽出したトレーニングデータセットの特徴を使用してML分類器モデル(SVM、XGBoost、KNN)をトレーニングします。
  • テストデータセットから抽出された特徴に基づいて予測を行います。
  • 各MLモデルの精度とF1スコアを評価します。

データ:Food 101は、101,000枚の画像を持つ101の食品カテゴリの難しいデータセットです。各クラスには、250の手動レビューされたテスト画像と750のトレーニング画像が用意されています。

モデル:小さなDINOv2モデル(ViT-S/14 distilled)

MLモデル:SVM、XGBoost、KNN。

ステップ1-設定(Google Colabを使用してコードを実行し、GPUをオンにできます)

import torchimport numpy as npimport torchvisionfrom torchvision import transformsfrom torch.utils.data import Subset, DataLoaderimport matplotlib.pyplot as pltimport timeimport osimport randomfrom tqdm import tqdmfrom xgboost import XGBClassifierfrom sklearn.svm import SVCfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.metrics import accuracy_score, f1_scoreimport pandas as pddef set_seed(no):    torch.manual_seed(no)    random.seed(no)    np.random.seed(no)    os.environ['PYTHONHASHSEED'] = str()    torch.backends.cudnn.benchmark = False    torch.backends.cudnn.deterministic = Trueset_seed(100)

ステップ2-変換の作成、Food101 Pytorchデータセットのダウンロードと作成、トレーニングおよびテストデータローダーオブジェクトの作成

batch_size = 8transformation = transforms.Compose([        transforms.Resize(256),        transforms.CenterCrop(224),        transforms.ToTensor(),        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])    ])trainset = torchvision.datasets.Food101(root='./data', split='train',                                        download=True, transform=transformation)testset = torchvision.datasets.Food101(root='./data', split='test',                                       download=True, transform=transformation)# train_indices = random.sample(range(len(trainset)), 20000)# test_indices = random.sample(range(len(testset)), 5000)# trainset = Subset(trainset, train_indices)# testset  = Subset(testset, test_indices)trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,                                          shuffle=True)testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,                                         shuffle=False)classes = trainset.classesprint(len(trainset), len(testset))print(len(trainloader), len(testloader))

[出力] 75750 25250

[出力] 9469 3157

ステップ3(オプション)— トレーニングデータローダーバッチの可視化

# 画像のバッチを取得dataiter = iter(trainloader)images, labels = next(dataiter)# 画像をプロットfig, axes = plt.subplots(1, len(images),figsize=(12,12))for i, ax in enumerate(axes):    # テンソル画像をnumpy形式に変換    image = images[i].numpy()    image = image.transpose((1, 2, 0))  # (高さ、幅、チャンネル)に転置    # 画像を正規化    mean = [0.485, 0.456, 0.406]    std = [0.229, 0.224, 0.225]    normalized_image = (image * std) + mean    # 画像を表示    ax.imshow(normalized_image)    ax.axis('off')    ax.set_title(f'ラベル:{labels[i]}')# プロットを表示plt.show()
batch of images

ステップ4 — 小規模なDINOv2モデルをロードし、トレーニングデータローダーとテストデータローダーから特徴量を抽出する。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")dinov2_vits14 = torch.hub.load('facebookresearch/dinov2', 'dinov2_vits14').to(device)#トレーニングtrain_embeddings = []train_labels = []dinov2_vits14.eval()with torch.no_grad():  for data, labels in tqdm(trainloader):    image_embeddings_batch = dinov2_vits14(data.to(device))    train_embeddings.append(image_embeddings_batch.detach().cpu().numpy())    train_labels.append(labels.detach().cpu().numpy())#テストtest_embeddings = []test_labels = []dinov2_vits14.eval()with torch.no_grad():  for data, labels in tqdm(testloader):    image_embeddings_batch = dinov2_vits14(data.to(device))    test_embeddings.append(image_embeddings_batch.detach().cpu().numpy())    test_labels.append(labels.detach().cpu().numpy())#結果を連結train_embeddings_f = np.vstack(train_embeddings)train_labels_f = np.concatenate(train_labels).flatten()test_embeddings_f = np.vstack(test_embeddings)test_labels_f = np.concatenate(test_labels).flatten()train_embeddings_f.shape, train_labels_f.shape, test_embeddings_f.shape, test_labels_f.shape

[出力] ((75750, 384), (75750,), (25250, 384), (25250,))

ステップ5 — SVM、XGBoost、KNN分類器のための関数を構築する。

def evaluate_classifiers(X_train, y_train, X_test, y_test):    # サポートベクターマシン(SVM)    svm_classifier = SVC()    svm_classifier.fit(X_train, y_train)    svm_predictions = svm_classifier.predict(X_test)    # XGBoost分類器    xgb_classifier = XGBClassifier(tree_method='gpu_hist')    xgb_classifier.fit(X_train, y_train)    xgb_predictions = xgb_classifier.predict(X_test)    # k近傍(KNN)分類器    knn_classifier = KNeighborsClassifier()    knn_classifier.fit(X_train, y_train)    knn_predictions = knn_classifier.predict(X_test)    # Top-1を計算する    top1_svm = accuracy_score(y_test, svm_predictions)    top1_xgb = accuracy_score(y_test, xgb_predictions)    top1_knn = accuracy_score(y_test, knn_predictions)    # F1スコアを計算する    f1_svm = f1_score(y_test, svm_predictions, average='weighted')    f1_xgb = f1_score(y_test, xgb_predictions, average='weighted')    f1_knn = f1_score(y_test, knn_predictions, average='weighted')    return pd.DataFrame({        'SVM': {'Top-1 Accuracy': top1_svm, 'F1 Score': f1_svm},        'XGBoost': {'Top-1 Accuracy': top1_xgb,'F1 Score': f1_xgb},        'KNN': {'Top-1 Accuracy': top1_knn, 'F1 Score': f1_knn}    })X_train = train_embeddings_f  # トレーニングデータの特徴y_train = train_labels_f  # トレーニングデータのラベルX_test = test_embeddings_f   # テストデータの特徴y_test = test_labels_f   # テストデータのラベルresults = evaluate_classifiers(X_train, y_train, X_test, y_test)print(results)

結果

Result of small DINOv2 + SVM/XGBoost/KNN (image by the author)

すごい、結果は素晴らしいです!小さいDINOv2から抽出された特徴量に基づいてトレーニングされたSVMモデルが、他のMLモデルを凌駕し、ほぼ90%の精度を達成しました。

結論

小さいDINOv2モデルを使用して特徴量を抽出しましたが、抽出された特徴量に基づいてトレーニングされたMLモデル(特にSVM)は、ファイングレインド分類タスクで素晴らしいパフォーマンスを発揮しました。101の異なるクラスのオブジェクトをほぼ90%の精度で分類できます。

精度は、big、large、giant DINOv2モデルを使用すると改善されます。ステップ4のdinov2_vits14をdinov2_vitb14、dinov2_vitl14、またはdinov2_vitg14に変更するだけで、試して、コメントセクションで精度の結果を自由に共有してください 🙂

楽しんでいただけたら幸いです。この記事に関する質問やご意見がある場合は、コメントしていただければ幸いです。

私の作品を直接サポートし、VoAGIの記事に無制限にアクセスするには、こちらの紹介リンクを使用してVoAGIメンバーになってください。何百万回もありがとうございます、素晴らしい一日を!

VoAGIメンバーとして、あなたの会費の一部があなたが読んだ作家に支払われ、すべてのストーリーに完全にアクセスできます…

VoAGI.com

参考文献

[1] Oquab, M., Darcet, T., Moutakanni, T., Vo, H., Szafraniec, M., Khalidov, V., … & Bojanowski, P. (2023). Dinov2: Learning robust visual features without supervision. arXiv preprint arXiv:2304.07193 .

[2] Dosovitskiy, A., Beyer, L., Kolesnikov, A., Weissenborn, D., Zhai, X., Unterthiner, T., … & Houlsby, N. (2020). An image is worth 16×16 words: Transformers for image recognition at scale. arXiv preprint arXiv:2010.11929 .ISO 690

[3] The DINOv2 team, DINOv2: State-of-the-art computer vision models with self-supervised learning

[4] DINOv2 Github

[5] Hinton, G., Vinyals, O., & Dean, J. (2015). Distilling the knowledge in a neural network. arXiv preprint arXiv:1503.02531 .

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more