Residual Connection
잔차 연결 / Skip Connection
입력을 출력에 더하는 스킵 연결. 깊은 네트워크 학습 안정화. ResNet, Transformer의 핵심 구조.
잔차 연결 / Skip Connection
입력을 출력에 더하는 스킵 연결. 깊은 네트워크 학습 안정화. ResNet, Transformer의 핵심 구조.
Residual Connection(잔차 연결)은 신경망에서 입력을 변환된 출력에 직접 더하는 구조입니다. 수식으로 표현하면 output = F(x) + x로, 레이어가 원본 입력(x)과 학습된 변환(F(x))의 합을 출력합니다. 이를 통해 네트워크가 "배워야 할 것"만 학습하면 되어 훈련이 쉬워집니다.
2015년 Microsoft Research의 Kaiming He가 발표한 ResNet 논문에서 처음 도입되었습니다. 당시 깊은 네트워크(50층 이상)에서 발생하던 "성능 저하 문제(degradation problem)"를 해결하여 152층 ResNet이 ImageNet 대회에서 인간 수준을 처음으로 넘었습니다.
핵심 원리는 그래디언트 하이웨이입니다. 역전파 시 그래디언트가 덧셈 연산을 통해 직접 흐를 수 있어 기울기 소실(vanishing gradient) 문제가 완화됩니다. 100층이 넘는 깊은 네트워크도 안정적으로 학습됩니다. 또한 항등 매핑(identity mapping)을 기본값으로 가지므로 최악의 경우에도 입력을 그대로 전달합니다.
현대 딥러닝의 거의 모든 아키텍처에 사용됩니다. Transformer의 Multi-Head Attention과 Feed-Forward 블록 모두 잔차 연결을 사용하고, Vision Transformer(ViT), BERT, GPT 등 대부분의 최신 모델에 필수적으로 포함됩니다.
import torch
import torch.nn as nn
class ResidualBlock(nn.Module):
"""기본 Residual Block (ResNet 스타일)"""
def __init__(self, channels: int):
super().__init__()
self.conv1 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn1 = nn.BatchNorm2d(channels)
self.conv2 = nn.Conv2d(channels, channels, 3, padding=1)
self.bn2 = nn.BatchNorm2d(channels)
self.relu = nn.ReLU(inplace=True)
def forward(self, x: torch.Tensor) -> torch.Tensor:
identity = x # 원본 입력 저장
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out += identity # 잔차 연결: F(x) + x
out = self.relu(out)
return out
class TransformerResidual(nn.Module):
"""Transformer 스타일 Residual + LayerNorm"""
def __init__(self, d_model: int, dropout: float = 0.1):
super().__init__()
self.norm = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x: torch.Tensor, sublayer_output: torch.Tensor) -> torch.Tensor:
# Pre-LayerNorm 방식 (GPT 스타일)
return x + self.dropout(sublayer_output)
# 사용 예시
block = ResidualBlock(64)
x = torch.randn(1, 64, 32, 32)
output = block(x)
print(f"입력: {x.shape}, 출력: {output.shape}") # 동일한 shape
"레이어를 더 깊게 쌓으려면 Residual Connection 필수입니다. 20층 넘어가면 잔차 연결 없이는 학습이 안 되거나 성능이 오히려 떨어져요. Transformer 블록처럼 Pre-LN + Residual 조합이 안정적이에요."
"Residual Connection은 그래디언트가 skip path를 통해 직접 흐를 수 있게 해서 기울기 소실 문제를 해결합니다. ResNet에서 처음 도입되었고, 지금은 Transformer의 모든 블록에 사용됩니다. output = F(x) + x 형태로 항등 매핑이 기본값이라 최악의 경우에도 손실이 없어요."
"Loss가 수렴 안 되는데 혹시 잔차 연결이 빠진 거 아니에요? 깊은 네트워크에서 residual 없으면 그래디언트가 뒤쪽 레이어까지 제대로 안 전달돼요. 코드에서 += identity 부분 확인해보세요."
입력과 출력의 shape이 다르면 직접 덧셈이 불가능합니다. Projection layer(1x1 conv 또는 Linear)를 사용해 차원을 맞춰야 합니다.
Pre-LN(Residual 전에 정규화)과 Post-LN(Residual 후에 정규화)은 학습 안정성에 큰 차이가 있습니다. GPT는 Pre-LN, 원본 Transformer는 Post-LN입니다.
차원이 변경되는 경우 1x1 Conv나 Linear layer로 projection하고, 깊은 네트워크에서는 Pre-LN 방식이 학습에 더 안정적입니다.