CNN 백본 진화: AlexNet → VGG → GoogLeNet → ResNet
GoogLeNet Inception 모듈 — 4개 병렬 브랜치를 깊이 방향으로 결합
개요 — 3년간의 설계 철학 진화
2012년 AlexNet이 ILSVRC에서 기존 최고 성능 대비 10.9%p 격차로 우승하며 딥러닝 시대를 열었습니다. 이후 3년간 VGG, GoogLeNet, ResNet이 차례로 ImageNet 챔피언십을 가져가며 네트워크 설계 철학을 빠르게 발전시켰습니다. 이 4개 논문은 오늘날 모든 컴퓨터 비전 아키텍처의 직·간접 조상입니다.
| 모델 | 연도 | 깊이 | 파라미터 | Top-5 오류 | 핵심 혁신 |
|---|---|---|---|---|---|
| AlexNet | 2012 | 8 | 60M | 15.3% | ReLU, Dropout, GPU |
| VGG-16 | 2014 | 16 | 138M | 7.3% | 3×3 conv만 사용 |
| GoogLeNet | 2014 | 22 | 6.8M | 6.7% | Inception 모듈, 1×1 bottleneck |
| ResNet-152 | 2015 | 152 | 60M | 3.57% | 잔차(skip) 연결 |
AlexNet — ReLU·Dropout·GPU의 조합
AlexNet은 3가지 기술 혁신이 결합되어 이전 방법을 압도했습니다. ReLU: sigmoid 대비 기울기 소실 없이 6배 빠른 수렴. Dropout(p=0.5): 학습 중 랜덤으로 뉴런을 끄는 정규화 기법으로 공동 적응(co-adaptation) 방지. 데이터 증강: 좌우 반전, 무작위 자르기, 색상 변형으로 데이터를 2048배 증폭.
또한 두 GPU를 병렬로 활용해 메모리 한계를 극복했습니다. LRN(Local Response Normalization)은 이후 효과가 미미하다고 밝혀졌지만, GPU 병렬화 전략은 현대 딥러닝 인프라의 출발점이 됐습니다.
VGGNet — 3×3만으로, 단순함의 힘
Oxford VGG 팀의 핵심 인사이트: 3×3 convolution 2개를 쌓으면 7×7 convolution 1개와 동일한 수용 영역(receptive field)이지만 파라미터는 54% 적고 비선형성은 2배입니다. 이 원리로 더 작은 필터만으로 깊이를 늘렸습니다. 구조가 단순해서 다른 작업으로의 전이 학습 기반 모델로 오랫동안 활용됐습니다.
GoogLeNet (InceptionV1) — Inception 모듈과 1×1 bottleneck
"다양한 크기의 수용 영역을 동시에 봐야 한다." — 1×1, 3×3, 5×5 convolution과 MaxPool을 병렬 실행 후 결합하는 Inception 모듈이 핵심입니다. 1×1 convolution(bottleneck)으로 3×3·5×5 이전에 채널을 줄여 연산량을 1/10로 감소시킵니다. 덕분에 22 레이어임에도 6.8M 파라미터에 불과합니다.
ResNet — 스킵 연결이 깊이의 한계를 없애다
단순히 깊게 쌓으면 오히려 정확도가 낮아지는 성능 저하(Degradation) 문제. 원인은 기울기 소실이 아닌 최적화 어려움이었습니다. He et al.의 해결책: H(x) = F(x) + x. 네트워크가 H(x) 대신 잔차 F(x) = H(x) - x만 학습하게 합니다. shortcut 연결을 통해 기울기가 직접 흐르므로 152 레이어에서도 안정적 학습이 가능합니다.
왜 F(x)+x가 작동하는가?
항등 함수를 학습하려 할 때 F(x)=0만 학습하면 됩니다. 전체를 0으로 만드는 것보다 훨씬 쉽습니다.
Bottleneck 블록 (ResNet-50+)
1×1(채널 감소)→3×3→1×1(복원). 연산 효율을 높이면서 더 깊은 네트워크 가능.
💻 ResNet BasicBlock (PyTorch)
import torch, torch.nn as nn
class BasicBlock(nn.Module):
expansion = 1
def __init__(self, in_ch, out_ch, stride=1, downsample=None):
super().__init__()
self.conv1 = nn.Conv2d(in_ch, out_ch, 3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_ch)
self.relu = nn.ReLU(inplace=True)
self.conv2 = nn.Conv2d(out_ch, out_ch, 3, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(out_ch)
self.downsample = downsample # 형태 변화 시 1×1 conv
def forward(self, x):
identity = x
out = self.relu(self.bn1(self.conv1(x))) # F(x): 전반부
out = self.bn2(self.conv2(out)) # F(x): 후반부 (ReLU 없음)
if self.downsample is not None:
identity = self.downsample(x) # x를 차원에 맞춤
out = self.relu(out + identity) # H(x) = F(x) + x, 후 ReLU
return out
# ResNet 레이어 구성
def make_layer(in_ch, out_ch, n_blocks, stride=1):
ds = None
if stride != 1 or in_ch != out_ch:
ds = nn.Sequential(nn.Conv2d(in_ch, out_ch, 1, stride=stride, bias=False),
nn.BatchNorm2d(out_ch))
return nn.Sequential(BasicBlock(in_ch, out_ch, stride, ds),
*[BasicBlock(out_ch, out_ch) for _ in range(1, n_blocks)])
x = torch.randn(2, 64, 56, 56)
print(BasicBlock(64, 64)(x).shape) # torch.Size([2, 64, 56, 56])
💬 해설
이 4개 논문은 각각 하나의 핵심 아이디어를 탁월하게 증명했습니다. AlexNet은 GPU+ReLU+데이터 증강의 조합, VGG는 3×3만 쓰는 단순함, GoogLeNet은 효율성과 성능의 동시 달성, ResNet은 스킵 연결로 깊이의 한계 제거.
ResNet의 스킵 연결은 지금도 Transformer의 residual stream, U-Net의 스킵 연결, DenseNet에 살아있습니다. GoogLeNet의 1×1 bottleneck은 MobileNet, EfficientNet의 핵심 구성 요소입니다. 2012-2015년의 인사이트가 2025년에도 현역이라는 것이 이 논문들의 진짜 가치입니다.