ビジョン トランスフォーマー (ViT): トランスフォーマー モデルを使用したコンピューター ビジョン
過去数年にわたって、トランスフォーマーは機械学習における NLP ドメインを変革してきました。 GPT や BERT などのモデルは、人間の言語の理解と生成において新たなベンチマークを設定しました。現在、同じ原理がコンピュータ ビジョンの分野にも適用されています。 コンピューター ビジョンの分野における最近の開発は、ビジョン トランスフォーマー (ViT) です。論文「An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale」で詳しく説明されているように、ViT とトランスフォーマーベースのモデルは、畳み込みニューラル ネットワーク (CNN) を置き換えるように設計されています。 Vision Transformers は、コンピュータ ビジョンの問題を解決するための新しい考え方です。 ViT は、数十年にわたって画像関連タスクのバックボーンであった従来の畳み込みニューラル ネットワーク (CNN) に依存する代わりに、トランスフォーマー アーキテクチャを使用して画像を処理します。これらは画像パッチを文内の単語のように扱い、モデルがテキストの段落のコンテキストを学習するのと同じように、これらのパッチ間の関係を学習できるようにします。
CNN とは異なり、ViT は入力画像をパッチに分割し、ベクトルにシリアル化し、行列の乗算を使用して次元を削減します。次に、トランスフォーマー エンコーダーは、これらのベクトルをトークン埋め込みとして処理します。この記事では、ビジョン トランスフォーマーと、畳み込みニューラル ネットワークとの主な違いについて説明します。 CNN が特に興味深いのは、画像内の全体的なパターンを理解する能力です。これは CNN にとっては困難な点です。
前提条件
- ニューラル ネットワークの基礎: ニューラル ネットワークがデータを処理する方法について理解します。
- 畳み込みニューラル ネットワーク (CNN): CNN とコンピューター ビジョンにおける CNN の役割について理解します。
- トランスフォーマーのアーキテクチャ: トランスフォーマー、特に NLP での使用に関する知識。
- 画像処理: 画像表現、チャネル、ピクセル配列などの基本概念を理解します。
- 注意メカニズム: 自己注意と入力間の関係をモデル化するその能力を理解します。
ビジョントランスフォーマーとは何ですか?
ビジョン トランスフォーマーは、アテンションとトランスフォーマーの概念を使用して画像を処理します。これは、自然言語処理 (NLP) コンテキストにおけるトランスフォーマーに似ています。ただし、トークンを使用する代わりに、画像はパッチに分割され、一連の線形埋め込みとして提供されます。これらのパッチは、NLP でトークンまたは単語が処理されるのと同じ方法で処理されます。
ViT は全体像を同時に見るのではなく、ジグソーパズルのように画像を小さな断片に切り分けます。各ピースは、その特徴を説明する数値のリスト (ベクトル) に変換され、モデルはすべてのピースを調べ、変換メカニズムを使用してそれらが互いにどのように関連しているかを判断します。
CNN とは異なり、ViT は画像に特定のフィルターまたはカーネルを適用することで機能し、エッジ パターンなどの特定の特徴を検出します。これは、プリンタが画像をスキャンするのとよく似た畳み込みプロセスです。これらのフィルターは画像全体をスライドして、重要な特徴を強調表示します。その後、ネットワークはこれらのフィルターを複数の層に積み上げ、より複雑なパターンを徐々に特定します。
CNN では、プーリング層により特徴マップのサイズが削減されます。これらの層は、抽出された特徴を分析して、画像認識や物体検出などに役立つ予測を作成します。ただし、CNN の受容野は固定されているため、長距離の依存関係をモデル化する能力は制限されます。
CNN は画像をどのように表示しますか?
ViT は、より多くのパラメータを持っているにもかかわらず、セルフアテンション メカニズムを使用して特徴をより適切に表現し、より深い層の必要性を減らします。 CNN では同様の表現力を実現するために非常に深いアーキテクチャが必要となり、計算コストの増加につながります。
さらに、CNN のフィルターは画像の局所的な領域に焦点を当てているため、グローバル レベルの画像パターンをキャプチャすることはできません。画像全体や遠くの関係を理解するために、CNN は多くのレイヤーを積み重ねてプールし、視野を拡大することに依存します。ただし、このプロセスでは詳細を段階的に集約するため、グローバル情報が失われる可能性があります。
一方、ViT は、画像を個別の入力トークンとして扱われるパッチに分割します。 ViT は自己注意を使用してすべてのパッチを同時に比較し、それらがどのように関連しているかを学習します。これにより、レイヤーごとに構築することなく、イメージ全体のパターンと依存関係をキャプチャできるようになります。
誘導バイアスとは何ですか?
次に進む前に、誘導バイアスの概念を理解することが重要です。誘導バイアスとは、モデルがデータ構造に関して行う仮定を指します。これにより、トレーニング中にモデルがより一般化され、バイアスが軽減されます。 CNN では、帰納的バイアスには次のものが含まれます。
- 局所性: 画像内の特徴 (エッジやテクスチャなど) は小さな領域内に局在化されます。
- 二次元の近傍構造: 近くのピクセルは関連している可能性が高いため、フィルターは空間的に隣接する領域に作用します。
- 変換の等価性: エッジなど、画像のある部分で検出された特徴は、別の部分に現れても同じ意味を保持します。
CNN は本質的に画像の空間的および構造的特性を利用するように設計されているため、これらのバイアスにより、CNN は画像タスクに対して非常に効率的になります。
ビジョン トランスフォーマー (ViT) は、CNN よりも画像固有の誘導バイアスが大幅に少ないです。 ViT の場合:
- グローバル処理: セルフ アテンション レイヤーは画像全体に作用し、モデルがローカル領域に制限されることなくグローバルな関係と依存関係をキャプチャできるようにします。
- 最小限の 2D 構造: 画像の 2D 構造は、最初 (画像がパッチに分割されるとき) と微調整中 (さまざまな解像度の位置埋め込みを調整するため) にのみ使用されます。 CNN とは異なり、ViT は近くのピクセルが必ずしも関連しているとは想定しません。
- 学習された空間関係: ViT の位置埋め込みは、初期化時に特定の 2D 空間関係をエンコードしません。代わりに、モデルはトレーニング中にデータからすべての空間関係を学習します。
ビジョントランスフォーマーの仕組み
Vision Transformers は、1D テキスト シーケンス用に開発された標準の Transformer アーキテクチャを使用します。 2D 画像を処理するには、P P ピクセルなどの固定サイズの小さなパッチに分割し、ベクトルに平坦化します。画像の寸法が H W で C チャネルの場合、パッチの総数は N=H W/P P になります。これは、トランスフォーマーの有効な入力シーケンス長です。これらの平坦化されたパッチは、パッチ埋め込みと呼ばれる固定次元空間 D に線形投影されます。
BERT の [CLS] トークンに似た特別な学習可能なトークンが、一連のパッチ埋め込みの先頭に追加されます。このトークンは、後で分類に使用されるグローバルな画像表現を学習します。さらに、位置エンベディングがパッチ エンベディングに追加されて位置情報がエンコードされ、モデルが画像の空間構造を理解するのに役立ちます。
エンベディングのシーケンスは Transformer エンコーダーを通過し、 Transformer エンコーダーは、マルチヘッド セルフ アテンション (MSA) と MLP ブロックとも呼ばれるフィードフォワード ニューラル ネットワークという 2 つの主要な操作を交互に行います。各層には、これらの操作の前に適用される層正規化(LN)と、トレーニングを安定させるために後に追加される残留接続が含まれています。 Transformer エンコーダーの出力、特に [CLS] トークンの状態は、画像の表現として使用されます。
分類タスクのために、最終的な [CLS] トークンに単純なヘッドが追加されます。事前トレーニング中、このヘッドは小型の多層パーセプトロン (MLP) ですが、微調整中は通常、単一の線形層です。このアーキテクチャにより、ViT はパッチ間のグローバルな関係を効果的にモデル化し、自己注意力を最大限に活用して画像を理解できるようになります。
ハイブリッド Vision Transformer モデルでは、生の画像をパッチに直接分割するのではなく、CNN によって生成された特徴マップから入力シーケンスが導出されます。 CNN は最初に画像を処理して意味のある空間特徴を抽出し、それを使用してパッチを作成します。これらのパッチは平坦化され、標準のビジョン トランスフォーマーと同じトレーニング可能な線形投影を使用して固定次元空間に投影されます。このアプローチの特殊なケースは、サイズ 1×1 のパッチを使用することであり、各パッチは CNN の特徴マップ内の単一の空間位置に対応します。
この場合、特徴マップの空間次元が平坦化され、結果として得られるシーケンスが Transformer の入力次元に投影されます。標準の ViT と同様に、位置情報を保持し、グローバルな画像の理解を可能にするために、分類トークンと位置埋め込みが追加されます。このハイブリッド アプローチは、CNN のローカル特徴抽出の強みを活用しながら、Transformer のグローバル モデリング機能と組み合わせます。
コードデモ
これは、画像上でビジョン トランスフォーマーを使用する方法のコード ブロックです。
# Install the necessary libraries
pip install -q transformers
from transformers import ViTForImageClassification
from PIL import Image
from transformers import ViTImageProcessor
import requests
import torch
# Load the model and move it to ‘GPU’
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224')
model.to(device)
# Load the image to perform predictions
url = 'link to your image'
image = Image.open(requests.get(url, stream=True).raw)
processor = ViTImageProcessor.from_pretrained('google/vit-base-patch16-224')
inputs = processor(images=image, return_tensors="pt").to(device)
pixel_values = inputs.pixel_values print(pixel_values.shape)
ViT モデルは画像を処理します。これは、BERT のようなエンコーダーと、[CLS] トークンの最終的な隠れ状態の上部に位置する線形分類ヘッドで構成されます。
with torch.no_grad():
outputs = model(pixel_values)
logits = outputs.logits
logits.shape
prediction = logits.argmax(-1)
print("Predicted class:", model.config.id2label[prediction.item()])
ここでは、PyTorch を使用した基本的な Vision Transformer (ViT) の実装を示します。このコードには、パッチの埋め込み、位置エンコーディング、Transformer エンコーダーなどのコア コンポーネントが含まれています。これは、単純な分類タスクに使用できます。
import torch
import torch.nn as nn
import torch.nn.functional as F
class VisionTransformer(nn.Module):
def __init__(self, img_size=224, patch_size=16, num_classes=1000, dim=768, depth=12, heads=12, mlp_dim=3072, dropout=0.1):
super(VisionTransformer, self).__init__()
# Image and patch dimensions
assert img_size % patch_size == 0, "Image size must be divisible by patch size"
self.num_patches = (img_size // patch_size) ** 2
self.patch_dim = (3 * patch_size ** 2) # Assuming 3 channels (RGB)
# Layers
self.patch_embeddings = nn.Linear(self.patch_dim, dim)
self.position_embeddings = nn.Parameter(torch.randn(1, self.num_patches + 1, dim))
self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
self.dropout = nn.Dropout(dropout)
# Transformer Encoder
self.transformer = nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model=dim, nhead=heads, dim_feedforward=mlp_dim, dropout=dropout),
num_layers=depth
)
# MLP Head for classification
self.mlp_head = nn.Sequential(
nn.LayerNorm(dim),
nn.Linear(dim, num_classes)
)
def forward(self, x):
# Flatten patches and embed
batch_size, channels, height, width = x.shape
patch_size = height // int(self.num_patches ** 0.5)
x = x.unfold(2, patch_size, patch_size).unfold(3, patch_size, patch_size)
x = x.contiguous().view(batch_size, 3, patch_size, patch_size, -1)
x = x.permute(0, 4, 1, 2, 3).flatten(2).permute(0, 2, 1)
x = self.patch_embeddings(x)
# Add positional embeddings
cls_tokens = self.cls_token.expand(batch_size, -1, -1)
x = torch.cat((cls_tokens, x), dim=1)
x = x + self.position_embeddings
x = self.dropout(x)
# Transformer Encoder
x = self.transformer(x)
# Classification Head
x = x[:, 0] # CLS token
return self.mlp_head(x)
Example usage
if __name__ == "__main__":
model = VisionTransformer(img_size=224, patch_size=16, num_classes=10, dim=768, depth=12, heads=12, mlp_dim=3072)
print(model)
dummy_img = torch.randn(8, 3, 224, 224) # Batch of 8 images, 3 channels, 224x224 size
preds = model(dummy_img)
print(preds.shape) # Output: [8, 10] (Batch size, Number of classes)
主要コンポーネント:
- パッチの埋め込み: 画像は小さなパッチに分割され、平坦化され、埋め込みに線形変換されます。
- 位置エンコーディング: トランスフォーマーは位置に依存しないため、位置情報がパッチの埋め込みに追加されます。
- トランスフォーマー エンコーダー: セルフ アテンション レイヤーとフィードフォワード レイヤーを適用して、パッチ間の関係を学習します。
- 分類ヘッド: CLS トークンを使用してクラス確率を出力します。
Adam などのオプティマイザーやクロスエントロピーなどの損失関数を使用して、任意の画像データセットでこのモデルをトレーニングできます。パフォーマンスを向上させるには、微調整する前に大規模なデータセットでの事前トレーニングを検討してください。
人気の続編作品
-
Facebook AI によるDeiT (Data-efficient Image Transformers): これらは、知識の蒸留によって効率的にトレーニングされたビジョン トランスフォーマーです。 DeiT は、deit-tiny モデル、deit-small モデル、および 2 つのdeit-base モデルの 4 つのバリエーションを提供します。
DeiTImageProcessor
を使用して画像を準備します。 Microsoft Research によるBEiT (画像変換の BERT 事前トレーニング): BERT からインスピレーションを得た BEiT は、自己教師ありマスク イメージ モデリングを使用し、教師あり ViT よりも優れたパフォーマンスを発揮します。トレーニングには VQ-VAE を使用します。
Facebook AI によるDINO (自己監視型ビジョン トランスフォーマー トレーニング): DINO でトレーニングされた ViT は、明示的なトレーニングなしでオブジェクトをセグメント化できます。チェックポイントはオンラインで利用できます。
Facebook によるMAE (マスクされたオートエンコーダー) は、マスクされたパッチ (75%) を再構築することによって ViT を事前トレーニングします。このシンプルな方法を微調整すると、教師付き事前トレーニングを上回ります。
結論
結論として、ViT は画像認識にトランスフォーマーを適用し、誘導バイアスを最小限に抑え、画像をシーケンス パッチとして扱うため、CNN の優れた代替手段となります。このシンプルかつスケーラブルなアプローチは、特に大規模なデータセットでの事前トレーニングと組み合わせた場合に、多くの画像分類ベンチマークで最先端のパフォーマンスを実証しています。ただし、物体検出やセグメンテーションなどのタスクへの ViT の拡張、自己教師付き事前トレーニング方法のさらなる改善、パフォーマンスをさらに向上させるための ViT のスケーリングの可能性の探求など、潜在的な課題は残っています。
追加リソース
- ビジョントランスフォーマー (ViT)
- 画像は 16X16 ワードの価値があります: 大規模な画像認識のためのトランスフォーマー
- PyTorch で CNN を最初から作成する