목차
핵심 한 줄 정리
CNN을 안정적으로 학습하려면 합성곱만 쌓는 것이 아니라 정규화, Dropout, 활성화 함수를 목적에 맞게 배치하고, 잔차 연결과 Kaiming 초기화로 깊은 신경망의 최적화를 안정화하며, 데이터 증강과 전이 학습, 올바른 디버깅 절차까지 하나의 학습 과정으로 연결해야 한다.
반드시 기억할 개념
CNN을 만든다는 것과 학습한다는 것
CNN을 다룰 때는 두 문제를 구분해야 한다.
- 어떤 계층을 어떤 순서와 형태로 연결해 아키텍처를 만들 것인가?
- 만들어진 아키텍처가 실제 데이터에서 안정적으로 학습되도록 어떻게 준비하고 검증할 것인가?
첫 번째 문제에는 합성곱, 풀링, 정규화, Dropout, 활성화 함수, 완전연결층이 포함된다. 두 번째 문제에는 가중치 초기화, 입력 정규화, 데이터 증강, 전이 학습, 하이퍼파라미터 탐색이 포함된다.
좋은 아키텍처라도 초기화와 학습률이 잘못되면 학습되지 않는다. 반대로 학습 과정이 좋아도 아키텍처의 수용 영역이나 잔차 경로가 문제에 맞지 않으면 충분한 표현력을 얻기 어렵다.
합성곱 계층 복습
RGB 이미지를 입력으로 사용하는 경우를 생각해 보자.
합성곱 계층에 필터가 개 있다면 각 필터의 깊이는 입력 채널 수인 과 같아야 한다. 각 필터가 공간 방향을 따라 이동하며 국소 영역과 내적을 계산하고 편향을 더한다.
는 필터 인덱스이다. 필터 하나가 활성화 맵 하나를 만들기 때문에 출력 채널 수는 필터 수인 이 된다.
다음 합성곱 계층의 필터는 앞 계층의 활성화 맵 전체를 봐야 하므로 필터 깊이도 이 된다. 일반적으로 합성곱 가중치의 shape는 다음과 같다.
풀링 계층 복습
풀링은 채널 수를 바꾸지 않고 공간 해상도를 줄인다. 예를 들어 윈도우와 스트라이드 를 사용해 최대 풀링을 적용할 수 있다.
평균 풀링이라면 같은 영역의 평균을 사용한다.
풀링은 높이와 너비를 줄여 계산량을 낮추고 수용 영역을 빠르게 넓힌다. 최대 풀링과 평균 풀링 중 무엇이 좋은지는 아키텍처와 문제에 따라 달라질 수 있다.
CNN의 기본 계층 구성
CNN은 보통 다음 종류의 계층을 조합한다.
- 합성곱 계층
- 풀링 계층
- 완전연결층
- 정규화 계층
- Dropout 계층
- 비선형 활성화 함수
합성곱과 완전연결층은 곱셈과 덧셈으로 이루어진 선형 연산이다. 선형 연산만 여러 번 연결하면 전체도 하나의 선형 함수로 합쳐진다.
따라서 합성곱이나 완전연결층 뒤에는 보통 비선형 활성화 함수를 둔다. 정규화는 활성값의 크기를 안정화하고, Dropout은 학습 중 무작위성을 넣어 규제한다.
정규화의 공통 구조
정규화 계층은 선택한 축을 기준으로 평균과 분산을 계산하고 입력을 표준화한다.
은 분모가 에 가까워지는 것을 막는 작은 상수이다. 표준화한 값을 그대로 사용하지 않고 학습 가능한 scale 와 shift 를 적용한다.
따라서 정규화는 무조건 평균 , 분산 로 고정하는 계층이 아니다. 일단 크기를 정돈한 뒤, 문제에 필요한 분포를 와 로 다시 학습한다.
정규화 방법은 통계를 계산하는 축이 다르다
CNN 활성값의 shape를 다음과 같이 두자.
은 배치 크기, 는 채널 수, 와 는 공간 차원이다. BatchNorm, LayerNorm, InstanceNorm, GroupNorm은 같은 정규화 식을 사용하지만 평균과 분산을 구하는 범위가 다르다.
| 방법 | 한 통계에 포함되는 축 | 통계가 분리되는 기준 |
|---|---|---|
| BatchNorm | 채널 마다 | |
| LayerNorm | 샘플 마다 | |
| InstanceNorm | 샘플 과 채널 마다 | |
| GroupNorm | 그룹 안의 | 샘플 과 채널 그룹마다 |
이 표에서 어떤 값들이 같은 평균과 분산을 공유하는지 이해하는 것이 핵심이다.
%% title: CNN 정규화 방법의 통계 계산 범위
%% caption: 모든 방법은 같은 표준화 식을 쓰지만, N × C × H × W 텐서에서 평균과 분산을 공유하는 축이 다르다.
flowchart TB
x["Activation X<br/>N × C × H × W"]
x --> bn["BatchNorm<br/>채널별로 N · H · W 통계"]
x --> ln["LayerNorm<br/>샘플별로 C · H · W 통계"]
x --> inn["InstanceNorm<br/>샘플·채널별로 H · W 통계"]
x --> gn["GroupNorm<br/>샘플·그룹별로 C/G · H · W 통계"]
bn --> affine["학습 가능한 γ, β"]
ln --> affine
inn --> affine
gn --> affine
Layer Normalization(LayerNorm)
단순한 벡터 입력의 shape가 다음과 같다고 하자.
LayerNorm은 각 샘플의 개 특성을 독립적으로 정규화한다.
CNN 텐서에서는 샘플 하나의 전체를 기준으로 통계를 계산하는 형태로 볼 수 있다.
각 샘플을 따로 처리하므로 다른 샘플이 배치에 들어오더라도 결과가 달라지지 않는다. 배치 크기가 작아도 안정적이며 Transformer에서 널리 사용된다.
Batch Normalization(BatchNorm)
BatchNorm은 채널 마다 미니배치와 공간 위치 전체를 모아 통계를 계산한다.
학습 중에는 현재 미니배치의 통계를 사용한다. 추론에서는 배치 구성에 따라 예측이 바뀌면 안 되므로 학습 중 누적한 평균과 분산을 사용한다.
BatchNorm은 CNN에서 오랫동안 널리 사용되었지만 배치 크기가 너무 작으면 통계가 불안정할 수 있다. LayerNorm과 GroupNorm은 배치 축에 의존하지 않는다는 차이가 있다.
InstanceNorm과 GroupNorm
InstanceNorm은 샘플과 채널마다 공간 차원 만 이용해 통계를 계산한다.
각 이미지의 채널 대비를 독립적으로 정규화하므로 스타일 변환과 이미지 생성에서 자주 사용되어 왔다.
GroupNorm은 채널을 개 그룹으로 나누고, 샘플별로 그룹 안의 채널과 공간 위치를 함께 정규화한다.
GroupNorm은 BatchNorm처럼 배치 크기에 의존하지 않으면서 채널 전체를 한 번에 묶는 LayerNorm보다 세분화된 통계를 사용한다.
입력 정규화와 정규화 계층은 다르다
입력 정규화는 데이터셋의 RGB 채널 평균과 표준편차를 이용해 모델에 넣기 전 이미지를 한 번 표준화하는 전처리이다. 정규화 계층은 신경망 내부 활성값을 각 계층에서 정규화하며 학습 가능한 , 를 갖는다.
두 작업 모두 값의 크기를 다루지만 위치와 목적이 다르다.
Dropout은 아키텍처 안에 들어가는 규제이다
Dropout은 학습 순전파마다 활성값 일부를 무작위로 으로 만든다. 제거 확률을 , 유지 확률을 라고 하자.
각 활성값에 적용할 마스크는 베르누이 분포에서 뽑는다.
와 는 자주 사용하는 설정이다. 어떤 활성값을 제거할지는 사람이 특징을 보고 선택하지 않으며 순전파마다 무작위로 달라진다.
Dropout의 직관
고양이 분류기의 마지막 특징이 다음과 같다고 하자.
- 귀
- 꼬리
- 털
- 발톱
학습 데이터에서 귀와 털만으로 고양이를 거의 맞힐 수 있다면 모델은 일부 특징 조합에 과도하게 의존할 수 있다. Dropout은 매 단계마다 일부 특징을 가리므로 특정 활성값이 항상 존재한다고 가정할 수 없게 만든다.
그 결과 여러 특징이 예측에 기여하는 중복 표현을 학습하도록 유도한다. 학습 문제는 더 어려워져 학습 손실이 높아질 수 있지만, 처음 보는 데이터에 대한 일반화는 좋아질 수 있다.
학습과 추론에서 Dropout의 동작
가장 단순한 Dropout은 학습할 때 마스크만 적용한다.
이때 기댓값은 다음과 같다.
추론에서는 모든 활성값을 사용하므로 기댓값을 맞추기 위해 를 곱한다.
실제 딥러닝 프레임워크는 보통 inverted dropout을 사용한다. 학습할 때 살아남은 활성값을 keep probability 로 나누고 추론에서는 별도의 크기 조정을 하지 않는다.
이 방식도 학습과 추론의 기댓값을 같게 만든다.
첫 번째 방식은 추론에서 활성값에 유지 확률을 곱하는 추론 시 크기 조정(test-time scaling)이다. 구현할 때는 라이브러리가 inverted dropout을 사용하는지 확인해야 이중으로 크기를 조정하는 실수를 피할 수 있다.
%% title: Inverted Dropout의 학습과 추론
%% caption: 학습 시에는 무작위 마스크를 적용하고 살아남은 활성값을 p로 나누며, 추론 시에는 모든 활성값을 그대로 사용한다.
flowchart LR
h["Activation h"]
subgraph train["Training"]
mask["m ~ Bernoulli(p)"] --> scale["m ⊙ h / p"]
end
subgraph test["Inference"]
identity["h 그대로 사용"]
end
h --> mask
h --> identity
scale --> expected1["E[output] = h"]
identity --> expected2["output = h"]
Dropout의 역전파
Inverted dropout의 기울기는 같은 마스크를 사용한다.
인 경로에서는 기울기도 이 된다. 해당 순전파에서 제거된 활성값과 연결된 가중치는 그 경로를 통해 갱신되지 않는다. ReLU에서 음수 입력의 기울기가 막히는 것과 계산 그래프 관점에서는 비슷하지만, Dropout 마스크는 무작위이고 학습에만 적용된다는 차이가 있다.
활성화 함수가 필요한 이유
합성곱과 완전연결층은 선형 연산이므로 비선형 활성화 함수 없이 여러 계층을 쌓아도 전체는 하나의 선형 매핑이다. 활성화 함수는 계층 사이에 비선형성을 넣어 복잡한 결정 경계를 표현하게 한다.
활성화 함수는 일반적으로 합성곱이나 완전연결층 직후에 배치한다.
Sigmoid와 기울기 소실
Sigmoid는 입력을 범위로 압축한다.
도함수는 다음과 같다.
가 커지면 sigmoid가 이나 에 포화되어 미분값이 에 가까워진다. 역전파에서 이런 작은 미분값이 여러 계층에 걸쳐 곱해지면 초기 계층의 기울기가 매우 작아진다.
이 기울기 소실이 은닉층의 활성화 함수로 sigmoid를 잘 사용하지 않게 된 주요 이유이다.
ReLU
ReLU는 다음과 같다.
도함수는 에서 , 에서 이다.
양수 영역에서는 기울기가 줄지 않고 계산도 단순한 최댓값 연산이므로 sigmoid보다 깊은 신경망을 학습하기 쉬워졌다. 그러나 음수 입력에서는 기울기가 완전히 이 되어 유닛이 계속 비활성화되는 dead ReLU 문제가 생길 수 있다.
GELU와 SiLU
GELU는 가우스 누적분포함수 를 이용한다.
큰 양수 입력에서는 에 가까워지고 큰 음수 입력에서는 에 가까워진다. ReLU처럼 에서 도함수가 갑자기 바뀌지 않고 부드럽게 변하며 Transformer에서 널리 사용된다.
형태의 활성화 함수는 SiLU 또는 Swish이다.
SiLU도 음수 영역에 작은 영이 아닌 기울기를 남기고 양수 영역에서는 거의 선형으로 동작한다. GELU와 SiLU는 식은 다르지만 그래프의 전체적인 모양이 비슷하다.
| 활성화 함수 | 핵심 특성 | 주요 문제 또는 용도 |
|---|---|---|
| Sigmoid | 출력이 | 양 끝에서 포화, 기울기 소실 |
| ReLU | 양수 영역의 도함수가 | 음수 영역의 기울기가 |
| GELU | 형태의 부드러운 게이팅 | Transformer에서 널리 사용 |
| SiLU | 형태의 부드러운 게이팅 | 현대 CNN에서도 자주 사용 |
CNN 아키텍처를 읽는 방법
아키텍처 도식의 블록은 계층 하나 또는 반복되는 계층 묶음을 나타낸다. 도식을 볼 때는 다음을 추적해야 한다.
- 텐서의 가 계층마다 어떻게 변하는가?
- 필터 크기, 스트라이드, 패딩은 얼마인가?
- 채널 수를 언제 늘리는가?
- 공간 해상도를 언제 줄이는가?
- 비선형 활성화 함수가 몇 번 들어가는가?
- shortcut 경로에서 더하는 텐서의 shape가 같은가?
최종 분류 계층의 출력 차원은 클래스 수와 같아야 한다.
ImageNet 분류라면 이다.
AlexNet과 VGG
AlexNet은 GPU를 이용해 ImageNet에서 대규모 CNN을 성공적으로 학습하며 딥러닝의 전환점이 된 아키텍처이다. VGG는 이 구조를 더 규칙적으로 만들고 깊게 확장했다.
VGG의 핵심 합성곱은 다음 설정을 반복한다.
- 커널 크기:
- 스트라이드:
- 패딩:
이 설정은 합성곱 전후의 공간 해상도를 유지한다.
몇 개의 합성곱을 쌓은 뒤 최대 풀링으로 해상도를 줄이고 채널을 늘린다. 분류 헤드에는 당시 구조 기준으로 차원 완전연결층들이 사용되고 마지막에 개 ImageNet 클래스 점수를 출력한다.
VGG는 계층 종류가 많아서 강력한 것이 아니라, 작은 합성곱과 풀링이라는 단순한 구성 요소를 규칙적으로 깊게 쌓아 강한 표현을 만든다는 점이 중요하다.
여러 합성곱을 쌓는 이유
스트라이드 인 합성곱은 계층 하나를 지날 때 수용 영역을 각 방향으로 한 칸씩 넓힌다. 따라서 수용 영역 한 변의 길이는 계층마다 씩 증가한다.
즉, 합성곱 세 개를 쌓으면 합성곱 하나와 같은 유효 수용 영역을 얻는다.
입력과 출력의 채널 수가 모두 로 일정하고 편향은 무시한다고 하자. 계층 세 개의 파라미터 수는 다음과 같다.
계층 하나는 다음과 같다.
작은 필터 세 개가 파라미터도 더 적다. 또한 중간에 활성화 함수가 세 번 들어가므로 큰 필터 하나보다 더 복잡한 비선형 매핑을 표현할 수 있다.
깊은 plain network의 성능 저하 문제
계층을 더 많이 쌓으면 표현 능력은 커진다. 더 깊은 모델은 일부 계층을 항등 함수로 만들면 얕은 모델과 같은 함수도 표현할 수 있기 때문이다.
그런데 plain CNN에서는 계층 모델이 계층 모델보다 테스트 오차뿐 아니라 학습 오차도 더 높은 현상이 관찰되었다. 학습 오차도 나쁘므로 단순한 과적합이 아니다.
함수 집합은 더 큰데 실제 최적화가 그 좋은 해를 찾지 못한 것이다. 이를 성능 저하 문제(degradation problem)라고 한다.
잔차 학습
일반 블록이 목표 매핑 를 직접 학습한다고 하자. ResNet은 변화량인 잔차 함수(residual function)를 학습한다.
따라서 블록 출력은 다음과 같다.
주 경로는 합성곱을 통해 를 계산하고 shortcut 경로는 를 그대로 전달한다. 만약 추가 계층이 필요 없다면 만 학습하면 출력이 가 된다.
합성곱 묶음 전체가 항등 매핑을 새로 학습하는 것보다 잔차를 에 가깝게 만드는 것이 더 쉬울 수 있다. 이것이 깊은 신경망이 최소한 얕은 신경망처럼 동작할 수 있는 경로를 아키텍처 안에 직접 넣는 아이디어이다.
잔차 블록의 shape
기본 잔차 블록은 다음 흐름으로 구성된다.
shortcut 경로의 를 더한 뒤 활성화 함수를 적용한다.
원소별 덧셈을 하려면 두 텐서의 shape가 같아야 한다.
스트라이드 , 패딩 인 합성곱을 사용하는 이유 중 하나가 spatial shape를 유지하기 위해서이다. 해상도나 채널 수가 바뀌는 스테이지에서는 projection shortcut을 사용할 수 있다.
는 보통 합성곱으로 shortcut 경로의 shape를 맞춘다.
%% title: ResNet Residual Block
%% caption: 주 경로는 잔차 F(x)를 학습하고 shortcut은 x를 덧셈 지점까지 직접 전달한다. Shape가 바뀌면 1 × 1 projection으로 shortcut을 맞춘다.
flowchart LR
x["Input x"] --> conv1["3 × 3 Conv"]
conv1 --> relu1["ReLU"]
relu1 --> conv2["3 × 3 Conv<br/>F(x)"]
conv2 --> add(("+"))
x --> shortcut["Identity<br/>or 1 × 1 Projection"]
shortcut --> add
add --> relu2["ReLU"]
relu2 --> y["Output y"]
ResNet에서 공간 해상도와 채널의 변화
ResNet은 같은 스테이지 안에서 잔차 블록을 반복할 때 스트라이드 을 사용한다. 따라서 feature map(특징 맵)의 공간 해상도와 채널 수가 유지된다.
스테이지가 바뀌는 첫 잔차 블록에서는 주 경로의 합성곱에 스트라이드 를 사용해 높이와 너비를 각각 절반으로 줄이고, 출력 채널 수는 보통 두 배로 늘린다.
대표적인 feature map 변화는 다음과 같다.
스테이지 전환에서는 주 경로와 shortcut 경로의 shape가 모두 달라진다. 따라서 shortcut 경로에도 보통 스트라이드 인 합성곱을 적용해 공간 해상도를 줄이고 채널 수를 로 맞춘다. 이렇게 해야 두 경로를 원소별로 더할 수 있다.
공간 면적은 원래의 이 되고 채널 수는 두 배가 되므로, feature map에 포함된 전체 스칼라 활성값 수는 절반으로 감소한다.
즉, 뒤쪽 스테이지로 갈수록 공간 위치의 수는 줄어들지만 각 위치에서 더 많은 채널을 사용해 높은 수준의 특징을 표현한다. 다만 활성값 수가 절반이 된다는 사실이 파라미터 수나 연산량도 반드시 절반이 된다는 뜻은 아니다. 합성곱의 비용은 입력 채널, 출력 채널, 커널 크기에도 영향을 받기 때문이다. 마지막에는 공간 정보를 벡터로 모아 분류 점수를 계산한다.
ResNet은 , , , , 계층과 같이 여러 깊이로 구성되었다. 계층을 늘릴수록 성능이 좋아졌지만 에서 처럼 매우 깊어질수록 추가 개선은 작아졌다. 모델 크기와 GPU 메모리도 실제 깊이 선택을 제한한다.
가중치 초기화가 중요한 이유
신경망을 학습하기 전 가중치 크기가 너무 작으면 계층을 지날수록 활성값과 기울기가 에 가까워질 수 있다. 반대로 너무 크면 활성값이 계층마다 커져 오버플로나 기울기 폭발로 이어질 수 있다.
특성 차원이 인 계층 완전연결 신경망을 생각해 보자. 정규분포에서 뽑은 가중치에 을 곱해 초기화하면 계층이 깊어질수록 활성값의 평균과 표준편차가 작아질 수 있다. 초기화 크기를 처럼 키우면 반대로 활성값이 급격히 커질 수 있다.
좋은 초기화는 순전파 활성값과 역전파 기울기의 크기가 계층을 지나도 크게 변하지 않게 만드는 것을 목표로 한다.
Kaiming 초기화
ReLU 신경망에서 널리 사용하는 Kaiming 초기화는 입력 유닛 수인 에 따라 가중치 분산을 정한다.
즉, 표준편차는 다음과 같다.
ReLU가 음수 활성값을 제거한다는 점을 반영해 분산이 계층마다 지나치게 줄거나 커지지 않도록 만든다.
완전연결층에서 은 입력 차원이다.
합성곱 계층에서는 커널 하나가 보는 입력 수이다.
예를 들어 커널과 입력 채널 을 사용하면 다음과 같다.
정규화 계층이 활성값 크기를 보정하더라도 초기화는 여전히 최적화의 시작점과 기울기 흐름에 영향을 준다.
이미지 입력 정규화
이미지 데이터셋에서는 학습 세트의 RGB 채널별 평균과 표준편차를 계산한다.
모델에 넣기 전에 각 채널을 표준화한다.
평균과 표준편차는 검증이나 테스트 세트를 포함하지 않고 학습 세트에서만 계산해야 한다. ImageNet 사전학습 모델을 사용할 때는 모델이 학습 중 사용한 ImageNet 정규화 값을 그대로 쓰는 것이 일반적이다.
데이터 증강의 목적
데이터 증강은 라벨을 유지하는 변환을 학습 이미지에 무작위로 적용한다.
학습 목적함수는 변환에 대한 기댓값으로 볼 수 있다.
같은 이미지를 여러 번 보더라도 매번 다른 형태가 들어가므로 모델이 학습 예시를 그대로 암기하기 어려워진다. Dropout과 마찬가지로 학습을 어렵게 만들지만 일반화를 높이는 규제이다.
좌우 반전과 도메인 지식
일상 사물 분류에서는 좌우 반전이 라벨을 대체로 유지한다. 그러나 텍스트 이미지를 좌우로 뒤집으면 읽을 수 없게 되고, 상하 반전은 일반적인 자연 이미지에서 사물의 방향을 비현실적으로 만들 수 있다.
반대로 현미경 이미지나 위에서 촬영한 이미지처럼 방향이 고정되지 않은 데이터에서는 상하 반전이나 회전이 타당할 수 있다. 데이터 증강은 무조건 많이 쓰는 것이 아니라 해당 문제에서 라벨을 보존하는 변환인지 확인해야 한다.
무작위 크기 조정과 잘라내기(RandomResizedCrop)
모델 입력이 일 때는 다음 과정을 흔히 사용한다.
- 원본 이미지의 짧은 변을 로 크기 조정한다.
- 종횡비를 유지한 채 긴 변도 같은 비율로 바꾼다.
- 크기가 조정된 이미지에서 영역을 무작위로 잘라낸다.
예를 들어 이미지의 짧은 변을 으로 바꾸면 긴 변도 같은 비율로 줄어든다. 그다음 영역을 잘라낸다.
이 방식은 사물의 크기와 위치가 달라져도 같은 범주로 인식하도록 만든다. 라이브러리에서는 보통 RandomResizedCrop으로 제공된다.
색상 변형(ColorJitter)과 영역 지우기(RandomErasing)
ColorJitter는 밝기, 대비, 채도 등을 무작위로 바꾼다. 모델이 특정 조명이나 색 균형에만 의존하지 않도록 한다.
RandomErasing 또는 Cutout은 이미지 일부를 검은색이나 회색 영역으로 가린다. 카메라가 가려지거나 사물 일부가 보이지 않는 환경에서 견고성을 높일 수 있다.
좋은 데이터 증강 범위는 이미지를 충분히 다양하게 만들면서도 사람이 보았을 때 원래 라벨이 유지되는 정도이다. 변환이 너무 강하면 라벨 잡음을 직접 만들어 학습을 방해한다.
추론 시 데이터 증강(Test-time augmentation)
추론에서 크기 조정, 잘라내기, 반전을 적용한 여러 이미지를 각각 모델에 넣고 예측을 평균낼 수도 있다.
추론 시 데이터 증강은 경우에 따라 약 에서 의 추가 성능을 만들 수 있다. 다만 추론을 여러 번 수행하므로 지연 시간과 연산 비용이 늘어나며, 변환 수가 많아질수록 추가 이득은 줄어든다.
CNN의 특징 계층
CNN의 초기 계층은 경계, 방향, 단순한 질감 같은 국소 특징을 학습한다. 뒤쪽 계층은 이 특징을 조합해 사물의 부분과 범주 수준의 표현을 만든다.
사전학습된 CNN을 다음처럼 나눌 수 있다.
는 백본이고 는 마지막 분류 계층 직전의 특징 벡터이다. 의미상 같은 범주의 이미지는 원시 픽셀 공간보다 이 특징 공간에서 가까운 경향이 있다.
전이 학습: 특징 추출기로 사용하기
새 데이터셋이 작다면 대규모 데이터셋으로 사전학습된 백본을 고정하고 마지막 분류 헤드만 새로 학습할 수 있다.
ImageNet 모델의 클래스 헤드를 제거하고 새 데이터셋의 클래스 수에 맞는 헤드를 붙인다. 새 헤드는 Kaiming 초기화와 같은 방법으로 초기화하고, 백본 가중치는 갱신하지 않는다.
이 경우 사전학습된 CNN은 과거의 수작업 특징 추출기처럼 동작하지만, 특징 자체가 대규모 데이터에서 학습되었다는 차이가 있다.
전이 학습: full fine-tuning
새 데이터셋이 충분히 크면 사전학습된 가중치에서 시작해 백본과 헤드를 모두 갱신하는 것이 일반적으로 더 좋은 성능을 낸다.
무작위 초기화에서 시작하는 것보다 대규모 사전학습에서 이미 얻은 일반적인 시각 표현을 활용할 수 있다.
데이터셋 크기와 도메인 유사도에 따른 선택
| 목표 데이터셋 | 사전학습 데이터와 유사함 | 사전학습 데이터와 다름 |
|---|---|---|
| 작음 | 백본을 고정하고 선형 헤드부터 학습 | 더 가까운 사전학습 모델을 찾는 것이 중요 |
| 큼 | full fine-tuning | 사전학습과 처음부터 하는 학습을 모두 비교 |
ImageNet 사전학습 특징은 일상 사물에 잘 맞지만 화성 이미지처럼 분포가 크게 다른 데이터에서는 효과가 줄 수 있다. 사전학습 모델도 학습 데이터의 편향을 갖고 있기 때문이다.
작고 도메인도 매우 다른 데이터셋은 가장 어려운 경우이다. 관련 도메인의 사전학습 모델을 찾거나 도메인 적응 방법을 고려해야 한다.
LoRA처럼 모든 기존 가중치를 직접 바꾸지 않고 low-rank update만 학습하는 parameter-efficient fine-tuning (PEFT)도 있다. 전체 가중치를 갱신하기 어려울 때 적은 수의 파라미터만으로 모델을 조정할 수 있는 방법이다.
학습 디버깅의 첫 단계: 작은 데이터를 암기시키기
모델이 학습되지 않을 때 가장 먼저 전체 데이터셋과 복잡한 규제를 붙잡고 있으면 원인을 찾기 어렵다. 학습 예시 하나 또는 아주 작은 부분집합만 사용해 손실을 거의 까지 낮출 수 있는지 확인한다.
모델에 충분한 표현력이 있는데 작은 데이터도 암기하지 못한다면 다음 문제를 의심할 수 있다.
- 순전파 또는 역전파 구현 오류
- 라벨과 데이터 정렬 오류
- 지나치게 작거나 큰 학습률
- 잘못된 손실 계산
- 기울기가 끊긴 파라미터
- 학습/평가 모드 설정 오류
이 단계에서는 데이터 증강, 강한 규제, Dropout처럼 암기를 방해하는 요소를 잠시 끄는 것이 원인을 분리하는 데 도움이 된다.
학습률을 먼저 찾기
작은 데이터에서 전체 과정이 동작하는 것을 확인한 뒤 학습률을 넓은 범위에서 시험한다. 보통 선형 척도가 아니라 로그 척도로 탐색한다.
한 epoch 정도의 짧은 실행으로 다음을 본다.
- 손실이 전혀 줄지 않는가?
- 손실이 발산하거나
NaN이 되는가? - 초기에 빠르게 줄어든 뒤 안정적으로 계속 감소하는가?
가장 빠른 순간 감소만 보는 것이 아니라 지속적으로 안정된 감소를 보이는 영역을 찾는 것이 중요하다.
학습과 검증 곡선 읽기
학습 정확도와 검증 정확도가 함께 계속 올라가면 아직 더 학습할 여지가 있다. 학습 성능은 좋아지는데 검증 성능이 정체되거나 나빠지면 과적합이 시작된 것이다.
이 경우 다음을 고려할 수 있다.
- 더 강한 규제
- 더 많은 데이터
- 더 나은 데이터 증강
- 조기 종료
- 더 작은 모델
학습과 검증 성능이 모두 낮으면 과적합보다는 과소적합, 최적화 실패, 부족한 학습을 먼저 의심해야 한다.
Random search가 grid search보다 유리한 이유
하이퍼파라미터 두 개 중 하나만 성능에 큰 영향을 준다고 하자. Grid search는 중요하지 않은 축의 같은 값들을 반복해서 확인하느라 중요한 축을 적은 수의 값으로만 시험할 수 있다.
Random search는 각 실험에서 모든 하이퍼파라미터를 새로 뽑으므로 같은 실험 횟수에서 중요한 축의 더 다양한 값을 확인할 가능성이 높다.
학습률처럼 값의 범위가 넓은 항목은 로그 균등분포에서 뽑는 것이 적절하다.
Coarse random search로 좋은 영역을 찾은 뒤 그 주변을 더 좁게 탐색하는 방식이 실용적이다.
CNN 학습의 전체 흐름
CNN 학습의 전체 과정을 순서대로 정리하면 다음과 같다.
- 합성곱, 정규화, 활성화 함수, 풀링을 조합해 아키텍처를 정의한다.
- 깊은 신경망에는 잔차 연결을 사용해 항등 경로를 만든다.
- ReLU 계열 활성화 함수에 맞는 Kaiming 초기화를 사용한다.
- 사전학습 모델이라면 요구되는 RGB 정규화를 적용한다.
- 학습 데이터에 라벨을 보존하는 데이터 증강을 적용한다.
- 데이터셋 크기와 도메인 유사도에 따라 고정된 백본 또는 full fine-tuning을 선택한다.
- 작은 샘플에 과적합시켜 구현과 학습률을 점검한다.
- 학습과 검증 곡선을 비교해 과소적합과 과적합을 구분한다.
- Random search로 하이퍼파라미터를 탐색한다.
- 테스트 세트는 모든 선택이 끝난 뒤 최종 평가에만 사용한다.
과제에서 확인할 것
정규화 축
텐서에서 BatchNorm, LayerNorm, InstanceNorm, GroupNorm이 각각 어느 축으로 평균과 분산을 계산하는지 직접 표시한다.
학습 가능한 scale과 shift
정규화 역전파에서 와 도 기울기를 받고 갱신되는 파라미터인지 확인한다.
Dropout 학습/평가 모드
프레임워크의 Dropout이 inverted dropout을 사용하는지 확인하고, train()과 eval()에서 출력이 어떻게 달라지는지 작은 텐서로 실험한다.
Dropout 기울기
순전파에서 마스크가 이 된 위치의 기울기도 이 되는지 확인한다. 같은 마스크가 역전파에 사용되어야 한다.
활성화 함수의 기울기
Sigmoid, ReLU, GELU, SiLU의 입력 구간별 도함수를 비교하고 큰 양수 또는 음수 입력에서 기울기가 어떻게 달라지는지 확인한다.
수용 영역과 파라미터 수
스트라이드 인 합성곱 세 개의 수용 영역이 인지 계산하고, 와 의 파라미터 수를 비교한다.
잔차 덧셈의 shape
주 경로와 shortcut 경로의 가 같은지 확인한다. Shape가 다르면 projection shortcut이 필요한 이유를 점검한다.
Kaiming 초기화
완전연결층과 합성곱 계층에서 을 각각 계산하고 가중치 표준편차가 인지 확인한다.
데이터 증강의 라벨 보존
좌우 반전, 상하 반전, 무작위 잘라내기, ColorJitter, RandomErasing이 현재 데이터셋에서 라벨을 유지하는 변환인지 이미지를 직접 확인한다.
전이 학습 범위
고정된 백본에서는 백본 파라미터의 기울기와 가중치가 변하지 않는지 확인한다. Full fine-tuning과 검증 성능도 비교한다.
소규모 샘플 과적합
학습 예시 하나나 작은 배치의 손실을 거의 으로 만들 수 있는지 확인한다. 실패하면 전체 학습 전에 데이터, 손실, 기울기, 학습률을 점검한다.
학습과 검증 곡선
두 곡선을 함께 그려 최적화 실패, 과소적합, 과적합을 구분하고 규제 강도나 학습 시간을 조정한다.
하이퍼파라미터 random search
학습률을 로그 척도에서 추출하고 grid search와 같은 실험 횟수를 사용했을 때 탐색되는 값의 다양성을 비교한다.