Level 5: CNN & 이미지 처리
🖼️

Level 5

CNN 구현 (CIFAR-10)

더 복잡한 이미지 분류

50분
CNN 구현 (CIFAR-10) 강의 영상
강의 영상 보기 (새 탭에서 재생)YouTube

📓Google Colab에서 실습하기

이 레슨은 PyTorch/GPU가 필요합니다. 노트북을 다운로드 후 Google Colab에서 열어주세요.

학습 내용

CNN 구현 (CIFAR-10)

학습 목표

이 레슨을 완료하면:

  • CIFAR-10 데이터셋의 특성을 이해합니다
  • 데이터 증강 기법을 적용합니다
  • 더 깊은 CNN을 구현합니다
  • 컬러 이미지 분류 모델을 학습합니다

핵심 메시지

"실제 이미지는 MNIST보다 훨씬 복잡합니다." CIFAR-10은 컬러 이미지, 다양한 배경, 다양한 물체 위치를 가집니다. 이를 해결하려면 더 깊은 네트워크와 데이터 증강이 필요합니다.


1. CIFAR-10 데이터셋

MNIST vs CIFAR-10 비교

특성MNISTCIFAR-10
이미지 크기28×2832×32
색상흑백 (1채널)컬러 (3채널)
클래스숫자 0-9사물 10종
난이도쉬움중간
배경단순 (검정)복잡 (다양)

CIFAR-10의 10개 클래스

비행기, 자동차, 새, 고양이, 사슴, 개, 개구리, 말, 배, 트럭

🔬 실습: CIFAR-10 데이터 로딩

python
⚠️ 로컬 실행 필요
import torch from torch.utils.data import DataLoader from torchvision import datasets, transforms import matplotlib.pyplot as plt import numpy as np # ═══════════════════════════════════════════════════════════════ # 📊 CIFAR-10 데이터셋 준비 # ═══════════════════════════════════════════════════════════════ # 클래스 이름 classes = ['비행기', '자동차', '새', '고양이', '사슴', '개', '개구리', '말', '배', '트럭'] # 훈련용 변환 (데이터 증강 포함) train_transform = transforms.Compose([ transforms.RandomHorizontalFlip(), # 좌우 반전 transforms.RandomCrop(32, padding=4), # 랜덤 크롭 transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)) ]) # 테스트용 변환 (증강 없음) test_transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)) ]) # 데이터셋 로드 train_dataset = datasets.CIFAR10('./data', train=True, download=True, transform=train_transform) test_dataset = datasets.CIFAR10('./data', train=False, transform=test_transform) train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=100, shuffle=False) print("=" * 50) print("📊 CIFAR-10 데이터셋 정보") print("=" * 50) print(f"훈련 데이터: {len(train_dataset)}개") print(f"테스트 데이터: {len(test_dataset)}개") print(f"이미지 크기: 32 × 32 × 3 (컬러)") print(f"클래스 수: 10") # 샘플 이미지 시각화 (정규화 해제) fig, axes = plt.subplots(2, 5, figsize=(12, 5)) for i, ax in enumerate(axes.flat): # 정규화 해제를 위한 원본 이미지 사용 img, label = datasets.CIFAR10('./data', train=True, download=False)[i] ax.imshow(img) ax.set_title(classes[label]) ax.axis('off') plt.suptitle('CIFAR-10 Sample Images', fontsize=14, fontweight='bold') plt.tight_layout() plt.show()

2. 데이터 증강

데이터 증강은 학습 데이터를 인위적으로 늘려 과적합을 방지합니다.

주요 증강 기법

기법설명효과
RandomHorizontalFlip좌우 반전방향 불변성
RandomCrop랜덤 자르기위치 불변성
RandomRotation회전각도 불변성
ColorJitter색상 변환조명 불변성

3. 깊은 CNN 모델

🔬 실습: CIFAR-10용 CNN

python
⚠️ 로컬 실행 필요
import torch import torch.nn as nn # ═══════════════════════════════════════════════════════════════ # 📊 CIFAR-10용 깊은 CNN 모델 # ═══════════════════════════════════════════════════════════════ class CIFAR10_CNN(nn.Module): def __init__(self): super(CIFAR10_CNN, self).__init__() # 블록 1: 32 -> 32 -> Pool -> 16 self.block1 = nn.Sequential( nn.Conv2d(3, 64, 3, padding=1), nn.BatchNorm2d(64), nn.ReLU(inplace=True), nn.Conv2d(64, 64, 3, padding=1), nn.BatchNorm2d(64), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2) ) # 블록 2: 16 -> 16 -> Pool -> 8 self.block2 = nn.Sequential( nn.Conv2d(64, 128, 3, padding=1), nn.BatchNorm2d(128), nn.ReLU(inplace=True), nn.Conv2d(128, 128, 3, padding=1), nn.BatchNorm2d(128), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2) ) # 블록 3: 8 -> 8 -> Pool -> 4 self.block3 = nn.Sequential( nn.Conv2d(128, 256, 3, padding=1), nn.BatchNorm2d(256), nn.ReLU(inplace=True), nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2) ) # 분류기 self.classifier = nn.Sequential( nn.Dropout(0.5), nn.Linear(256 * 4 * 4, 512), nn.ReLU(inplace=True), nn.Dropout(0.5), nn.Linear(512, 10) ) def forward(self, x): x = self.block1(x) x = self.block2(x) x = self.block3(x) x = x.view(x.size(0), -1) x = self.classifier(x) return x # 모델 생성 model = CIFAR10_CNN() print("=" * 50) print("📊 CIFAR-10 CNN 모델") print("=" * 50) # 파라미터 수 total_params = sum(p.numel() for p in model.parameters()) print(f"총 파라미터: {total_params:,}") # 테스트 x = torch.randn(1, 3, 32, 32) output = model(x) print(f"입력: {x.shape} -> 출력: {output.shape}")

4. 학습 및 평가

🔬 실습: CIFAR-10 학습

python
⚠️ 로컬 실행 필요
import torch import torch.nn as nn import torch.optim as optim import matplotlib.pyplot as plt # ═══════════════════════════════════════════════════════════════ # 📊 CIFAR-10 모델 학습 # ═══════════════════════════════════════════════════════════════ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = CIFAR10_CNN().to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.5) # 학습 기록 train_losses, test_accs = [], [] # 학습 실행 epochs = 20 print("\n학습 시작!") print("=" * 60) for epoch in range(1, epochs + 1): # 훈련 model.train() total_loss = 0 for data, target in train_loader: data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() total_loss += loss.item() # 평가 model.eval() correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) output = model(data) correct += output.argmax(1).eq(target).sum().item() train_loss = total_loss / len(train_loader) test_acc = 100. * correct / len(test_dataset) train_losses.append(train_loss) test_accs.append(test_acc) scheduler.step() if epoch % 5 == 0 or epoch == 1: print(f"Epoch {epoch:2d}/{epochs} | Loss: {train_loss:.4f} | " f"Test Acc: {test_acc:.2f}%") print("=" * 60) print(f"최종 테스트 정확도: {test_accs[-1]:.2f}%") # 학습 곡선 fig, axes = plt.subplots(1, 2, figsize=(12, 4)) axes[0].plot(train_losses, 'b-', linewidth=2) axes[0].set_xlabel('Epoch') axes[0].set_ylabel('Loss') axes[0].set_title('Training Loss') axes[0].grid(True, alpha=0.3) axes[1].plot(test_accs, 'r-', linewidth=2) axes[1].set_xlabel('Epoch') axes[1].set_ylabel('Accuracy (%)') axes[1].set_title('Test Accuracy') axes[1].grid(True, alpha=0.3) plt.suptitle('CIFAR-10 CNN Training Results', fontsize=14, fontweight='bold') plt.tight_layout() plt.show()

핵심 요약

항목MNIST CNNCIFAR-10 CNN
입력1×28×283×32×32
Conv 블록2개3개
데이터 증강불필요필수
목표 정확도99%+85%+

학습 체크리스트

  • MNIST와 CIFAR-10의 차이를 설명할 수 있다
  • 데이터 증강 기법을 적용할 수 있다
  • 더 깊은 CNN을 구현할 수 있다
  • 학습률 스케줄러를 사용할 수 있다

다음 강의 예고

"전이 학습" - 사전 훈련된 모델을 활용하여 적은 데이터로 높은 성능을 달성합니다!

레슨 정보

레벨
Level 5: CNN & 이미지 처리
예상 소요 시간
50분
참고 영상
YouTube 링크

💡실습 환경 안내

이 레벨은 PyTorch/GPU가 필요하여 Google Colab 사용을 권장합니다.

Colab은 무료 GPU를 제공하여 PyTorch, CNN, Transformer 등을 실행할 수 있습니다.