FCN 구조 및 Oxford Pet 데이터셋 실습

JJang-404·2025년 11월 25일

FCN 구조 및 Oxford Pet 데이터셋 실습

학습 목표

  • FCN(Fully Convolutional Networks)의 구조와 동작 원리 이해
  • Semantic Segmentation과 Instance Segmentation의 차이 파악
  • Oxford-IIIT Pet 데이터셋의 구조 및 Trimap 개념 학습
  • 이미지 보간법(Interpolation)의 중요성 이해
  • ConvTranspose2d를 활용한 업샘플링 기법 습득

1. Semantic vs Instance Segmentation

Semantic Segmentation

정의: 같은 클래스의 모든 객체를 동일한 번호로 분류

특징

  • 사람1, 사람2, 사람3 모두 → 같은 클래스 번호 (예: 1번)
  • 객체의 개별 구분 없음
  • 픽셀 단위로 "이것이 무엇인가?"를 분류

예시

이미지에 사람이 3명 있는 경우:
- Semantic: 모두 1번 (person)
- 개별 구분 불가

Instance Segmentation

정의: 같은 클래스라도 개별 객체를 다르게 구분

특징

  • 사람1 → 번호 1
  • 사람2 → 번호 2
  • 사람3 → 번호 3
  • 서로 다른 위치에 있으면 각자 다르게 분류

예시

이미지에 사람이 3명 있는 경우:
- Instance: 사람1=ID1, 사람2=ID2, 사람3=ID3
- 각 사람을 개별적으로 추적 가능

2. FCN (Fully Convolutional Networks) 구조

FCN의 핵심 개념

Fully Connected Layer 대신 Convolution 사용

  • 기존 CNN: 마지막에 Fully Connected Layer로 분류
  • FCN: 마지막까지 모두 Convolution Layer로 구성
  • 목표: 픽셀마다 예측값을 만들어야 하기 때문

FCN의 탄생 배경 (2015년)

문제점: 픽셀마다 예상값을 만들어야 하는데 너무 큰 사이즈를 처리할 수 없었음

해결책
1. MaxPooling으로 이미지 크기를 계속 줄여감
2. 픽셀에 해당하는 값을 축소
3. 21개의 픽셀로 축소하여 예측
4. 다시 원본 크기로 복원

2015년 당시: MaxPooling만으로도 충분한 효과

FCN의 동작 과정

1단계: 다운샘플링 (Encoder)

입력 이미지 (예: 128×128)
    ↓ Conv + MaxPool
64×64
    ↓ Conv + MaxPool
32×32
    ↓ Conv + MaxPool
16×16
  • MaxPooling으로 이미지 크기 축소
  • 파라미터는 없지만 stride=2로 1/2씩 줄어듦
  • 정보 손실 발생

2단계: 업샘플링 (Decoder)

16×16
    ↓ ConvTranspose2d (stride=2)
32×32
    ↓ ConvTranspose2d (stride=2)
64×64
    ↓ ConvTranspose2d (stride=2)
128×128
  • 다운샘플링으로 손실된 정보를 복원
  • ConvTranspose2d로 크기를 2배씩 증가

FCN의 문제점

정보 손실

  • 다운샘플링 단계에서 정보 손실 발생
  • 어떻게 해결할 것인가? → U-Net 등장

세밀한 경계 복원이 어려움

  • 반반 걸쳐져 있는 경우 처리 곤란
  • 경계선이 부정확함
  • 성능 저하 발생

3. Encoder-Decoder 구조

Encoder 단계

목표: 이미지의 특징 추출 및 크기 축소

과정

# Conv + ReLU + MaxPool 반복
x = torch.relu(self.conv1(x))  # 128×128
x = self.pool(x)                # 64×64

x = torch.relu(self.conv2(x))  # 64×64
x = self.pool(x)                # 32×32

특징

  • 채널 수는 증가: 3 → 64 → 128
  • 이미지 크기는 감소: 128 → 64 → 32
  • 정보가 압축됨

Decoder 단계

목표: 압축된 정보를 다시 복원

과정

# ConvTranspose2d로 크기 복원
x = self.up1(x)  # 32×32 → 64×64
x = self.up2(x)  # 64×64 → 128×128

특징

  • 채널 수는 감소: 128 → 64 → 3 (클래스 수)
  • 이미지 크기는 증가: 32 → 64 → 128
  • 정보가 복원됨

4. ConvTranspose2d (전치 합성곱)

ConvTranspose2d란

역할: 이미지 크기를 늘리는 업샘플링 연산

일반 Convolution과의 차이

구분ConvolutionConvTranspose2d
방향크기 감소크기 증가
stride=21/2로 축소2배로 확대
용도다운샘플링업샘플링

ConvTranspose2d 동작 원리

예시: 4×4를 8×8로 확대

nn.ConvTranspose2d(
    in_channels=64,   # 입력 채널
    out_channels=32,  # 출력 채널
    kernel_size=2,    # 커널 크기
    stride=2          # 2배로 확대
)

stride=2의 의미

  • 입력 픽셀 사이에 0을 삽입
  • 결과적으로 크기가 2배로 증가

시각적 이해

입력 (4×4):
[1 2 3 4]
[5 6 7 8]
[...]

↓ stride=2 (픽셀 사이에 0 삽입)

[1 0 2 0 3 0 4 0]
[0 0 0 0 0 0 0 0]
[5 0 6 0 7 0 8 0]
[...]

↓ Convolution 적용

출력 (8×8)

FCN에서의 활용

class FCN(nn.Module):
    def __init__(self):
        super().__init__()
        # Encoder
        self.conv1 = nn.Conv2d(3, 64, 3, padding=1)
        self.conv2 = nn.Conv2d(64, 128, 3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        
        # Decoder
        self.up1 = nn.ConvTranspose2d(128, 64, 2, stride=2)
        self.up2 = nn.ConvTranspose2d(64, 3, 2, stride=2)

크기 변화

입력: 128×128×3
    ↓ conv1 + pool
64×64×64
    ↓ conv2 + pool
32×32×128
    ↓ up1 (stride=2)
64×64×64
    ↓ up2 (stride=2)
128×128×3

마지막 출력 채널 = 클래스 수

  • 3개 클래스: 전경, 배경, 경계
  • 각 픽셀에서 3개 클래스 중 하나 선택

5. Oxford-IIIT Pet 데이터셋

데이터셋 개요

출처: 옥스퍼드 대학 Visual Geometry Group (VGG)

특징

  • 37가지 고양이와 강아지 품종
  • 이미지 분류, 객체 위치 파악, 분할(Segmentation) 작업에 유용
  • 크기, 자세, 조명 등 다양한 변화 포함

어노테이션 종류

1. 품종 분류 (Classification)

  • 각 이미지의 정확한 품종 레이블
  • 예: 'Abyssinian', 'beagle' 등

2. 객체 위치 파악 (Object Localization)

  • 동물의 머리 주변 영역(Head ROI) 바운딩 박스

3. 픽셀 수준 분할 (Pixel-level Segmentation) - Trimap

Trimap 개념

정의: 이미지를 세 가지 구분된 영역으로 정의하는 맵

어원

  • Tri (트라이): 숫자 셋(Three)을 의미하는 접두사
  • Map (맵): 지도나 영역을 표시하고 매핑하는 것

3가지 클래스

클래스의미설명
Foreground1전경고양이 또는 강아지 자체에 속하는 픽셀
Background2배경이미지에서 동물 외의 부분에 속하는 픽셀
Boundary3경계/불확실 영역전경과 배경 사이의 경계 영역

Trimap의 중요성

경계 영역의 역할

  • 물체 인식의 정확도 향상
  • 명확한 객체 세그멘테이션 가능
  • 지도상에서 필요한 경계 정보 제공

데이터 값이 명확하지 않은 경우

  • 바깥쪽과 안쪽의 경계를 명확히 구분
  • 잘못 그으면 성능 저하
  • 경계 영역을 따로 표시하여 모델이 학습

데이터 불러오기

from torchvision.datasets import OxfordIIITPet
import matplotlib.pyplot as plt
import numpy as np

# 다운로드
print("Oxford Pet 데이터셋 다운로드 중...")
pet_dataset = OxfordIIITPet(
    root='./data', 
    split='trainval',
    target_types='segmentation',
    download=True
)

print(f"다운로드 완료! 총 {len(pet_dataset)}장")

데이터 탐색 (EDA)

마스크 값 확인

img, mask = pet_dataset[0]

# numpy 배열로 변환
mask_array = np.array(mask)

print(f"마스크 shape: {mask_array.shape}")
print(f"마스크 dtype: {mask_array.dtype}")
print(f"\n마스크 unique 값들: {np.unique(mask_array)}")

# 각 값의 개수 확인
for val in np.unique(mask_array):
    count = np.sum(mask_array == val)
    percent = count / mask_array.size * 100
    print(f"  값 {val}: {count}개 ({percent:.1f}%)")

출력 예시

마스크 shape: (500, 394)
마스크 dtype: uint8

마스크 unique 값들: [1 2 3]
  값 1: 45000개 (22.8%)  # 전경
  값 2: 150000개 (76.1%) # 배경
  값 3: 2000개 (1.1%)    # 경계

클래스별 시각화

fig, axes = plt.subplots(1, 4, figsize=(16, 4))

# 원본 이미지
axes[0].imshow(img)
axes[0].set_title('Original Image')
axes[0].axis('off')

# 클래스 1: 전경 (동물)
axes[1].imshow(mask_array == 1, cmap='Reds')
axes[1].set_title('Class 1 (Foreground/animal)')
axes[1].axis('off')

# 클래스 2: 배경
axes[2].imshow(mask_array == 2, cmap='Blues')
axes[2].set_title('Class 2 (Background)')
axes[2].axis('off')

# 클래스 3: 경계선
axes[3].imshow(mask_array == 3, cmap='Greens')
axes[3].set_title('Class 3 (Boundary)')
axes[3].axis('off')

plt.tight_layout()
plt.show()

6. 이미지 보간법 (Interpolation)

보간법이란

정의: 이미지 크기를 변경할 때 새로운 픽셀 값을 추정하는 방법

필요성

  • 이미지를 확대하면 픽셀이 부족함
  • 이미지를 축소하면 픽셀이 남음
  • 새로운 픽셀 값을 어떻게 채울 것인가?

마스크 리사이즈의 문제

일반 이미지 리사이즈

# 일반 이미지는 평균, 선형 보간 사용 가능
img_resized = T.Resize((128, 128))(img)

마스크 리사이즈의 문제점

원본 마스크:
[1 1 2 2]
[1 1 2 2]

↓ 평균 보간법 사용 시

[1.0 1.5 2.0]
[1.0 1.5 2.0]
        ↑
      1.5는 존재하지 않는 클래스!

문제

  • 1번 배경과 2번 전경 사이에 1.5가 나옴
  • 1.5 레이블은 없음!
  • 마스크 번호는 절대로 1, 2, 3이어야 함

보간법 종류

NEAREST (최근접 이웃 보간)

원리: 가장 가까운 픽셀 값을 그대로 사용

원본:
[1 1 2 2]
[1 1 2 2]

↓ NEAREST 사용

[1 1 2 2]
[1 1 2 2]

특징

  • 값이 정확히 보존됨
  • 계단 현상(aliasing) 발생
  • 마스크에 필수적으로 사용

BILINEAR (선형 보간)

원리: 주변 4개 픽셀의 가중 평균

1과 5 사이를 보간:
가운데 값 = (1 + 5) / 2 = 3

특징

  • 부드러운 결과
  • 새로운 값 생성 가능
  • 일반 이미지에 적합

BICUBIC (3차 보간)

원리: 주변 16개 픽셀의 3차 함수로 추정

특징

  • 가장 부드러운 결과
  • 계산량 많음
  • 고품질 이미지 확대에 사용

마스크 전처리 시 주의사항

올바른 방법

# 마스크는 반드시 NEAREST 사용
mask = T.Resize(
    (128, 128), 
    interpolation=T.InterpolationMode.NEAREST
)(mask)

잘못된 방법

# 평균값이 나와서 이상한 값 발생
mask = T.Resize((128, 128))(mask)  # 기본값: BILINEAR

보간법 비교

보간법속도품질마스크 사용일반 이미지 사용
NEAREST빠름낮음 (계단 현상)O 필수X
BILINEAR중간중간XO
BICUBIC느림높음XO

Anti-aliasing (안티 에일리어싱)

Aliasing (계단 현상)

  • 이미지를 확대하면 계단처럼 딱딱 끊어짐
  • 픽셀이 보이는 현상

Anti-aliasing

  • 경계를 부드럽게 만듦
  • 주변 픽셀값을 평균내거나 가중치 적용
  • 보간법의 일종

7. FCN 구현 및 학습

데이터셋 클래스 구현

import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
from torchvision.datasets import OxfordIIITPet
import torchvision.transforms as T
import numpy as np

class PetDataset(Dataset):
    def __init__(self):
        self.pet = OxfordIIITPet(
            root='./data', 
            split='trainval',
            target_types='segmentation', 
            download=True
        )

    def __len__(self):
        return len(self.pet)

    def __getitem__(self, idx):
        img, mask = self.pet[idx]

        # 이미지 전처리
        img = T.Resize((128, 128))(img)
        img = T.ToTensor()(img)

        # 마스크 전처리 (NEAREST 필수!)
        mask = T.Resize(
            (128, 128), 
            interpolation=T.InterpolationMode.NEAREST
        )(mask)
        mask = torch.tensor(np.array(mask), dtype=torch.long)
        mask = mask - 1  # 1,2,3 -> 0,1,2

        return img, mask

마스크 전처리 핵심

  1. NEAREST 보간: 클래스 값 보존
  2. 값 조정: 1,2,3 → 0,1,2 (PyTorch는 0부터 시작)

FCN 모델 구현

class FCN(nn.Module):
    def __init__(self):
        super().__init__()
        
        # Encoder (다운샘플링)
        self.conv1 = nn.Conv2d(3, 64, 3, padding=1)
        self.conv2 = nn.Conv2d(64, 128, 3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        
        # Decoder (업샘플링)
        self.up1 = nn.ConvTranspose2d(128, 64, 2, stride=2)
        self.up2 = nn.ConvTranspose2d(64, 3, 2, stride=2)

    def forward(self, x):
        # Encoder
        x = torch.relu(self.conv1(x))  # 128×128×64
        x = self.pool(x)                # 64×64×64
        
        x = torch.relu(self.conv2(x))  # 64×64×128
        x = self.pool(x)                # 32×32×128
        
        # Decoder
        x = self.up1(x)  # 64×64×64
        x = self.up2(x)  # 128×128×3
        
        return x

구조 요약

입력: [배치, 3, 128, 128]
    ↓ conv1 + ReLU
[배치, 64, 128, 128]
    ↓ MaxPool
[배치, 64, 64, 64]
    ↓ conv2 + ReLU
[배치, 128, 64, 64]
    ↓ MaxPool
[배치, 128, 32, 32]
    ↓ up1 (ConvTranspose2d)
[배치, 64, 64, 64]
    ↓ up2 (ConvTranspose2d)
출력: [배치, 3, 128, 128]

학습 코드

# 데이터 & 모델 준비
dataset = PetDataset()
loader = DataLoader(dataset, batch_size=8, shuffle=True, num_workers=2)

model = FCN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

print(f"데이터: {len(dataset)}장")
print(f"모델 파라미터: {sum(p.numel() for p in model.parameters()):,}개")

# 학습
epochs = 3

for epoch in range(epochs):
    total_loss = 0
    for i, (imgs, masks) in enumerate(loader):
        optimizer.zero_grad()
        
        # Forward
        outputs = model(imgs)
        loss = criterion(outputs, masks)
        
        # Backward
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
        
        if i % 50 == 0:
            print(f"Epoch {epoch+1}, Batch {i}, Loss: {loss.item():.4f}")
    
    print(f"Epoch {epoch+1} 완료, Avg Loss: {total_loss/len(loader):.4f}\n")

print("학습 완료!")

손실 함수

CrossEntropyLoss 사용

criterion = nn.CrossEntropyLoss()
loss = criterion(outputs, masks)

입력 형태

  • outputs: [배치, 클래스 수, H, W] = [8, 3, 128, 128]
  • masks: [배치, H, W] = [8, 128, 128]

동작 과정

  1. 각 픽셀에서 3개 클래스 중 확률 계산
  2. 정답 클래스와 비교
  3. 픽셀별 손실 계산 후 평균
픽셀 (i, j)에서:
- 출력: [0.1, 0.7, 0.2] (3개 클래스 확률)
- 정답: 1 (두 번째 클래스)
- 손실: -log(0.7)

결과 확인

# 평가 모드
model.eval()
with torch.no_grad():
    img, mask = dataset[0]
    pred = model(img.unsqueeze(0))
    pred = pred.argmax(1).squeeze()

# 시각화
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

axes[0].imshow(img.permute(1, 2, 0))
axes[0].set_title('Input Image')
axes[0].axis('off')

axes[1].imshow(mask, cmap='tab20')
axes[1].set_title('Ground Truth')
axes[1].axis('off')

axes[2].imshow(pred, cmap='tab20')
axes[2].set_title('Prediction')
axes[2].axis('off')

plt.tight_layout()
plt.show()

8. Pix2Pix와 GAN

Pix2Pix 개요

참고 자료: https://www.tensorflow.org/tutorials/generative/pix2pix?hl=ko

개념: 픽셀을 픽셀로 바꾸는 생성 모델

세그멘테이션과의 관계

  • 입력: 원본 이미지
  • 출력: 세그멘테이션 마스크
  • 역방향도 가능: 마스크 → 이미지

Pix2Pix의 활용

세그멘테이션 → 이미지 생성

Input: Segmentation Mask
    ↓ Pix2Pix
Output: 실제 이미지

이미지 → 세그멘테이션

Input: 원본 이미지
    ↓ Pix2Pix
Output: Segmentation Mask

특징

  • 초반에는 픽셀 자체를 손으로 그림
  • 이제는 세그멘테이션으로 자동화
  • 입력 데이터는 색상, 출력 데이터는 이미지
  • 생성형이지만 세그멘테이션 기본 작업도 포함

9. Resize 전후 비교

Resize의 영향

원본 크기

마스크 shape: (500, 394)
픽셀 개수: 197,000개
unique 값: [1, 2, 3]

Resize 후

마스크 shape: (128, 128)
픽셀 개수: 16,384개
unique 값: [1, 2, 3]

크기 변화

  • 197,000개 → 16,384개 (약 1/12로 축소)
  • 클래스 값은 보존 (NEAREST 덕분)

픽셀 값 비교

Resize 전 (10×10 영역)

[1 1 1 2 2 2 3 3 2 2]
[1 1 1 2 2 2 3 3 2 2]
[1 1 1 1 2 2 2 3 2 2]
...

Resize 후 (10×10 영역)

[1 1 2 2 2 3 2 2 2 2]
[1 1 1 2 2 2 2 2 2 2]
[1 1 1 1 2 2 2 2 2 2]
...

관찰

  • 클래스 값은 1, 2, 3만 유지
  • 경계가 약간 변형될 수 있음
  • 하지만 전체적인 구조는 보존

클래스 분포 변화

Resize 전

Class 1 (전경): 45,000 pixels
Class 2 (배경): 150,000 pixels
Class 3 (경계): 2,000 pixels

Resize 후

Class 1 (전경): 3,500 pixels
Class 2 (배경): 12,500 pixels
Class 3 (경계): 384 pixels

비율은 거의 유지됨

  • 전경: 22.8% → 21.4%
  • 배경: 76.1% → 76.3%
  • 경계: 1.1% → 2.3%

Q&A 정리

Q. "FCN과 일반 CNN의 차이는 무엇인가요?"

일반 CNN은 마지막에 Fully Connected Layer를 사용하여 하나의 클래스를 예측하지만, FCN은 마지막까지 Convolution Layer를 사용하여 픽셀마다 클래스를 예측합니다. 이를 통해 이미지의 각 위치에서 세그멘테이션을 수행할 수 있습니다.

Q. "ConvTranspose2d는 어떻게 이미지를 확대하나요?"

ConvTranspose2d는 stride=2를 사용할 때 입력 픽셀 사이에 0을 삽입한 후 Convolution을 적용합니다. 이를 통해 입력보다 2배 큰 출력을 생성할 수 있습니다. 학습 가능한 파라미터를 통해 어떤 값으로 채울지 학습합니다.

Q. "마스크를 Resize할 때 왜 NEAREST를 사용해야 하나요?"

마스크의 값은 클래스 번호(1, 2, 3)이므로 정확히 보존되어야 합니다. BILINEAR나 BICUBIC을 사용하면 1과 2 사이에 1.5 같은 값이 생성되는데, 이는 존재하지 않는 클래스입니다. NEAREST는 가장 가까운 픽셀 값을 그대로 사용하므로 클래스 값이 정확히 보존됩니다.

Q. "Trimap의 경계 영역(Class 3)은 왜 필요한가요?"

전경과 배경 사이의 경계는 모호한 영역입니다. 이를 별도의 클래스로 표시하면 모델이 불확실한 영역을 학습할 수 있고, 더 정확한 세그멘테이션 결과를 얻을 수 있습니다. 특히 물체 인식이나 지도 작업에서 경계 정보가 중요합니다.

Q. "FCN의 성능이 좋지 않은 이유는 무엇인가요?"

FCN은 다운샘플링 과정에서 정보 손실이 발생하고, 업샘플링만으로는 세밀한 경계를 복원하기 어렵습니다. 반반 걸쳐져 있는 경계 부분의 처리가 곤란하여 성능 저하가 발생합니다. 이를 해결하기 위해 U-Net 등의 개선된 모델이 등장했습니다.


핵심 정리

  1. Semantic vs Instance: Semantic은 같은 클래스를 동일하게, Instance는 개별 객체를 다르게 구분

  2. FCN 구조: Fully Connected Layer 대신 Convolution만 사용, 픽셀마다 예측 수행

  3. Encoder-Decoder: Encoder는 특징 추출 및 축소, Decoder는 복원 및 예측

  4. ConvTranspose2d: stride=2로 이미지 크기를 2배로 확대하는 업샘플링 연산

  5. Oxford Pet 데이터셋: 37가지 품종, Trimap으로 전경/배경/경계 구분

  6. Trimap: 1=전경, 2=배경, 3=경계로 구성된 3클래스 마스크

  7. 보간법 중요성: 마스크는 반드시 NEAREST 사용, 일반 이미지는 BILINEAR/BICUBIC 가능

  8. 마스크 전처리: NEAREST 보간 + 값 조정(1,2,3 → 0,1,2)

  9. CrossEntropyLoss: 픽셀별로 다중 분류 손실 계산 후 평균

  10. FCN의 한계: 정보 손실과 경계 복원 문제로 U-Net 등장


추가 학습 권장 사항

이론 심화

FCN 논문 정독

  • "Fully Convolutional Networks for Semantic Segmentation" (Long et al., 2015)
  • Skip connection이 없는 기본 구조 이해
  • FCN-32s, FCN-16s, FCN-8s 비교

U-Net 학습

  • FCN의 문제점을 어떻게 해결했는지
  • Skip connection의 역할
  • 의료 영상에서의 성공 이유

SegNet 학습

  • Pooling indices를 사용한 업샘플링
  • FCN과의 차이점

실습 심화

다양한 업샘플링 기법 비교

  • ConvTranspose2d vs Upsample + Conv
  • 성능 및 파라미터 수 비교
  • 체커보드 아티팩트(checkerboard artifacts) 이해

보간법 실험

  • NEAREST, BILINEAR, BICUBIC 직접 비교
  • 각 방법의 장단점 실습
  • 마스크와 이미지에서의 차이 확인

데이터 증강

  • 이미지 증강: RandomCrop, RandomHorizontalFlip
  • 마스크 증강: 이미지와 동일한 변환 적용
  • NEAREST 보간 유지 확인

Loss 함수 실험

  • CrossEntropyLoss vs Dice Loss
  • Focal Loss 적용
  • 클래스 불균형 문제 해결

모델 개선

  • 더 깊은 Encoder 구조
  • Batch Normalization 추가
  • Dropout 적용

관련 개념

Pix2Pix와 GAN

  • Image-to-Image Translation
  • 조건부 GAN의 이해
  • TensorFlow 튜토리얼 실습

업샘플링 기법

  • Nearest Neighbor
  • Bilinear Interpolation
  • Transposed Convolution
  • Sub-pixel Convolution

다운샘플링 기법

  • MaxPooling vs AvgPooling
  • Strided Convolution
  • 정보 손실 최소화 방법

안티 에일리어싱

  • Aliasing 현상 이해
  • Anti-aliasing 기법
  • 이미지 품질 향상

프로젝트 아이디어

커스텀 데이터셋 구축

  • 자신만의 세그멘테이션 데이터셋 제작
  • Roboflow로 어노테이션
  • FCN으로 학습 및 평가

의료 영상 세그멘테이션

  • CT, MRI 등 의료 영상 데이터
  • 장기나 종양 세그멘테이션
  • 높은 정확도 요구

자율 주행 시뮬레이션

  • 도로, 차량, 보행자 세그멘테이션
  • Cityscapes 데이터셋 활용
  • 실시간 처리 최적화

참고 자료

논문

  • FCN: Long et al., "Fully Convolutional Networks for Semantic Segmentation", CVPR 2015
  • U-Net: Ronneberger et al., "U-Net: Convolutional Networks for Biomedical Image Segmentation", MICCAI 2015
  • Pix2Pix: Isola et al., "Image-to-Image Translation with Conditional Adversarial Networks", CVPR 2017

온라인 자료

라이브러리

  • torchvision.models.segmentation
  • segmentation_models_pytorch
  • albumentations (데이터 증강)

코드 저장소

profile
V I S I O N _ E N G I N E E R

0개의 댓글