Stochastic Depth 기초부터 배우기: 더 깊은 네트워크를 더 빠르게 학습시키기 위해 잔차 레이어 전체를 무작위로 드롭하기
요약
Stochastic Depth는 잔차 블록을 무작위로 드롭하여 깊은 네트워크의 학습 속도를 높이고 그래디언트 소실 문제를 해결하는 기술입니다. 각 레이어의 생존 확률을 깊이에 따라 선형적으로 조절하여 효율적인 학습을 유도합니다.
핵심 포인트
- 잔차 블록을 무작위로 드롭하여 네트워크를 일시적으로 짧게 만듦
- 항등 스킵(identity skip)을 통해 드롭 시에도 유효한 경로 유지
- 깊은 레이어일수록 낮은 생존 확률을 부여하는 선형 스케줄링 적용
- 학습 시에는 무작위 드롭, 테스트 시에는 모든 블록 유지 및 스케일링
100개 레이어로 구성된 ResNet은 학습 속도가 느리며, 초기 레이어로 가는 과정에서 여전히 그래디언트(gradient)가 소실됩니다. Stochastic Depth (Huang et al., 2016)는 무모해 보이는 트릭을 통해 이 두 가지 문제를 동시에 해결합니다. 바로 각 학습 단계에서 **잔차 블록(residual blocks) 전체를 무작위로 드롭(drop)**하는 것입니다. 드롭된 블록은 단순한 항등 바이패스(identity bypass)가 되므로, 해당 단계에서 네트워크는 더 '짧아'집니다. 즉, 계산 비용이 저렴해지고 그래디언트가 통과해야 할 비선형성(nonlinearities)이 줄어듭니다. 이는 드롭아웃(dropout)의 '레이어 전체를 드롭하는' 사촌 격인 기술입니다. 저는 블록 타워를 기초부터 구현한 데모를 만들었습니다. 한 줄씩 전체 과정을 살펴보겠습니다.
레이어를 드롭하는 것을 가능하게 하는 것은 항등 스킵(identity skip)입니다
일반적인 네트워크에서는 임의의 레이어를 삭제할 수 없습니다. 경로가 끊기기 때문입니다. Stochastic Depth가 작동하는 이유는 이미 항등 지름길(identity shortcut)인 y = x + F(x)를 가지고 있는 잔차(residual) 블록을 드롭하기 때문입니다. F를 아무것도 없는 상태로 설정하면 y = x가 남습니다. 이는 완벽하게 유효하며, 연결이 유지되고, 형태를 보존하는 변환입니다. 드롭된 블록은 구멍이 아니라, 잘 정의된 통과 경로(pass-through)입니다. 이것이 바로 이 기술이 특히 ResNet 계열의 기술인 이유입니다.
function block(x, F) { return add(x, F(x)); } // y = x + F(x)
// F를 완전히 드롭해도 여전히 유효한 네트워크가 유지됩니다: y = x (identity)
생존 확률은 깊이에 따라 선형적으로 감소합니다
모든 블록이 동일하게 드롭되어서는 안 됩니다. 초기 블록들은 저수준(low-level)의, 널리 재사용되는 특징을 학습하므로 이를 드롭하는 것은 파괴적입니다. 깊은 블록들은 더 전문화되어 있고 중복적(redundant)이므로 자유롭게 드롭될 수 있습니다. 따라서 각 블록 l은 첫 번째 블록의 ≈1에서 마지막 블록의 p_L(통상적으로 0.5)까지 선형적으로(linearly) 감소하는 유지 확률 p_l을 가집니다. 하나의 하이퍼파라미터인 p_L이 전체 스케줄을 제어합니다.
function survival(l, L, pL) {
return 1 - (l / L) * (1 - pL); // l = 1..L
}
...
순전파(Forward) 학습 — 블록당 하나의 베르누이(Bernoulli) 동전
각 훈련 단계(training step)에서, 모든 블록에 대해 독립적인 동전을 던집니다. 앞면(확률 p_l): 정상적으로 x + F(x)를 실행합니다. 뒷면: 브랜치(branch)를 완전히 건너뛰고 x를 그대로 통과시킵니다. 드롭된(dropped) 브랜치는 해당 단계에서 연산을 수행하지 않으며 그래디언트(gradient)를 받지 않습니다. 원본 논문에서 생존한 브랜치는 훈련 중에 스케일링(scaling)되지 않습니다 — 즉, 하드(hard) 0/1 게이트 방식입니다.
function trainBlock(x, F, p) {
if (Math.random() < p) return add(x, F(x)); // 생존: x + F(x)
else return x; // 드롭됨: 항등 함수 (identity)
...
테스트 시점(Test time) — 모든 블록을 유지하고 생존 확률로 스케일링
추론(inference) 시에는 무작위성이 허용되지 않습니다. 하나의 결정론적인(deterministic) 답을 원하기 때문입니다. 따라서 테스트 시점에는 아무것도 드롭되지 않습니다. 모든 블록이 실행되지만, 각 브랜치는 생존 확률에 따라 가중치가 부여되어 y = x + p_l·F(x)가 됩니다. 이는 각 블록의 기대 기여도(expected contribution)를 훈련 시 보았던 것과 일치하게 만듭니다 — 이는 뉴런에서 레이어 전체로 확장된, 드롭아웃(dropout)의 '훈련 시 드롭 / 테스트 시 스케일링' 원리와 정확히 일치합니다.
function testBlock(x, F, p) {
return add(x, scale(F(x), p)); // y = x + p * F(x) (드롭 없음)
}
기대 깊이(Expected depth) — 네트워크의 실제 깊이
각 블록이 독립적으로 생존하기 때문에, 활성화된 블록의 기대값은 단순히 생존 확률의 합인 E[depth] = Σ p_l이 됩니다. 0.5까지 선형 감소(linear decay)하는 경우 이는 약 0.75·L이 됩니다. 따라서 54개 블록의 ResNet은 평균적으로 약 40개 블록의 네트워크처럼 훈련되며, 유명한 1202층 버전은 단계마다 약 900층 버전처럼 동작합니다. 이것이 Stochastic Depth가 규제(regularise) 효과뿐만 아니라 실제 벽시계 시간(wall-clock time) 기준으로 더 빠르게 훈련되는 이유입니다.
function expectedDepth(L, pL) {
let e = 0;
for (let l = 1; l <= L; l++) e += survival(l, L, pL);
...
작동 원리: 암시적 앙상블(implicit ensemble) + 그래디언트 지름길(gradient shortcut)
두 가지 효과가 보상을 제공합니다. (1) $L$개의 블록이 있으면 2^L개의 가능한 유지/드롭(keep/drop) 서브 네트워크가 존재하며, 각 단계마다 서로 다른 네트워크를 최적화합니다. 최종 모델은 이 거대한 얕은 네트워크 군집의 평균처럼 동작합니다. 이는 앙상블 (ensemble)과 같이 강력한 규제 (regularisation) 효과를 제공하며, 이는 데모의 "sample ×25" 히스토그램이 보여주는 바와 같습니다. (2) 활성 경로 (active path)가 짧아지면 역전파 (backprop)가 통과해야 하는 비선형 분기 (nonlinear branches)가 줄어들므로, 초기 레이어로 전달되는 그래디언트 (gradients)가 강하게 유지되어 학습이 더 빠르게 수렴합니다. 이 두 가지가 결합되어 일반적인 잔차 네트워크 (residual net)보다 훨씬 더 깊은 네트워크를 학습할 수 있게 해줍니다. 논문에서는 CIFAR-10 데이터셋을 사용하여 1202-레이어 ResNet을 학습시켰으며, 일반 버전이 과적합 (overfit)되는 상황에서도 Stochastic Depth를 사용했을 때 성능이 _개선_되었습니다.
동전을 직접 던질 필요는 없습니다. Torchvision에는 StochasticDepth가 포함되어 있고, timm에서는 이를 DropPath라고 부릅니다. 각 잔차 블록 (residual block) 내부에서 블록별 드롭 확률 (1 − p_l, 깊이에 따라 감쇠됨)을 사용하여 드롭합니다. 이는 eval() 모드에서는 아무런 동작도 하지 않는 no-op이며, 아키텍처 변경이 필요하지 않습니다. 또한 ResNet, EfficientNet, ConvNeXt, 그리고 사실상 거의 모든 Vision Transformer의 표준 장비입니다.
from torchvision.ops import StochasticDepth # timm: from timm.models.layers import DropPath
class ResBlock(nn.Module):
...
이는 Dropout이나 DropConnect와 마찬가지로 "일반화를 위해 무언가를 드롭한다"는 동일한 계열에 속하지만, 그 입도 (granularity)가 레이어 전체 단위라는 점이 다릅니다.
블록 타워 위로 동전을 던져 네트워크가 짧아지는 것을 확인해 보세요:
https://dev48v.infy.uk/dl/day38-stochastic-depth.html
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기