13. CNN (Convolutional Neural Network)
Convolution, Pooling, Transfer Learning
학습 목표
이 튜토리얼을 마치면 다음을 이해할 수 있습니다:
- CNN의 핵심 개념 (Convolution, Pooling)과 작동 원리
- 필터/커널의 역할과 특징 추출 과정
- CNN 아키텍처 구조와 파라미터 계산
- Transfer Learning의 개념과 적용 전략
- 주요 CNN 모델(VGG, ResNet, EfficientNet)의 특징
1. 왜 CNN인가?
1.1 기존 신경망의 한계
완전연결층(Dense/FC)으로 이미지를 처리할 때의 문제점:
28x28 이미지 = 784 픽셀
입력층(784) → 은닉층(512) → 출력층(10)
파라미터: 784 x 512 + 512 x 10 = 401,408개
더 큰 이미지 (224x224x3)라면?
150,528 x 512 = 77,070,336개!⚠️
완전연결층의 추가 문제점:
- 공간적 구조 정보 손실: 픽셀 위치 관계를 무시
- 위치 변화에 취약: 고양이가 왼쪽/오른쪽에 있으면 다른 입력으로 인식
1.2 CNN의 핵심 아이디어
| 개념 | 설명 |
|---|---|
| 지역 연결 (Local Connectivity) | 전체가 아닌 작은 영역만 연결 → 파라미터 수 대폭 감소 |
| 가중치 공유 (Weight Sharing) | 같은 필터를 이미지 전체에 적용 → 위치 불변성 확보 |
| 계층적 특징 학습 | 낮은 층: 엣지, 코너 / 높은 층: 복잡한 패턴, 객체 |
이미지 → [Conv] → [Pool] → [Conv] → [Pool] → [FC] → 출력
↓ ↓ ↓ ↓
엣지 축소 패턴 축소 → 분류2. Convolution Layer
필터(커널)를 이미지에 슬라이딩하며 특징 추출
2.1 필터(커널)란?
작은 가중치 행렬이 이미지 위를 슬라이딩하며 특징을 추출합니다:
이미지 (5x5) 필터 (3x3) 출력 (3x3)
┌─────────────────┐ ┌───────────┐ ┌───────────┐
│ 1 0 1 0 1 │ │ 1 0 1 │ │ ? ? ? │
│ 0 1 0 1 0 │ * │ 0 1 0 │ = │ ? ? ? │
│ 1 0 1 0 1 │ │ 1 0 1 │ │ ? ? ? │
│ 0 1 0 1 0 │ └───────────┘ └───────────┘
│ 1 0 1 0 1 │
└─────────────────┘
출력[i,j] = Σ(이미지 영역 x 필터) (element-wise 곱의 합)2.2 출력 크기 계산
Input: (H, W, C)
Filter: (K, K, C)
Output: (H', W', F)
H' = (H - K + 2P) / S + 1| 파라미터 | 설명 |
|---|---|
| Kernel Size | 필터 크기 (3x3, 5x5) |
| Stride | 이동 간격 |
| Padding | 테두리 패딩 (same, valid) |
| Filters | 필터 개수 = 출력 채널 |
출력 크기 계산 예시:
| Input | Kernel | Padding | Stride | Output |
|---|---|---|---|---|
| 28 | 3 | 0 | 1 | 26 |
| 28 | 3 | 1 | 1 | 28 (same) |
| 28 | 3 | 0 | 2 | 13 |
| 224 | 7 | 3 | 2 | 112 |
from tensorflow.keras.layers import Conv2D
Conv2D(filters=32, kernel_size=(3, 3), strides=1,
padding='same', activation='relu')3. Pooling Layer
공간 크기 축소, 연산량 감소
3.1 Max Pooling
영역 내 최대값 선택으로 특징 강조 + 크기 축소:
입력 (4x4) Max Pool (2x2, stride=2) 출력 (2x2)
┌─────────────────┐ ┌─────────┐
│ 1 3 │ 2 4 │ │ 6 8 │
│ 5 [6]│ 7 [8]│ → 각 영역 최대값 → │ 14 16 │
├────────┼────────┤ └─────────┘
│ 9 11 │ 10 12 │
│ 13 [14]│ 15 [16]│
└─────────────────┘| 유형 | 설명 |
|---|---|
| Max Pooling | 최대값 선택 (일반적) |
| Average Pooling | 평균값 |
| Global Average Pooling | 전체 평균 (FC 대체) |
Pooling의 장점:
- 파라미터 없음 (학습 불필요)
- 크기 축소 → 계산량 감소
- 작은 위치 변화에 불변 (Translation Invariance)
from tensorflow.keras.layers import MaxPooling2D, GlobalAveragePooling2D
MaxPooling2D(pool_size=(2, 2)) # 크기 절반
GlobalAveragePooling2D() # Flatten 대체4. CNN 기본 구조
4.1 일반적인 CNN 구조
입력 이미지 (28x28x1)
↓
┌──────────────────┐
│ Conv (32 filters)│ → 특징 추출
│ ReLU │ → 비선형성
│ MaxPool (2x2) │ → 크기 축소 (14x14x32)
└──────────────────┘
↓
┌──────────────────┐
│ Conv (64 filters)│ → 더 복잡한 특징
│ ReLU │
│ MaxPool (2x2) │ → (7x7x64)
└──────────────────┘
↓
┌──────────────────┐
│ Flatten │ → 7x7x64 = 3136
│ Dense (128) │ → 분류 준비
│ ReLU │
│ Dense (10) │ → 클래스 수
│ Softmax │ → 확률 출력
└──────────────────┘from tensorflow.keras import models, layers
model = models.Sequential([
# Conv Block 1
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
# Conv Block 2
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
# Conv Block 3
layers.Conv2D(64, (3, 3), activation='relu'),
# Classifier
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])4.2 계층적 특징 학습
낮은 층 (Conv1) 중간 층 (Conv2-3) 높은 층 (Conv4-5)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ ─ │ \ │ │ 눈 │ 코 │ │ 고양이 │
│ | │ / │ → │ 입 │ 귀 │ → │ 강아지 │
│엣지 │코너 │ │ 패턴/부분 │ │ 전체 객체 │
└─────────────┘ └─────────────┘ └─────────────┘5. 파라미터 계산
Conv2D(32, (3,3), input_shape=(28,28,1))
Parameters = (3 x 3 x 1 + 1) x 32 = 320
(kernel x channels + bias) x filtersCNN 파라미터 계산 예시 (MNIST):
| Layer | 계산 | 파라미터 |
|---|---|---|
| Conv1 (3x3, 1→32) | (3x3x1+1) x 32 | 320 |
| Conv2 (3x3, 32→64) | (3x3x32+1) x 64 | 18,496 |
| FC1 (3136→128) | 3136 x 128 + 128 | 401,536 |
| FC2 (128→10) | 128 x 10 + 10 | 1,290 |
| Total | 421,642 |
💡
비교: Dense만 사용 시 첫 층에서만 784 x 512 = 401,408 파라미터가 필요합니다. CNN은 가중치 공유로 훨씬 효율적입니다!
6. 대표 모델
| 모델 | 연도 | 파라미터 | 핵심 아이디어 |
|---|---|---|---|
| LeNet-5 | 1998 | 60K | CNN의 시작, 손글씨 인식 |
| AlexNet | 2012 | 60M | ImageNet 우승, GPU 학습, ReLU/Dropout |
| VGG16 | 2014 | 138M | 3x3 필터만 사용, 깊은 네트워크 |
| GoogLeNet | 2014 | 6.8M | Inception 모듈, 1x1 Conv |
| ResNet | 2015 | 25M | Skip Connection, 매우 깊은 학습 가능 |
| EfficientNet | 2019 | 5.3M | 효율적 스케일링, SOTA 성능 |
| MobileNet | - | 경량 | 모바일용 |
6.1 ResNet Skip Connection
x ──────────────┐
│ │
↓ │
┌─────┐ │
│Conv │ │
│ReLU │ │
│Conv │ │
└──┬──┘ │
│ │
↓ │
(+) ←───────────┘ F(x) + x
│
↓
ReLUSkip Connection은 기울기 소실 문제를 해결하여 100층 이상의 네트워크 학습을 가능하게 합니다.
from tensorflow.keras.applications import (
VGG16, ResNet50, InceptionV3, EfficientNetB0, MobileNetV2
)7. Transfer Learning
사전 학습된 모델 활용
| 전략 | 상황 |
|---|---|
| Feature Extraction | 적은 데이터 |
| Fine-tuning | 충분한 데이터 |
from tensorflow.keras.applications import VGG16
# 사전 학습 모델 로드 (ImageNet)
base_model = VGG16(weights='imagenet', include_top=False,
input_shape=(224, 224, 3))
# Feature Extraction: 동결
base_model.trainable = False
# 새 분류기 추가
model = models.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(256, activation='relu'),
layers.Dropout(0.5),
layers.Dense(num_classes, activation='softmax')
])8. Data Augmentation
학습 데이터 증강으로 과적합 방지
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
zoom_range=0.2
)
# 증강 데이터로 학습
model.fit(datagen.flow(X_train, y_train, batch_size=32),
epochs=50, validation_data=(X_val, y_val))9. CNN 설계 가이드
9.1 일반적인 패턴
1. 필터 수: 점점 증가
32 → 64 → 128 → 256
2. 공간 크기: 점점 감소
28 → 14 → 7 (Pooling으로)
3. 필터 크기: 3x3 권장 (VGG 이후 표준)
4. 활성화: ReLU (Conv 후), Softmax (마지막)
5. 정규화:
- BatchNorm: Conv 후
- Dropout: FC 층 (0.5)9.2 성능 향상 팁
| 문제 | 해결책 |
|---|---|
| 과적합 | Dropout, Data Augmentation, Early Stopping |
| 수렴 느림 | BatchNorm, Learning Rate Scheduler |
| 기울기 소실 | ReLU, Skip Connection (ResNet) |
| 메모리 부족 | Batch Size 줄이기, 모델 경량화 |
| 데이터 부족 | Transfer Learning, Data Augmentation |
코드 요약
from tensorflow.keras import models, layers
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Transfer Learning with MobileNetV2
base_model = MobileNetV2(weights='imagenet', include_top=False,
input_shape=(224, 224, 3))
base_model.trainable = False
model = models.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.3),
layers.Dense(num_classes, activation='softmax')
])
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# Data Augmentation
datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
horizontal_flip=True,
validation_split=0.2
)
# Train
history = model.fit(
datagen.flow(X_train, y_train, subset='training'),
validation_data=datagen.flow(X_train, y_train, subset='validation'),
epochs=30
)면접 질문 맛보기
- Convolution 연산의 장점은?
- Transfer Learning은 언제 사용하나요?
- Stride와 Padding의 역할은?
더 많은 면접 질문은 Premium Interviews (opens in a new tab)에서 확인하세요.
실습 노트북
💡
노트북에서 추가로 다루는 내용:
- Convolution 연산의 수동 구현과 시각화
- 다양한 필터(수직 엣지, 수평 엣지, 블러, 샤픈)의 효과
- Max Pooling 시각화와 크기 변화 확인
- PyTorch 코드 구조 예시
이전: 12. Neural Network | 다음: 14. NLP