Skip to main content

합성곱과 풀링 — CNN의 핵심 연산

CNN의 두 가지 핵심 연산인 합성곱(Convolution)과 풀링(Pooling)의 수학적 원리와 PyTorch 구현을 다룹니다.

핵심 아이디어

합성곱 연산은 **작은 필터(커널)**를 이미지 위에서 슬라이딩하며, 지역적 패턴(에지, 코너, 텍스처)을 탐지합니다. 완전 연결층(FC)과 달리 파라미터를 공유하므로, 파라미터 수가 이미지 크기에 독립적입니다.

동작 방식

합성곱 연산

입력 X\mathbf{X}에 커널 K\mathbf{K}를 적용하는 2D 합성곱: (XK)[i,j]=mnX[i+m,j+n]K[m,n](\mathbf{X} * \mathbf{K})[i, j] = \sum_{m}\sum_{n} \mathbf{X}[i+m, j+n] \cdot \mathbf{K}[m, n]

출력 크기 계산

Output Size=Input SizeKernel Size+2×PaddingStride+1\text{Output Size} = \frac{\text{Input Size} - \text{Kernel Size} + 2 \times \text{Padding}}{\text{Stride}} + 1 예시: 입력 32x32, 커널 3x3, 패딩 1, 스트라이드 1: 323+2×11+1=32\frac{32 - 3 + 2 \times 1}{1} + 1 = 32

구현

import torch
import torch.nn as nn

# 합성곱 레이어
conv = nn.Conv2d(
    in_channels=3,     # 입력 채널 (RGB = 3)
    out_channels=16,   # 출력 채널 (필터 개수)
    kernel_size=3,     # 커널 크기 3×3
    stride=1,          # 이동 간격
    padding=1,         # 제로 패딩 (same padding)
)

x = torch.randn(1, 3, 32, 32)  # (배치, 채널, 높이, 너비)
out = conv(x)
print(f"입력: {x.shape} → 출력: {out.shape}")
# 입력: (1, 3, 32, 32) → 출력: (1, 16, 32, 32)

# 파라미터 수 확인
params = sum(p.numel() for p in conv.parameters())
print(f"파라미터 수: {params}")  # 3×3×3×16 + 16(bias) = 448

풀링

풀링(Pooling)은 특성 맵의 공간적 크기를 줄여 연산량을 감소시키고, 이동 불변성을 부여합니다.
# Max Pooling: 영역 내 최대값 선택
maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
x = torch.randn(1, 16, 32, 32)
out = maxpool(x)
print(f"MaxPool: {x.shape}{out.shape}")
# (1, 16, 32, 32) → (1, 16, 16, 16)

# Average Pooling: 영역 내 평균값
avgpool = nn.AvgPool2d(kernel_size=2, stride=2)

# Global Average Pooling: 전체 공간을 1×1로 축소
gap = nn.AdaptiveAvgPool2d(1)
out = gap(torch.randn(1, 512, 7, 7))
print(f"GAP: {out.shape}")  # (1, 512, 1, 1)

CNN 블록 패턴

def conv_block(in_ch, out_ch):
    """Conv → BatchNorm → ReLU → MaxPool 기본 블록"""
    return nn.Sequential(
        nn.Conv2d(in_ch, out_ch, kernel_size=3, padding=1),
        nn.BatchNorm2d(out_ch),
        nn.ReLU(inplace=True),
        nn.MaxPool2d(2, 2),
    )

# 간단한 CNN
simple_cnn = nn.Sequential(
    conv_block(3, 32),     # (3, 32, 32) → (32, 16, 16)
    conv_block(32, 64),    # (32, 16, 16) → (64, 8, 8)
    conv_block(64, 128),   # (64, 8, 8) → (128, 4, 4)
    nn.AdaptiveAvgPool2d(1),
    nn.Flatten(),
    nn.Linear(128, 10),
)

관련 기술 비교

연산특징용도
Conv2d지역적 패턴 추출모든 CNN
Depthwise Conv채널별 독립 합성곱경량 모델 (MobileNet)
Dilated Conv확장된 수용 영역시맨틱 세그멘테이션
Transposed Conv업샘플링생성 모델 (GAN, VAE)
1x1 합성곱은 공간 차원은 유지하면서 채널 수만 변경합니다. 채널 간 정보 혼합, 차원 축소(bottleneck), 비선형성 추가에 사용되며, Network in Network와 Inception 모듈에서 핵심적인 역할을 합니다.

참고 논문

논문핵심 기여연도
Gradient-Based Learning Applied to Document Recognition (LeCun et al.)LeNet-5, 합성곱+풀링 구조 정립1998
Network In Network (Lin et al.)1x1 합성곱, Global Average Pooling2013

다음 문서