- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- 1. 画像の基礎: ピクセル、チャンネル、畳み込み
- 2. CNNアーキテクチャの発展史
- 3. 物体検出: YOLO、DETR、Faster R-CNN
- 4. セグメンテーション: DeepLab、Mask R-CNN、SAM
- 5. Vision Transformer: ViT、Swin、DINOv2
- 6. 生成モデル: GAN、Diffusion、ControlNet
- 7. 実践パイプライン: DataLoaderからTensorRTまで
- クイズ: コンピュータービジョンの深い理解
- まとめ: 学習ロードマップ
はじめに
コンピュータービジョン(Computer Vision)は、機械が画像や動画を「理解」するAIのコア分野です。スマートフォンの顔認証、自動運転車の障害物認識、医療画像診断支援——これらすべてにコンピュータービジョン技術が使われています。
このガイドではピクセルレベルの基礎から最新のVision Transformer、Stable Diffusionまで、PyTorchコード例を交えながら体系的に解説します。
1. 画像の基礎: ピクセル、チャンネル、畳み込み
1.1 デジタル画像の構造
デジタル画像はピクセル(pixel)の2Dグリッドです。
- グレースケール画像: H x W 形状の2D配列、各ピクセル値は0〜255
- カラー画像(RGB): H x W x 3 形状の3Dテンソル、各チャンネル0〜255
- 解像度: 画像サイズ(例: 1920x1080)、ピクセル密度(DPI)
import torch
import torchvision.transforms as T
from PIL import Image
# 画像の読み込みとテンソル変換
img = Image.open("sample.jpg").convert("RGB")
transform = T.Compose([
T.Resize((224, 224)),
T.ToTensor(), # [0,255] -> [0.0,1.0], HWC -> CHW
T.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
tensor = transform(img) # shape: [3, 224, 224]
print(f"Shape: {tensor.shape}, dtype: {tensor.dtype}")
1.2 畳み込みと主なフィルター
畳み込み(Convolution)は小さなカーネル(フィルター)を画像全体にスライドさせて特徴を抽出します。
import torch
import torch.nn.functional as F
# 3x3 Sobelエッジ検出カーネル(水平方向)
kernel = torch.tensor([
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]
], dtype=torch.float32).unsqueeze(0).unsqueeze(0) # [1, 1, 3, 3]
# グレースケール画像に畳み込みを適用
gray_tensor = T.ToTensor()(T.Grayscale()(img)).unsqueeze(0)
edges = F.conv2d(gray_tensor, kernel, padding=1)
| カーネルの種類 | 目的 | 活用例 |
|---|---|---|
| Sobel | エッジ検出(水平/垂直) | 自動運転の車線認識 |
| Gaussian | ブラリング、ノイズ除去 | 画像前処理 |
| Laplacian | エッジ強調 | 先鋭化 |
| Average | 平均ブラー | ダウンサンプリング |
1.3 Albumentationsデータ拡張パイプライン
import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
train_transform = A.Compose([
A.RandomResizedCrop(224, 224, scale=(0.7, 1.0)),
A.HorizontalFlip(p=0.5),
A.ColorJitter(brightness=0.4, contrast=0.4,
saturation=0.4, hue=0.1, p=0.8),
A.GaussianBlur(blur_limit=(3, 7), p=0.2),
A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.1,
rotate_limit=15, p=0.5),
A.Normalize(mean=(0.485, 0.456, 0.406),
std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
image = cv2.cvtColor(cv2.imread("sample.jpg"), cv2.COLOR_BGR2RGB)
augmented = train_transform(image=image)["image"]
2. CNNアーキテクチャの発展史
2.1 主要アーキテクチャの年表
| 年 | アーキテクチャ | 主な貢献 | ImageNet Top-1 |
|---|---|---|---|
| 1998 | LeNet-5 | 最初の実用的CNN、畳み込み+プーリング構造 | - |
| 2012 | AlexNet | ReLU、Dropout、GPU学習 | 63.3% |
| 2014 | VGGNet | 3x3カーネルを深く積み重ね | 74.4% |
| 2015 | ResNet-50 | スキップ接続、残差学習 | 76.0% |
| 2017 | DenseNet | 全レイヤーの直接接続 | 77.4% |
| 2019 | EfficientNet-B7 | 複合スケーリング | 84.4% |
| 2022 | ConvNeXt-L | TransformerのCNN設計原則を適用 | 86.6% |
2.2 ResNet: 残差学習の革命
ResNetの核心は**スキップ接続(残差接続)**です。入力xを出力に直接加算することで勾配消失問題を解決します。残差ブロックの出力F(x) + xを微分するとdF/dx + 1となり、最小勾配1が常に保証されます。
import torch
import torch.nn as nn
import torchvision.models as models
class ResNetClassifier(nn.Module):
def __init__(self, num_classes: int, pretrained: bool = True):
super().__init__()
weights = models.ResNet50_Weights.IMAGENET1K_V2 if pretrained else None
self.backbone = models.resnet50(weights=weights)
in_features = self.backbone.fc.in_features
self.backbone.fc = nn.Sequential(
nn.Dropout(0.3),
nn.Linear(in_features, num_classes)
)
def forward(self, x):
return self.backbone(x)
def train_one_epoch(model, loader, optimizer, criterion, device):
model.train()
total_loss, correct = 0.0, 0
for images, labels in loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item() * images.size(0)
correct += (outputs.argmax(1) == labels).sum().item()
return total_loss / len(loader.dataset), correct / len(loader.dataset)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = ResNetClassifier(num_classes=10).to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-2)
criterion = nn.CrossEntropyLoss()
2.3 EfficientNet: 複合スケーリング
EfficientNetは**幅(width)、深さ(depth)、解像度(resolution)**を一緒にスケーリングする複合係数(compound coefficient)を導入しました。
import timm
# EfficientNet-B4のファインチューニング
model = timm.create_model(
"efficientnet_b4",
pretrained=True,
num_classes=100,
drop_rate=0.3
)
# バックボーンを固定(特徴抽出モード)
for name, param in model.named_parameters():
if "classifier" not in name:
param.requires_grad = False
2.4 ConvNeXt: CNNの近代化
ConvNeXtはTransformerの設計原則(大きなカーネル、LayerNorm、GELU、少ない活性化関数)をpure CNNに適用し、Swin Transformerと同等の性能を達成しました。
model = timm.create_model(
"convnext_large",
pretrained=True,
num_classes=1000
)
# 7x7 depthwise conv、LayerNorm、GELU活性化を使用
3. 物体検出: YOLO、DETR、Faster R-CNN
3.1 検出アプローチの比較
| アプローチ | モデル | 速度 | 精度 | 特徴 |
|---|---|---|---|---|
| Anchor-based 2-stage | Faster R-CNN | 遅い | 高い | RPN+分類器の分離 |
| Anchor-based 1-stage | YOLOv8 | 速い | 中〜高 | シングルパス推論 |
| Anchor-free 1-stage | YOLOv10、FCOS | 非常に速い | 高い | NMS不要、アンカー不要 |
| Transformer | DETR | 中程度 | 高い | エンドツーエンド、関係モデリング |
3.2 YOLOv8の実践的使用法
from ultralytics import YOLO
# 事前学習済みモデルの読み込み
model = YOLO("yolov8n.pt") # nano: 速度優先
# model = YOLO("yolov8x.pt") # extra-large: 精度優先
# 単一画像の推論
results = model("image.jpg", conf=0.25, iou=0.45)
for result in results:
for box in result.boxes:
cls = int(box.cls[0])
conf = float(box.conf[0])
x1, y1, x2, y2 = box.xyxy[0].tolist()
print(f"Class: {result.names[cls]}, Conf: {conf:.2f}")
# カスタムデータセットでのファインチューニング
model.train(
data="custom.yaml",
epochs=100,
imgsz=640,
batch=16,
lr0=0.01,
device=0
)
# 評価
metrics = model.val()
print(f"mAP50: {metrics.box.map50:.3f}")
print(f"mAP50-95: {metrics.box.map:.3f}")
3.3 YOLOv10: NMS不要の検出
YOLOv10はNon-Maximum Suppression(NMS)の後処理を排除し、**二重ラベル割り当て(dual label assignment)**と一貫性マッチングによってエンドツーエンドの学習を実現しました。
from ultralytics import YOLO
model = YOLO("yolov10n.pt")
# NMSなしで最終結果を直接返す — 低レイテンシ
results = model.predict("video.mp4", stream=True)
for frame_result in results:
print(frame_result.boxes)
3.4 DETR: Detection Transformer
DETRは二部マッチングロスを用いて、アンカーとNMSなしでボックスの最終セットを直接予測します。
import torch
from transformers import DetrImageProcessor, DetrForObjectDetection
from PIL import Image
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
img = Image.open("image.jpg")
inputs = processor(images=img, return_tensors="pt")
outputs = model(**inputs)
target_sizes = torch.tensor([img.size[::-1]])
results = processor.post_process_object_detection(
outputs, target_sizes=target_sizes, threshold=0.9
)[0]
for score, label, box in zip(
results["scores"], results["labels"], results["boxes"]
):
name = model.config.id2label[label.item()]
print(f"{name}: {score:.3f} at {[round(i, 2) for i in box.tolist()]}")
4. セグメンテーション: DeepLab、Mask R-CNN、SAM
4.1 セグメンテーションの種類
- セマンティック(Semantic): ピクセルごとにクラスラベルを付与(車、道路、空など)
- インスタンス(Instance): 同じクラスの個別オブジェクトを区別(車1、車2など)
- パノプティック(Panoptic): セマンティック+インスタンスの統合
4.2 SAM: Segment Anything Model
MetaのSAMは**プロンプト(点、ボックス、マスク)**を受け取り、任意のオブジェクトをゼロショットでセグメンテーションします。Image Encoder(ViT-H)、Prompt Encoder、Mask Decoderの3モジュール構造で、SA-1Bデータセット(10億マスク)で学習された汎用セグメンテーションモデルです。
import torch
import numpy as np
import cv2
from segment_anything import sam_model_registry, SamPredictor
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
sam.to("cuda")
predictor = SamPredictor(sam)
# 画像の設定
image = cv2.cvtColor(cv2.imread("image.jpg"), cv2.COLOR_BGR2RGB)
predictor.set_image(image)
# ポイントプロンプトによるセグメンテーション
input_point = np.array([[500, 375]]) # クリック位置 (x, y)
input_label = np.array([1]) # 1=前景、0=背景
masks, scores, logits = predictor.predict(
point_coords=input_point,
point_labels=input_label,
multimask_output=True # 複数のマスク候補を返す
)
best_mask = masks[scores.argmax()]
print(f"Mask shape: {best_mask.shape}, Score: {scores.max():.3f}")
# ボックスプロンプトによるセグメンテーション
input_box = np.array([100, 100, 400, 400])
masks_box, _, _ = predictor.predict(
box=input_box[None, :],
multimask_output=False
)
4.3 DeepLabV3+のセマンティックセグメンテーション
DeepLabV3+はASPP(Atrous Spatial Pyramid Pooling)でマルチスケールのコンテキスト情報を捉えます。
import torch
import torchvision.models.segmentation as seg_models
model = seg_models.deeplabv3_resnet101(
weights=seg_models.DeepLabV3_ResNet101_Weights.COCO_WITH_VOC_LABELS_V1
)
model.eval()
with torch.no_grad():
output = model(tensor.unsqueeze(0))["out"] # [1, num_classes, H, W]
pred = output.argmax(dim=1).squeeze() # [H, W]
print(f"セグメンテーションマップ shape: {pred.shape}")
4.4 Mask R-CNNのインスタンスセグメンテーション
from torchvision.models.detection import maskrcnn_resnet50_fpn_v2
from torchvision.models.detection import MaskRCNN_ResNet50_FPN_V2_Weights
from torchvision.utils import draw_segmentation_masks
import torchvision.transforms.functional as TF
from PIL import Image
weights = MaskRCNN_ResNet50_FPN_V2_Weights.DEFAULT
model = maskrcnn_resnet50_fpn_v2(weights=weights, box_score_thresh=0.75)
model.eval()
img = Image.open("people.jpg").convert("RGB")
inp = weights.transforms()(img).unsqueeze(0)
with torch.no_grad():
predictions = model(inp)
pred = predictions[0]
masks = (pred["masks"] > 0.5).squeeze(1)
img_uint8 = (TF.to_tensor(img) * 255).byte()
result = draw_segmentation_masks(img_uint8, masks, alpha=0.5)
5. Vision Transformer: ViT、Swin、DINOv2
5.1 ViTの核心原理
ViT(Vision Transformer)は画像を**固定サイズのパッチ(16x16)**に分割し、各パッチをトークンとしてTransformerに入力します。CNNと異なり、局所的なinductive biasなしにグローバルな関係を学習します。
import timm
import torch
# ViT-Base/16のファインチューニング
model = timm.create_model(
"vit_base_patch16_224",
pretrained=True,
num_classes=10,
img_size=224
)
# ViTには強いデータ拡張 + AdamW + cosineスケジュールが効果的
data_config = timm.data.resolve_model_data_config(model)
transforms_train = timm.data.create_transform(**data_config, is_training=True)
transforms_val = timm.data.create_transform(**data_config, is_training=False)
optimizer = torch.optim.AdamW(
model.parameters(), lr=1e-3, weight_decay=0.05
)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer, T_max=100
)
5.2 Swin Transformer: 階層的ViT
Swin Transformerは階層的特徴マップとShifted Window AttentionでCNNの局所性をViTに導入しました。各ステージで解像度を半分にしてチャンネルを増やし、FPNとの互換性を保ちます。
| モデル | 解像度 | パラメータ | ImageNet Top-1 |
|---|---|---|---|
| ViT-B/16 | 224 | 86M | 81.8% |
| Swin-T | 224 | 28M | 81.3% |
| Swin-B | 224 | 88M | 83.5% |
| Swin-L | 384 | 197M | 87.3% |
| DINOv2-L | 518 | 307M | 86.3% |
5.3 DINOv2: 自己教師あり学習の頂点
DINOv2はラベルなしの大規模画像データで学習した汎用ビジョンエンコーダです。**自己教師あり学習(self-supervised learning)**でImageNetの教師あり学習モデルを凌駕します。
import torch
import torchvision.transforms as T
# DINOv2特徴抽出器(ファインチューニングなしで即使用可能)
dinov2 = torch.hub.load("facebookresearch/dinov2", "dinov2_vitl14")
dinov2.eval().cuda()
preprocess = T.Compose([
T.Resize(518),
T.CenterCrop(518),
T.ToTensor(),
T.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
with torch.no_grad():
# [B, 3, 518, 518] -> [B, 1024] 特徴
features = dinov2(preprocess(img).unsqueeze(0).cuda())
print(f"Feature dim: {features.shape}") # [1, 1024]
# DINOv2はk-NNベースの分類器でも優れた性能を示す
6. 生成モデル: GAN、Diffusion、ControlNet
6.1 生成モデルの比較
| 生成モデル | 代表モデル | 学習方式 | 長所 | 短所 |
|---|---|---|---|---|
| GAN | StyleGAN3 | 敵対的学習 | 高速生成 | 学習不安定、モード崩壊 |
| VAE | VQ-VAE-2 | 再構成+KL | 安定した学習 | ぼやけた画像 |
| Diffusion | DDPM、DDIM | ノイズ除去 | 最高品質 | 生成が遅い |
| LDM | Stable Diffusion | 潜在空間拡散 | 品質+速度のバランス | 高いGPUメモリ |
6.2 Stable Diffusion: 潜在拡散モデル
Stable Diffusionは**潜在拡散モデル(Latent Diffusion Model: LDM)**です。U-Netが潜在空間でノイズを段階的に除去します。
- 順方向プロセス: 画像にガウシアンノイズをTステップにわたって追加
- 逆方向プロセス: U-Netがnoisy latent z_t、timestep t、テキスト埋め込みを受け取りノイズ成分epsilonを予測
- VAEデコーダー: 最終的な潜在ベクトルをピクセル空間に復元
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
import torch
# SDXL 1.0 テキストから画像への生成
pipe = StableDiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
use_safetensors=True,
)
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
pipe.scheduler.config
)
pipe.to("cuda")
image = pipe(
prompt="a photorealistic cat on a desk, 8k, studio lighting",
negative_prompt="blurry, low quality, cartoon",
num_inference_steps=25,
guidance_scale=7.5,
width=1024,
height=1024
).images[0]
image.save("generated.png")
6.3 ControlNet: 構造条件付き生成
ControlNetはエッジマップ、深度マップ、ポーズなどの構造的条件で画像生成を精密に制御します。
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from diffusers.utils import load_image
import cv2
import numpy as np
from PIL import Image
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/sd-controlnet-canny",
torch_dtype=torch.float16
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
controlnet=controlnet,
torch_dtype=torch.float16
).to("cuda")
# Cannyエッジマップの生成
ref_image = np.array(load_image("reference.jpg"))
edges = cv2.Canny(ref_image, 100, 200)
edges_rgb = np.stack([edges] * 3, axis=-1)
result = pipe(
"a beautiful landscape painting",
image=Image.fromarray(edges_rgb),
num_inference_steps=20
).images[0]
result.save("controlnet_output.png")
7. 実践パイプライン: DataLoaderからTensorRTまで
7.1 カスタムDatasetとDataLoader
from torch.utils.data import Dataset, DataLoader
from pathlib import Path
import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
class CustomDataset(Dataset):
def __init__(self, root: str, split: str = "train"):
self.root = Path(root)
self.image_paths = list(
(self.root / split / "images").glob("*.jpg")
)
self.label_paths = [
self.root / split / "labels" / p.with_suffix(".txt").name
for p in self.image_paths
]
self.transform = self._get_transforms(split)
def _get_transforms(self, split: str):
if split == "train":
return A.Compose([
A.RandomResizedCrop(224, 224, scale=(0.7, 1.0)),
A.HorizontalFlip(p=0.5),
A.ColorJitter(brightness=0.4, contrast=0.4,
saturation=0.4, hue=0.1, p=0.8),
A.GaussianBlur(blur_limit=(3, 7), p=0.2),
A.Normalize(mean=(0.485, 0.456, 0.406),
std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
return A.Compose([
A.Resize(256, 256),
A.CenterCrop(224, 224),
A.Normalize(mean=(0.485, 0.456, 0.406),
std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
image = cv2.cvtColor(
cv2.imread(str(self.image_paths[idx])), cv2.COLOR_BGR2RGB
)
label = int(self.label_paths[idx].read_text().strip())
augmented = self.transform(image=image)
return augmented["image"], label
train_dataset = CustomDataset("data/", split="train")
train_loader = DataLoader(
train_dataset, batch_size=32, shuffle=True,
num_workers=4, pin_memory=True, persistent_workers=True
)
7.2 ONNXエクスポート
import torch
import torch.onnx
model.eval()
dummy_input = torch.randn(1, 3, 224, 224, device="cuda")
torch.onnx.export(
model,
dummy_input,
"model.onnx",
export_params=True,
opset_version=17,
do_constant_folding=True,
input_names=["input"],
output_names=["output"],
dynamic_axes={
"input": {0: "batch_size"},
"output": {0: "batch_size"}
}
)
print("ONNXエクスポート完了: model.onnx")
# ONNX Runtimeで検証
import onnxruntime as ort
import numpy as np
sess = ort.InferenceSession(
"model.onnx", providers=["CUDAExecutionProvider"]
)
input_name = sess.get_inputs()[0].name
result = sess.run(None, {input_name: dummy_input.cpu().numpy()})
print(f"ONNX推論結果のshape: {result[0].shape}")
7.3 TensorRT最適化
# trtexecを使ったTensorRT変換
trtexec \
--onnx=model.onnx \
--saveEngine=model_fp16.engine \
--fp16 \
--workspace=4096 \
--optShapes=input:8x3x224x224
import tensorrt as trt
import numpy as np
import pycuda.driver as cuda
import pycuda.autoinit
def trt_inference(engine_path: str, input_data: np.ndarray) -> np.ndarray:
logger = trt.Logger(trt.Logger.WARNING)
with open(engine_path, "rb") as f:
engine = trt.Runtime(logger).deserialize_cuda_engine(f.read())
context = engine.create_execution_context()
input_mem = cuda.mem_alloc(input_data.nbytes)
output = np.empty((input_data.shape[0], 1000), dtype=np.float32)
output_mem = cuda.mem_alloc(output.nbytes)
cuda.memcpy_htod(input_mem, input_data)
context.execute_v2([int(input_mem), int(output_mem)])
cuda.memcpy_dtoh(output, output_mem)
return output
クイズ: コンピュータービジョンの深い理解
Q1. ResNetのスキップ接続が勾配消失問題を解決する仕組みとは?
答え: 逆伝播時に勾配がスキップ接続を経由して直接伝達されるため、深いレイヤーでも消失することなく流れます。
解説: 一般的な深いニューラルネットワークでは、逆伝播の勾配はレイヤーを通過するごとに乗算で小さくなります。ResNetの残差ブロックF(x) + xを微分するとdF/dx + 1となり、最小勾配1が常に保証されます。これにより100層以上でも安定した学習が可能になります。
Q2. YOLOがFaster R-CNNよりリアルタイム推論に適している理由とは?
答え: YOLOは単一パス(single forward pass)で検出を完了しますが、Faster R-CNNはRegion Proposal Networkと分類器の2段階が必要です。
解説: Faster R-CNNは(1)RPNによる候補領域の生成、(2)RoI Pooling、(3)分類と回帰という多段構造です。YOLOは画像をグリッドに分割し、1回のCNNパスで全ボックスとクラスを同時に予測します。YOLOv8nはA100 GPUで80+ FPSを達成できます。
Q3. Vision TransformerがCNNよりも大規模データで優れた性能を発揮する理由とは?
答え: ViTのSelf-Attentionは全パッチ間のグローバルな関係を学習し、inductive biasなしにデータから直接最適な表現を習得します。
解説: CNNは局所性(locality)と並進等変性(translation equivariance)というinductive biasを内蔵しています。少ないデータではこのバイアスが役立ちますが、大規模データ(JFT-300Mなど)では表現力を制限します。ViTはバイアスなしにグローバルなパターンを自由に学習できるため、データが十分にある場合にCNNを凌駕します。
Q4. Stable DiffusionのDenoisingプロセスにおけるU-Netの役割とは?
答え: U-Netは各タイムステップで潜在ベクトルに追加されたノイズを予測して除去し、テキスト条件(CLIP埋め込み)をcross-attentionで統合します。
解説: 順方向プロセス(forward process)では画像にガウシアンノイズをTステップにわたって追加します。逆方向プロセス(reverse process)ではU-Netがnoisy latent z_t、タイムステップt、テキスト埋め込みを入力としてノイズ成分epsilonを予測します。VAEデコーダーが最終的な潜在ベクトルをピクセル空間に復元します。
Q5. SAMのプロンプトベースのセグメンテーションが従来の方法と異なる点とは?
答え: SAMは点、ボックス、マスクなど様々なプロンプトを受け取り、追加学習なしに任意のオブジェクトをゼロショットでセグメンテーションします。
解説: 従来のセグメンテーションモデル(DeepLab、Mask R-CNN)は特定のクラス集合に対して教師あり学習されます。SAMはSA-1Bデータセット(10億マスク)で学習された汎用モデルで、クラスに関わらずユーザーが指定した領域を分離します。Image Encoder(ViT-H)、Prompt Encoder、Mask Decoderの3モジュール構造を持ちます。
まとめ: 学習ロードマップ
コンピュータービジョンは急速に発展する分野です。推奨される学習経路:
- 基礎: OpenCV、NumPyによる画像処理 → torchvisionの実践
- 分類: ResNet/EfficientNetのファインチューニング → カスタムデータセット
- 検出: YOLOv8の実験 → カスタム学習 → ONNX/TensorRTでのデプロイ
- セグメンテーション: SAMの実験 → Mask R-CNN/DeepLabV3+のカスタム学習
- 上級: ViT/DINOv2による特徴抽出 → Stable Diffusionのファインチューニング
各ステップでKaggleコンペティションや実際のプロジェクトに応用することが、最も効果的な学習方法です。コンピュータービジョンの世界へようこそ!