컨볼루션
Convolution
이미지 처리에서 필터를 적용하는 연산. CNN의 핵심 구성 요소로 특징 추출에 사용.
Convolution
이미지 처리에서 필터를 적용하는 연산. CNN의 핵심 구성 요소로 특징 추출에 사용.
컨볼루션(Convolution)은 입력 데이터에 필터(커널)를 슬라이딩하며 적용하여 특징을 추출하는 수학적 연산입니다. 딥러닝에서는 CNN(Convolutional Neural Network)의 핵심 연산으로, 이미지의 에지, 텍스처, 패턴 등 계층적 특징을 자동으로 학습합니다.
컨볼루션 연산은 신호 처리 분야에서 오래전부터 사용되었지만, 딥러닝에서의 혁신은 1989년 Yann LeCun의 LeNet에서 시작되었습니다. 2012년 AlexNet이 ImageNet 대회에서 압도적 성능을 보이며 딥러닝 혁명을 촉발했고, 이후 VGGNet, ResNet, EfficientNet 등 다양한 CNN 아키텍처가 발전했습니다. 현재는 Vision Transformer(ViT)와 경쟁하지만, 여전히 효율성과 해석 가능성 측면에서 CNN이 선호되는 영역이 많습니다.
컨볼루션의 핵심 원리는 파라미터 공유와 지역 연결성입니다. 동일한 필터가 이미지 전체를 스캔하므로 파라미터 수가 대폭 감소하고, 학습된 필터는 위치에 관계없이 동일한 패턴을 탐지합니다(평행 이동 불변성). 필터 크기(예: 3x3, 5x5), 스트라이드(이동 간격), 패딩, 채널 수가 주요 하이퍼파라미터입니다. 다층 컨볼루션을 통해 저수준(에지)에서 고수준(물체) 특징까지 계층적으로 추출됩니다.
실무에서 컨볼루션은 이미지 분류, 객체 탐지, 시맨틱 분할, 의료 영상 분석 등 컴퓨터 비전의 기반 기술입니다. 2025년 현재 ConvNeXt, EfficientNetV2 같은 현대적 CNN은 ViT와 비슷한 성능을 더 적은 데이터와 연산으로 달성합니다. 1D 컨볼루션은 시계열, 음성 처리에, Graph Convolution은 분자 구조, 소셜 네트워크 분석에 활용됩니다.
PyTorch를 활용한 CNN 이미지 분류 구현:
# CNN 이미지 분류 모델 (PyTorch)
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
"""
CIFAR-10 분류를 위한 CNN 모델
입력: 32x32x3 이미지
"""
def __init__(self, num_classes=10):
super().__init__()
# Conv Block 1: 3 -> 32 채널
self.conv1 = nn.Conv2d(
in_channels=3,
out_channels=32,
kernel_size=3, # 3x3 필터
padding=1, # same padding
stride=1
)
self.bn1 = nn.BatchNorm2d(32)
# Conv Block 2: 32 -> 64 채널
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.bn2 = nn.BatchNorm2d(64)
# Conv Block 3: 64 -> 128 채널
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.bn3 = nn.BatchNorm2d(128)
# Pooling
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# Fully Connected Layers
# 32 -> 16 -> 8 -> 4 (3번의 pooling 후)
self.fc1 = nn.Linear(128 * 4 * 4, 256)
self.fc2 = nn.Linear(256, num_classes)
self.dropout = nn.Dropout(0.5)
def forward(self, x):
# Block 1: Conv -> BN -> ReLU -> Pool
x = self.pool(F.relu(self.bn1(self.conv1(x)))) # 32x32 -> 16x16
# Block 2
x = self.pool(F.relu(self.bn2(self.conv2(x)))) # 16x16 -> 8x8
# Block 3
x = self.pool(F.relu(self.bn3(self.conv3(x)))) # 8x8 -> 4x4
# Flatten
x = x.view(x.size(0), -1) # (batch, 128*4*4)
# FC Layers
x = self.dropout(F.relu(self.fc1(x)))
x = self.fc2(x)
return x
# 모델 생성 및 구조 확인
model = SimpleCNN(num_classes=10)
print(model)
# 입력 테스트
dummy_input = torch.randn(1, 3, 32, 32)
output = model(dummy_input)
print(f"\n입력: {dummy_input.shape} -> 출력: {output.shape}")
컨볼루션 연산의 시각적 이해:
# 컨볼루션 연산 시각화
import torch
import torch.nn.functional as F
import numpy as np
# 5x5 입력 이미지 (1채널)
input_image = torch.tensor([
[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8],
[5, 6, 7, 8, 9]
], dtype=torch.float32).unsqueeze(0).unsqueeze(0) # (1, 1, 5, 5)
# 3x3 에지 탐지 필터 (소벨 필터)
sobel_x = torch.tensor([
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]
], dtype=torch.float32).unsqueeze(0).unsqueeze(0) # (1, 1, 3, 3)
# 컨볼루션 적용
output = F.conv2d(input_image, sobel_x, padding=1)
print("입력 이미지 (5x5):")
print(input_image.squeeze().numpy())
print("\n소벨 필터 (3x3):")
print(sobel_x.squeeze().numpy())
print("\n컨볼루션 결과:")
print(output.squeeze().numpy())
# 다양한 설정 비교
print("\n=== 컨볼루션 설정별 출력 크기 ===")
for padding in [0, 1]:
for stride in [1, 2]:
out = F.conv2d(input_image, sobel_x, padding=padding, stride=stride)
print(f"padding={padding}, stride={stride} -> 출력 크기: {out.shape[-2:]})")
# 출력 크기 공식: (W - K + 2P) / S + 1
# W=5, K=3 -> padding=1, stride=1: (5-3+2)/1+1 = 5
# W=5, K=3 -> padding=0, stride=2: (5-3+0)/2+1 = 2
주요 CNN 아키텍처 성능 비교 (ImageNet 기준):
| 모델 | 년도 | 파라미터 | Top-1 정확도 | 특징 |
|---|---|---|---|---|
| AlexNet | 2012 | 60M | 57.1% | 딥러닝 혁명의 시작 |
| VGG-16 | 2014 | 138M | 71.5% | 3x3 필터 반복 사용 |
| ResNet-50 | 2015 | 25M | 76.1% | Skip Connection 도입 |
| EfficientNet-B7 | 2019 | 66M | 84.4% | 복합 스케일링 |
| ConvNeXt-L | 2022 | 198M | 87.5% | 현대화된 CNN |
* Vision Transformer(ViT-L)는 86.4% 수준, ConvNeXt가 ViT와 경쟁 가능함을 입증
태스크에 비해 너무 깊은 네트워크는 과적합되고 추론 시간이 늘어납니다. 데이터셋 크기와 복잡도에 맞는 아키텍처를 선택하세요. CIFAR-10에는 ResNet-18이면 충분합니다.
사전학습된 모델의 입력 크기(예: 224x224)와 실제 데이터 크기가 다르면 성능이 저하됩니다. 적절한 리사이징과 전처리(정규화 등)가 필수입니다.
ImageNet 사전학습 모델로 시작하여 전이학습하세요. 작은 데이터셋에서는 특징 추출(Feature Extraction)만, 큰 데이터셋에서는 전체 파인튜닝을 권장합니다. 데이터 증강(Augmentation)도 필수입니다.