Skip to content
Published on

컴퓨터 비전 완전 정복: CNN부터 ViT, YOLO, Stable Diffusion까지

Authors

들어가며

컴퓨터 비전(Computer Vision)은 기계가 이미지와 동영상을 이해하는 AI의 핵심 분야입니다. 스마트폰 얼굴 잠금 해제, 자율주행 차량의 장애물 인식, 의료 영상 진단 보조 — 모두 컴퓨터 비전 기술이 작동하고 있습니다.

이 가이드는 픽셀 수준의 기초부터 최신 Vision Transformer, Stable Diffusion까지 체계적으로 다룹니다.


1. 이미지 기초: 픽셀, 채널, 컨볼루션

1.1 디지털 이미지의 구조

디지털 이미지는 픽셀(pixel)의 2D 격자입니다.

  • 그레이스케일 이미지: H x W 형태의 2D 배열, 각 픽셀 값 0~255
  • 컬러 이미지(RGB): H x W x 3 형태의 3D 텐서, R/G/B 각 채널 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
1998LeNet-5최초 실용 CNN, 합성곱+풀링 구조-
2012AlexNetReLU, Dropout, GPU 학습63.3%
2014VGGNet3x3 커널 깊게 쌓기74.4%
2015ResNet-50Skip Connection, 잔차 학습76.0%
2017DenseNet모든 레이어 직접 연결77.4%
2019EfficientNet-B7복합 스케일링84.4%
2022ConvNeXt-LTransformer 설계 원칙을 CNN에 적용86.6%

2.2 ResNet: 잔차 학습의 혁명

ResNet의 핵심은 **skip connection(잔차 연결)**입니다. 입력 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-stageFaster R-CNN느림높음RPN + 분류기 분리
Anchor-based 1-stageYOLOv8빠름중-높음단일 패스 추론
Anchor-free 1-stageYOLOv10, FCOS매우 빠름높음NMS-free, 앵커 제거
TransformerDETR중간높음End-to-end, 관계 모델링

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-Free 탐지

YOLOv10은 Non-Maximum Suppression(NMS) 후처리를 제거하고 **이중 레이블 할당(dual label assignment)**으로 end-to-end 학습을 실현했습니다. 일관성 매칭(consistency matching)으로 one-to-one 예측과 one-to-many 예측을 동시에 활용합니다.

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은 bipartite matching loss를 통해 anchor와 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 데이터셋(1억 개 마스크)으로 학습된 범용 세그멘테이션 모델입니다.

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"Segmentation map 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과 달리 locality 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 schedule이 효과적
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의 locality를 ViT에 도입했습니다. 각 스테이지에서 해상도를 반씩 줄이고 채널을 늘려 FPN과 호환됩니다.

모델해상도파라미터ImageNet Top-1
ViT-B/1622486M81.8%
Swin-T22428M81.3%
Swin-B22488M83.5%
Swin-L384197M87.3%
DINOv2-L518307M86.3%

5.3 DINOv2: 자기지도 학습의 정점

DINOv2는 레이블 없이 대규모 이미지 데이터로 학습한 범용 비전 인코더입니다. self-supervised learning으로 ImageNet 지도 학습 모델을 능가합니다.

import torch

# DINOv2 특징 추출기 (학습 없이 바로 사용)
dinov2 = torch.hub.load("facebookresearch/dinov2", "dinov2_vitl14")
dinov2.eval().cuda()

# 임의 크기 이미지 처리
import torchvision.transforms as T
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 생성 모델 비교

생성 모델대표 모델학습 방식장점단점
GANStyleGAN3적대적 학습고속 생성학습 불안정, 모드 붕괴
VAEVQ-VAE-2재구성 + KL안정적 학습흐릿한 이미지
DiffusionDDPM, DDIM노이즈 제거품질 최고느린 생성
LDMStable Diffusion잠재 공간 확산품질+속도 균형높은 GPU 메모리

6.2 Stable Diffusion: 잠재 확산 모델

Stable Diffusion은 **Latent Diffusion Model(LDM)**입니다. U-Net이 잠재 공간에서 노이즈를 단계별로 제거합니다.

  • Forward process: 이미지에 가우시안 노이즈를 T 스텝에 걸쳐 추가
  • Reverse process: U-Net이 noisy latent z_t, timestep t, 텍스트 임베딩을 받아 노이즈 epsilon 예측
  • VAE decoder: 최종 잠재 벡터를 픽셀 공간으로 복원
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 최적화

# TensorRT 변환 (trtexec 사용)
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의 skip connection이 vanishing gradient를 해결하는 원리는?

정답: 역전파 시 기울기가 skip connection을 통해 직접 전달되어 깊은 레이어에서도 소실 없이 흐릅니다.

설명: 일반 깊은 신경망에서 역전파 기울기는 레이어를 거칠수록 곱셈으로 점점 작아집니다. ResNet의 잔차 블록 F(x) + x는 미분 시 dF/dx + 1이 되어, 최소 기울기 1이 항상 보장됩니다. 이 덕분에 100층 이상도 안정적으로 학습할 수 있습니다.

Q2. YOLO가 Faster R-CNN보다 실시간 추론에 적합한 이유는?

정답: YOLO는 단일 패스(single forward pass)로 탐지를 완료하지만, Faster R-CNN은 Region Proposal Network와 분류기 두 단계가 필요합니다.

설명: Faster R-CNN은 (1) RPN으로 후보 영역 생성, (2) RoI Pooling, (3) 분류 및 회귀의 다단계 구조입니다. YOLO는 이미지를 그리드로 나눠 한 번의 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 diffusion process에서 U-Net의 역할은?

정답: U-Net은 각 timestep에서 잠재 벡터에 추가된 노이즈를 예측하여 제거하며, 텍스트 조건(CLIP 임베딩)을 cross-attention으로 통합합니다.

설명: 순전파(forward process)에서 이미지에 가우시안 노이즈를 T 스텝에 걸쳐 추가합니다. 역전파(reverse process)에서 U-Net은 noisy latent z_t와 timestep t, 텍스트 임베딩을 입력받아 노이즈 성분 epsilon을 예측합니다. VAE 디코더로 최종 잠재 벡터를 픽셀 공간으로 복원합니다.

Q5. SAM의 prompt-based segmentation이 기존 방식과 다른 점은?

정답: SAM은 점, 박스, 마스크 등 다양한 프롬프트를 받아 학습 없이 임의의 객체를 제로샷으로 세그멘테이션합니다.

설명: 기존 세그멘테이션 모델(DeepLab, Mask R-CNN)은 특정 클래스 집합에 대해 지도 학습됩니다. SAM은 SA-1B 데이터셋(1억 개 마스크)으로 학습한 범용 모델로, 클래스에 구애받지 않고 사용자가 지정한 영역을 분리합니다. Image Encoder(ViT-H), Prompt Encoder, Mask Decoder의 3-모듈 구조로 되어 있습니다.


마무리: 학습 로드맵

컴퓨터 비전은 빠르게 발전하는 분야입니다. 추천 학습 경로:

  1. 기초: OpenCV, NumPy 이미지 처리 → torchvision 실습
  2. 분류: ResNet/EfficientNet 파인튜닝 → 커스텀 데이터셋 적용
  3. 탐지: YOLOv8 실험 → 커스텀 학습 → ONNX/TensorRT 배포
  4. 세그멘테이션: SAM 실험 → Mask R-CNN/DeepLabV3+ 커스텀 학습
  5. 고급: ViT/DINOv2 특징 추출 → Stable Diffusion 파인튜닝

각 단계마다 Kaggle 대회실제 프로젝트로 적용하는 것이 가장 빠른 학습 방법입니다.