
강의 영상 보기 (새 탭에서 재생)YouTube
📓Google Colab에서 실습하기
이 레슨은 PyTorch/GPU가 필요합니다. 노트북을 다운로드 후 Google Colab에서 열어주세요.
학습 내용
CNN 구현 (CIFAR-10)
학습 목표
이 레슨을 완료하면:
- •CIFAR-10 데이터셋의 특성을 이해합니다
- •데이터 증강 기법을 적용합니다
- •더 깊은 CNN을 구현합니다
- •컬러 이미지 분류 모델을 학습합니다
핵심 메시지
"실제 이미지는 MNIST보다 훨씬 복잡합니다." CIFAR-10은 컬러 이미지, 다양한 배경, 다양한 물체 위치를 가집니다. 이를 해결하려면 더 깊은 네트워크와 데이터 증강이 필요합니다.
1. CIFAR-10 데이터셋
MNIST vs CIFAR-10 비교
| 특성 | MNIST | CIFAR-10 |
|---|---|---|
| 이미지 크기 | 28×28 | 32×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 CNN | CIFAR-10 CNN |
|---|---|---|
| 입력 | 1×28×28 | 3×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 등을 실행할 수 있습니다.