CS231n Lecture 5 - Image Classification with CNNs

LECTURE 글 목록
목차

핵심 한 줄 정리

CNN은 작은 필터를 이미지 전체에 공유하며 적용해 공간 구조를 보존하고, 단순한 경계부터 복잡한 물체 특징까지 계층적으로 학습하는 신경망이다.

지금까지 배운 딥러닝의 기본 흐름

앞선 강의에서는 이미지 분류를 예제로 딥러닝 시스템을 구성하는 기본 요소를 배웠다. 전체 흐름은 다음과 같이 정리할 수 있다.

  1. 입력과 출력을 텐서로 표현한다.
  2. 입력으로부터 출력 점수를 계산하는 모델을 정의한다.
  3. 모델의 예측이 얼마나 나쁜지를 측정하는 손실 함수를 정의한다.
  4. 역전파로 손실에 대한 파라미터의 기울기를 계산한다.
  5. 경사하강법 기반 최적화 알고리즘으로 파라미터를 갱신한다.

이미지 분류에서는 입력 이미지 xx를 받아 각 클래스에 대한 점수 벡터 ss를 출력한다.

s=f(x;θ)s = f(x; \theta)

여기서 ff는 신경망이 나타내는 함수이고, θ\theta는 가중치와 편향을 포함한 학습 가능한 파라미터이다.

모델의 예측과 정답 사이의 차이는 손실 함수로 측정한다. 전체 학습 데이터에 대한 손실은 일반적으로 다음과 같이 표현할 수 있다.

L(θ)=1Ni=1NLi+λR(θ)L(\theta) = \frac{1}{N} \sum_{i=1}^{N} L_i + \lambda R(\theta)
  • NN은 학습 샘플의 개수이다.
  • LiL_iii번째 샘플의 데이터 손실이다.
  • R(θ)R(\theta)는 정규화 항이다.
  • λ\lambda는 정규화 강도를 조절하는 하이퍼파라미터이다.

역전파를 통해 θL\nabla_\theta L을 구한 뒤, 최적화 알고리즘을 사용하여 파라미터를 갱신한다. 가장 단순한 경사하강법의 갱신식은 다음과 같다.

θθηθL\theta \leftarrow \theta - \eta \nabla_\theta L

여기서 η\eta는 학습률이다. 실제 학습에서는 SGD with Momentum, RMSProp, Adam과 같은 최적화 알고리즘을 주로 사용한다.

%% title: 딥러닝 모델의 학습 흐름
%% caption: 순전파로 손실을 계산하고, 역전파로 구한 기울기를 이용해 파라미터를 반복해서 갱신한다.
flowchart LR
    input["입력 텐서 x"] --> model["모델 f(x; θ)"]
    model --> scores["클래스 점수 s"]
    scores --> loss["손실 L(θ)"]
    target["정답 y"] --> loss
    loss --> backward["역전파 ∇θL"]
    backward --> optimizer["최적화 알고리즘"]
    optimizer --> update["파라미터 갱신"]
    update --> model

이 과정은 이미지 분류에만 한정되지 않는다. 입력과 출력을 텐서로 표현하고, 미분 가능한 계산 그래프와 손실 함수를 정의할 수 있다면 이미지 생성, 언어 모델, 음성 인식 등 대부분의 딥러닝 문제에 같은 학습 방식을 적용할 수 있다.


수작업 특징 표현과 End-to-End Learning

딥러닝이 널리 사용되기 전에는 원본 픽셀을 바로 분류기에 넣기보다 사람이 설계한 특징 추출기를 먼저 적용하는 방식이 일반적이었다.

전체 구조는 다음과 같았다.

imagehandcrafted featuresclassifierscores\text{image} \rightarrow \text{handcrafted features} \rightarrow \text{classifier} \rightarrow \text{scores}

사람이 이미지에서 중요하다고 생각하는 정보를 직접 정의한 뒤, 그 특징 위에서 선형 분류기나 SVM을 학습하는 방식이다.

Color Histogram

색상 히스토그램은 이미지에 어떤 색상이 얼마나 포함되어 있는지를 나타내는 특징이다.

먼저 가능한 색상 공간을 여러 구간으로 나눈 뒤, 각 픽셀이 어느 구간에 속하는지 계산한다. 이후 각 색상 구간에 속한 픽셀 수를 세어 하나의 특징 벡터를 만든다.

예를 들어 사과의 숙성 여부를 판단하는 문제에서는 이미지에 빨간색과 초록색이 얼마나 포함되어 있는지가 유용한 정보가 될 수 있다.

색상 히스토그램은 이미지의 색상 분포를 잘 나타내지만 공간 정보를 대부분 제거한다. 빨간색 물체가 이미지의 왼쪽에 있든 오른쪽에 있든 색상 히스토그램은 동일할 수 있다.

Histogram of Oriented Gradients

Histogram of Oriented Gradients, 즉 HOG는 이미지의 색상보다 경계선의 방향과 형태에 집중하는 특징 표현이다.

이미지를 작은 영역으로 나눈 뒤, 각 영역에서 밝기가 가장 크게 변하는 방향을 계산한다. 이를 통해 수직선, 수평선, 대각선, 원형 구조와 같은 이미지의 국소적인 형태를 표현할 수 있다.

HOG는 물체의 윤곽과 구조를 잘 표현하지만 색상 정보는 대부분 사용하지 않는다.

여러 특징의 결합

과거에는 하나의 완벽한 특징을 찾기보다 색상 히스토그램, HOG 등 여러 특징을 추출하여 하나의 긴 특징 벡터로 연결하는 방식이 자주 사용되었다.

ϕ(x)=[ϕcolor(x)ϕHOG(x)ϕother(x)]\phi(x) = \begin{bmatrix} \phi_{\text{color}}(x) \\ \phi_{\text{HOG}}(x) \\ \phi_{\text{other}}(x) \end{bmatrix}

그다음 특징 벡터 ϕ(x)\phi(x)를 선형 분류기와 같은 학습 가능한 모델에 입력하였다.

이 방식의 한계는 특징 추출기의 대부분이 사람이 설계한 고정된 함수라는 점이다. 사람이 문제에서 중요한 요소를 잘못 판단하거나, 필요한 특징을 코드로 정확히 표현하지 못하면 분류기 성능에도 한계가 생긴다.

End-to-End Learning

신경망은 특징 추출 과정과 최종 분류 과정을 하나의 미분 가능한 모델로 구성한다.

imagelearned featuresclassifierscores\text{image} \rightarrow \text{learned features} \rightarrow \text{classifier} \rightarrow \text{scores}

모델 전체가 하나의 손실 함수를 최소화하도록 학습되므로, 특징 추출기의 가중치까지 데이터로부터 자동으로 결정된다.

수작업 특징 방식과 신경망 방식은 모두 원본 이미지를 입력받아 클래스 점수를 출력한다. 핵심적인 차이는 시스템의 어느 부분을 사람이 설계하고, 어느 부분을 데이터로부터 학습하는가에 있다.

구분수작업 특징 방식End-to-End 방식
특징 추출사람이 직접 설계한다.데이터로부터 학습한다.
분류기주로 학습한다.전체 모델과 함께 학습한다.
장점특징의 의미를 해석하기 쉽다.문제에 적합한 특징을 자동으로 찾을 수 있다.
한계사람의 직관과 설계 능력에 의존한다.많은 데이터와 계산량이 필요하다.

신경망에서도 사람이 완전히 사라지는 것은 아니다. 사람이 개별 특징을 직접 설계하지는 않지만, 어떤 연산을 어떤 순서로 배치할지, 채널 수와 계층 수를 어떻게 설정할지와 같은 네트워크 아키텍처는 여전히 사람이 결정해야 한다.

%% title: 수작업 특징과 End-to-End Learning 비교
%% caption: End-to-End 방식에서는 분류기뿐 아니라 특징 추출기까지 하나의 손실로 함께 학습한다.
flowchart LR
    subgraph manual["수작업 특징 방식"]
        image1["Image"] --> handcrafted["사람이 설계한 특징"]
        handcrafted --> classifier1["학습되는 분류기"]
        classifier1 --> scores1["Class Scores"]
    end
    subgraph endtoend["End-to-End 방식"]
        image2["Image"] --> learned["학습되는 특징 추출기"]
        learned --> classifier2["학습되는 분류기"]
        classifier2 --> scores2["Class Scores"]
        scores2 --> loss["Loss"]
        loss -. "Backpropagation" .-> learned
        loss -. "Backpropagation" .-> classifier2
    end

Fully Connected Network가 이미지에 적합하지 않은 이유

기존의 완전연결 계층은 이미지를 하나의 긴 벡터로 펼친 뒤 행렬을 곱한다.

CIFAR-10 이미지의 크기가 3×32×323 \times 32 \times 32라면, 이를 길이 3072의 벡터로 변환한다.

xR3×32×32xflatR3072x \in \mathbb{R}^{3 \times 32 \times 32} \rightarrow x_{\text{flat}} \in \mathbb{R}^{3072}

10개 클래스의 점수를 예측하려면 다음과 같은 가중치 행렬을 사용할 수 있다.

WR10×3072W \in \mathbb{R}^{10 \times 3072}

출력 점수는 다음과 같이 계산한다.

s=Wx+bs = Wx + b

이 방식에는 두 가지 중요한 문제가 있다.

공간 구조가 사라진다

이미지는 높이와 너비를 가진 2차원 구조이다. 가까이 있는 픽셀끼리는 서로 관련될 가능성이 높고, 특정 모양은 인접한 픽셀들의 배열로 나타난다.

그러나 이미지를 벡터로 펼치면 픽셀 간의 2차원 공간 관계가 모델 구조에 명시적으로 반영되지 않는다. 신경망이 공간 구조를 학습할 가능성은 있지만, 이를 위해 훨씬 많은 데이터와 파라미터가 필요하다.

입력 위치마다 별도의 가중치가 필요하다

완전연결 계층에서는 입력의 모든 위치가 서로 다른 가중치와 연결된다. 어떤 경계선이 이미지 왼쪽에 나타나는 경우와 오른쪽에 나타나는 경우를 서로 다른 패턴으로 취급한다.

하지만 이미지에서는 같은 특징이 어느 위치에 나타나더라도 같은 방식으로 처리하는 것이 자연스럽다. 예를 들어 고양이의 눈이 이미지 왼쪽에 있든 오른쪽에 있든 동일한 눈 검출기를 적용하는 것이 효율적이다.

CNN은 지역적인 연결과 가중치 공유를 통해 이 문제를 해결한다.


CNN의 기본 구조

Convolutional Neural Network는 이미지의 공간 구조를 유지하면서 처리하도록 설계된 신경망이다.

전형적인 CNN은 다음 연산을 조합하여 구성한다.

  • Convolution layer
  • Nonlinear activation
  • Pooling layer
  • Fully connected layer

고전적인 CNN에서는 합성곱 계층과 풀링 계층이 이미지에서 특징을 추출하고, 마지막의 완전연결 계층이 추출된 특징을 분류하였다.

imageConvReLUPoolFCscores\text{image} \rightarrow \text{Conv} \rightarrow \text{ReLU} \rightarrow \text{Pool} \rightarrow \cdots \rightarrow \text{FC} \rightarrow \text{scores}
CNN의 전형적인 구조
CNN의 전형적인 구조. Feature map의 면적은 pooling에서 줄고 채널 깊이는 convolution을 지나며 늘어난다. 오른쪽 세로 노드는 vector 계층을 나타낸다.
title: 실제 PyTorch CNN의 계산 그래프
caption: 위 구조를 nn.Conv2d, nn.ReLU, nn.MaxPool2d, nn.Linear로 구현한 뒤 torchview가 실제 forward pass에서 기록한 input·output shape이다. 점선 경계는 features와 classifier Sequential module을 구분한다.
source: /blog-assets/deep-learning/cs231n/lecture-5/tiny-cnn-torchview.svg

최근 구조에서는 완전연결 계층을 여러 개 사용하는 대신 global average pooling과 하나의 선형 분류기를 사용하는 경우도 많다. 구조가 달라지더라도 원본 픽셀부터 최종 분류 점수까지 전체 모델을 역전파로 학습한다는 점은 동일하다.

CNN의 역사적 위치

CNN의 기본 아이디어는 비교적 오래되었다. LeNet은 1990년대에 손글씨 숫자 인식을 위해 합성곱 신경망을 사용하였다.

2012년 AlexNet은 ImageNet 이미지 분류에서 큰 성능 향상을 보이며 딥러닝과 CNN의 확산을 이끌었다. 충분한 데이터와 GPU 계산 자원을 사용하면서 이전보다 훨씬 큰 CNN을 학습할 수 있게 된 것이 중요한 변화였다.

이후 CNN은 이미지 분류뿐 아니라 다음과 같은 문제에 널리 사용되었다.

  • Object detection
  • Semantic segmentation
  • Image captioning
  • Image generation
  • Super-resolution
  • Depth estimation

2020년 이후에는 Vision Transformer 계열이 대규모 비전 문제에서 강력한 성능을 보이며 CNN의 역할 일부를 대체하였다. 하지만 CNN은 계산 효율이 중요한 환경, 모바일 모델, 저수준 영상 처리, 하이브리드 모델 등에서 여전히 널리 사용된다.

CNN을 이해하면 이미지의 지역성, 가중치 공유, 수용 영역, 다운샘플링과 같은 비전 모델의 핵심 개념을 이해할 수 있다.


Fully Connected Layer를 Template Matching으로 이해하기

완전연결 계층의 각 출력은 입력 벡터와 가중치 벡터 사이의 내적으로 계산된다.

sj=wjTx+bjs_j = w_j^T x + b_j

여기서 wjw_jjj번째 출력에 대응하는 가중치 벡터이다.

두 벡터의 내적은 방향이 비슷할수록 커진다. 따라서 내적은 입력이 특정 템플릿과 얼마나 유사한지를 측정하는 연산으로 해석할 수 있다.

완전연결 계층에서는 각 wjw_j가 전체 입력 이미지와 같은 크기의 템플릿 역할을 한다. 각 출력 점수는 전체 이미지가 해당 템플릿과 얼마나 잘 일치하는지를 나타낸다.

문제는 하나의 템플릿이 이미지 전체를 한 번에 검사한다는 점이다. 특정 물체가 이미지의 어느 위치에 나타나는지에 따라 서로 다른 가중치가 필요하며, 물체의 위치 변화에 효율적으로 대응하기 어렵다.

합성곱 계층은 이 전역적인 템플릿 매칭을 지역적인 템플릿 매칭으로 바꾼다.


Convolution Layer

기본 직관

합성곱 계층은 작은 필터를 이미지의 여러 위치에 이동시키며 각 위치에서 내적을 계산한다.

입력 이미지가 다음 크기를 가진다고 하자.

XR3×32×32X \in \mathbb{R}^{3 \times 32 \times 32}

여기서 첫 번째 차원 3은 RGB 채널 수이고, 나머지 32×3232 \times 32는 공간 크기이다.

필터의 크기가 3×5×53 \times 5 \times 5라면 필터는 입력의 전체 채널을 포함하지만 공간적으로는 5×55 \times 5 영역만 확인한다.

WR3×5×5W \in \mathbb{R}^{3 \times 5 \times 5}

필터와 입력 이미지의 특정 3×5×53 \times 5 \times 5 영역 사이에서 내적을 계산하면 하나의 스칼라가 나온다. 이 값은 해당 이미지 영역이 필터가 나타내는 템플릿과 얼마나 잘 일치하는지를 나타낸다.

필터를 이미지 전체에 이동시키며 같은 계산을 반복하면 2차원 출력이 생성된다. 이를 activation map 또는 feature map이라고 한다.

하나의 필터는 하나의 Activation Map을 만든다

필터 하나를 이미지 전체에 적용하면 하나의 2차원 activation map이 만들어진다.

필터가 6개라면 각 필터가 별도의 activation map을 생성한다. 이들을 채널 방향으로 쌓으면 하나의 3차원 출력 텐서가 된다.

예를 들어 3×32×323 \times 32 \times 32 입력에 3×5×53 \times 5 \times 5 필터 6개를 padding 없이 stride 1로 적용하면 출력 크기는 다음과 같다.

YR6×28×28Y \in \mathbb{R}^{6 \times 28 \times 28}

공간 크기가 28이 되는 이유는 5×55 \times 5 필터를 32×3232 \times 32 이미지에 배치할 수 있는 위치가 각 축에서 28개이기 때문이다.

325+1=2832 - 5 + 1 = 28

출력 채널 수 6은 필터의 개수와 같다.

Convolution이 만드는 Feature-map Volume
Convolution이 만드는 Feature-map Volume. 필터 6개가 2차원 activation map을 하나씩 만들고, 이 맵들을 깊이 방향으로 쌓아 6 × 28 × 28 output volume을 만든다.

채널 전체를 확인하는 필터

합성곱 필터의 공간 크기는 입력보다 작지만, 채널 방향 크기는 입력 채널 수와 같아야 한다.

입력 채널 수가 CinC_{\text{in}}이고 커널 크기가 Kh×KwK_h \times K_w라면 필터 하나의 크기는 다음과 같다.

Cin×Kh×KwC_{\text{in}} \times K_h \times K_w

필터가 총 CoutC_{\text{out}}개라면 전체 가중치 텐서의 크기는 다음과 같다.

WRCout×Cin×Kh×KwW \in \mathbb{R}^{ C_{\text{out}} \times C_{\text{in}} \times K_h \times K_w }

각 필터는 하나의 출력 채널을 생성하므로 출력 채널 수는 항상 CoutC_{\text{out}}이다.


합성곱의 수식

배치 입력을 channel-first 형식으로 나타내면 입력 텐서의 크기는 다음과 같다.

XRN×Cin×Hin×WinX \in \mathbb{R}^{ N \times C_{\text{in}} \times H_{\text{in}} \times W_{\text{in}} }

각 기호의 의미는 다음과 같다.

  • NN은 batch size이다.
  • CinC_{\text{in}}은 입력 채널 수이다.
  • HinH_{\text{in}}은 입력 높이이다.
  • WinW_{\text{in}}은 입력 너비이다.
  • CoutC_{\text{out}}은 출력 채널 수이자 필터의 개수이다.
  • KhK_hKwK_w는 필터의 높이와 너비이다.
  • ShS_hSwS_w는 stride이다.
  • PhP_hPwP_w는 padding 크기이다.

합성곱 계층의 출력은 다음과 같이 계산할 수 있다.

Yn,o,i,j=bo+c=0Cin1u=0Kh1v=0Kw1Wo,c,u,vXn,c,iSh+uPh,jSw+vPwY_{n,o,i,j} = b_o + \sum_{c=0}^{C_{\text{in}}-1} \sum_{u=0}^{K_h-1} \sum_{v=0}^{K_w-1} W_{o,c,u,v} X_{n,c,iS_h+u-P_h,jS_w+v-P_w}
  • nn은 배치에서 이미지의 인덱스이다.
  • oo는 출력 채널 또는 필터의 인덱스이다.
  • iijj는 출력의 공간 위치이다.
  • bob_ooo번째 필터에 대응하는 편향이다.

Padding 영역 밖의 입력값은 일반적으로 0으로 처리한다.

딥러닝 라이브러리에서 convolution이라고 부르는 연산은 엄밀히 말하면 커널을 뒤집지 않는 cross-correlation인 경우가 많다. 커널 자체를 데이터로부터 학습하므로 실제 신경망 학습에서는 두 연산의 차이가 큰 문제가 되지 않는다.


Weight Sharing

합성곱에서는 하나의 필터를 입력의 모든 공간 위치에서 반복해서 사용한다. 이를 가중치 공유라고 한다.

예를 들어 수직 경계선을 검출하는 필터가 있다면, 동일한 필터가 이미지의 왼쪽, 중앙, 오른쪽에 모두 적용된다.

가중치 공유는 다음과 같은 장점을 가진다.

  • 같은 특징을 이미지의 모든 위치에서 검출할 수 있다.
  • 완전연결 계층보다 파라미터 수가 크게 줄어든다.
  • 이미지의 위치 변화에 더 자연스럽게 대응한다.
  • 지역적인 패턴을 학습하도록 구조적인 편향을 제공한다.

CNN이 이미지에 적합한 핵심 이유는 지역적 연결과 가중치 공유에 있다.

%% title: 하나의 필터를 모든 위치에서 공유하는 과정
%% caption: 위치마다 별도의 필터를 두지 않고 동일한 가중치 W를 반복 적용해 하나의 activation map을 만든다.
flowchart LR
    input["Input Feature Map"] --> left["왼쪽 Patch"]
    input --> center["가운데 Patch"]
    input --> right["오른쪽 Patch"]
    filter["Shared Filter W"] -.-> left
    filter -.-> center
    filter -.-> right
    left --> a1["Response a₁"]
    center --> a2["Response a₂"]
    right --> a3["Response a₃"]
    a1 --> output["Activation Map"]
    a2 --> output
    a3 --> output

Bias의 적용

합성곱 계층에서는 일반적으로 필터 하나당 하나의 편향을 사용한다.

필터 수가 CoutC_{\text{out}}이면 편향 벡터의 크기는 다음과 같다.

bRCoutb \in \mathbb{R}^{C_{\text{out}}}

oo번째 편향 bob_ooo번째 activation map의 모든 공간 위치에 동일하게 더해진다.

Yn,o,i,jYn,o,i,j+boY_{n,o,i,j} \leftarrow Y_{n,o,i,j} + b_o

따라서 편향은 공간 차원 전체에 broadcasting된다.


Parameter와 Hyperparameter

합성곱 계층을 이해할 때 학습되는 값과 사람이 미리 결정하는 값을 구분해야 한다.

Hyperparameter

하이퍼파라미터는 학습을 시작하기 전에 사람이 결정한다.

  • 필터 개수 CoutC_{\text{out}}
  • 커널 크기 Kh×KwK_h \times K_w
  • Stride
  • Padding
  • 계층의 개수
  • 각 계층의 채널 수

하이퍼파라미터는 가중치 텐서와 출력 텐서의 크기를 결정한다.

Parameter

파라미터는 학습 과정에서 역전파와 최적화 알고리즘에 의해 갱신된다.

  • 필터 내부의 각 가중치
  • 각 필터에 대응하는 편향

필터의 크기와 개수는 사람이 정하지만, 필터 내부의 값은 일반적으로 무작위로 초기화한 뒤 데이터로부터 학습한다.

손실에 대한 필터의 기울기는 다음과 같다.

LW\frac{\partial L}{\partial W}

이 기울기는 필터의 각 원소를 조금 변경했을 때 최종 손실이 얼마나 변하는지를 나타낸다.


학습 과정에서 필터가 갱신되는 방식

CNN의 학습도 다른 신경망과 동일한 반복 구조를 가진다.

  1. 미니배치 데이터를 네트워크에 입력한다.
  2. Forward pass로 클래스 점수를 계산한다.
  3. 손실 함수를 계산한다.
  4. Backward pass로 모든 파라미터의 기울기를 계산한다.
  5. Optimizer를 사용하여 필터와 편향을 갱신한다.
  6. 다음 미니배치에 대해 과정을 반복한다.

각 최적화 단계가 실행될 때마다 합성곱 필터의 값이 조금씩 달라진다. 충분한 학습이 진행되면 분류 문제에 유용한 색상, 경계선, 질감, 물체의 부분 구조 등을 검출하는 필터가 형성된다.


여러 Convolution Layer 쌓기

첫 번째 합성곱 계층의 출력은 다음 합성곱 계층의 입력이 될 수 있다.

예를 들어 첫 번째 계층의 출력이 다음 크기라고 하자.

X(1)R6×28×28X^{(1)} \in \mathbb{R}^{6 \times 28 \times 28}

다음 계층에서 필터 10개를 사용하려면 각 필터는 입력 채널 수 6을 모두 포함해야 한다.

W(2)R10×6×5×5W^{(2)} \in \mathbb{R}^{10 \times 6 \times 5 \times 5}

그 결과 두 번째 계층의 출력 채널 수는 10이 된다.

CNN은 이런 합성곱 계층을 여러 번 쌓아 점점 복잡한 특징을 추출한다.

합성곱 사이에 비선형 함수가 필요한 이유

합성곱은 입력에 대한 선형 연산이다. 편향을 포함하면 affine transformation이지만, 여러 합성곱 계층을 비선형 함수 없이 연속으로 적용해도 전체 연산은 하나의 선형 연산으로 합칠 수 있다.

W2(W1x)=(W2W1)xW_2(W_1x) = (W_2W_1)x

따라서 합성곱 계층을 여러 개 쌓는 것만으로는 모델의 표현력이 충분히 증가하지 않는다.

이를 해결하기 위해 합성곱 사이에 ReLU와 같은 비선형 활성화 함수를 넣는다.

X(l+1)=ReLU(W(l)X(l)+b(l))X^{(l+1)} = \operatorname{ReLU} \left( W^{(l)} * X^{(l)} + b^{(l)} \right)

비선형 함수가 추가되면 여러 계층을 쌓으면서 복잡한 비선형 함수를 표현할 수 있다.

전형적인 패턴은 다음과 같다.

ConvReLUConvReLU\text{Conv} \rightarrow \text{ReLU} \rightarrow \text{Conv} \rightarrow \text{ReLU}

CNN이 학습하는 특징의 계층 구조

첫 번째 계층

첫 번째 합성곱 계층은 원본 RGB 픽셀을 직접 입력받는다. 학습된 필터를 이미지처럼 시각화할 수 있으며, 일반적으로 다음과 같은 패턴이 나타난다.

  • 수직 경계선
  • 수평 경계선
  • 대각선 경계선
  • 색상 대비
  • 특정 색상의 작은 덩어리

첫 번째 계층은 이미지의 매우 국소적이고 단순한 특징을 학습한다.

중간 계층

중간 계층은 앞선 계층이 검출한 경계선과 색상 패턴을 조합한다.

  • 곡선
  • 모서리
  • 반복되는 질감
  • 원형 구조
  • 단순한 물체의 일부

깊은 계층

깊은 계층은 더 넓은 영역을 보고 여러 저수준 특징을 결합한다.

  • 바퀴
  • 얼굴의 일부
  • 문자 형태
  • 특정 물체의 구성 요소

이러한 필터를 사람이 직접 설계하는 것은 아니다. 최종 손실을 줄이기 위한 경사하강법의 결과로 각 계층이 서로 다른 수준의 특징을 학습한다.


Random Initialization과 Symmetry Breaking

모든 필터를 완전히 동일한 값으로 초기화하면 각 필터가 같은 출력을 생성한다. 같은 출력은 같은 기울기로 이어지므로 이후에도 모든 필터가 동일하게 갱신된다.

결과적으로 여러 필터를 사용하더라도 모두 같은 특징만 학습하게 된다.

이를 방지하기 위해 각 필터를 서로 다른 작은 무작위 값으로 초기화한다. 이를 symmetry breaking이라고 한다.

Wi(0)Wj(0)ijW_i^{(0)} \neq W_j^{(0)} \qquad i \neq j

초기 필터가 서로 다르면 각 필터가 서로 다른 출력과 기울기를 얻게 되고, 학습이 진행되면서 서로 다른 특징을 담당할 수 있다.


Convolution Output Size

입력의 공간 크기, 커널 크기, padding, stride에 따라 출력의 공간 크기가 결정된다.

입력 높이가 HinH_{\text{in}}, 커널 높이가 KhK_h, padding이 PhP_h, stride가 ShS_h이면 출력 높이는 다음과 같다.

Hout=Hin+2PhKhSh+1H_{\text{out}} = \left\lfloor \frac{ H_{\text{in}} + 2P_h - K_h }{ S_h } \right\rfloor + 1

출력 너비도 같은 방식으로 계산한다.

Wout=Win+2PwKwSw+1W_{\text{out}} = \left\lfloor \frac{ W_{\text{in}} + 2P_w - K_w }{ S_w } \right\rfloor + 1

출력 텐서의 전체 크기는 다음과 같다.

YRN×Cout×Hout×WoutY \in \mathbb{R}^{ N \times C_{\text{out}} \times H_{\text{out}} \times W_{\text{out}} }

Padding이 없는 경우

입력 크기가 7×77 \times 7이고 커널 크기가 3×33 \times 3이며 stride가 1이라면 출력 크기는 다음과 같다.

Hout=Wout=731+1=5H_{\text{out}} = W_{\text{out}} = \frac{7-3}{1}+1 = 5

따라서 출력 공간 크기는 5×55 \times 5가 된다.

합성곱 계층을 반복할수록 공간 크기가 계속 줄어드는 문제가 발생할 수 있다.


Padding

Padding은 입력 이미지의 가장자리에 가상의 값을 추가하는 방식이다. 가장 일반적인 방식은 0을 추가하는 zero padding이다.

입력의 각 방향에 크기 PP의 padding을 추가하면 공간 크기가 각 축에서 2P2P만큼 증가한다.

Hpadded=Hin+2PH_{\text{padded}} = H_{\text{in}} + 2P

Padding을 사용하면 합성곱 이후 공간 크기가 지나치게 빠르게 감소하는 것을 막을 수 있다. 또한 가장자리 픽셀도 여러 합성곱 연산에 참여할 수 있게 된다.

다만 zero padding은 이미지 바깥을 실제로 0이라고 가정하므로 경계 부근에 인공적인 패턴을 만들 수 있다. 실제 모델에서는 zero padding뿐 아니라 reflection padding이나 replication padding을 사용하는 경우도 있다.

공간 크기를 유지하는 Padding

커널 크기가 홀수이고 stride가 1이라면 다음 padding을 사용하여 입력과 출력의 공간 크기를 같게 만들 수 있다.

P=K12P = \frac{K-1}{2}

예를 들어 3×33 \times 3 커널에는 padding 1을 사용한다.

P=312=1P = \frac{3-1}{2} = 1

5×55 \times 5 커널에는 padding 2를 사용한다.

P=512=2P = \frac{5-1}{2} = 2

이러한 설정을 흔히 same padding이라고 부른다.


Stride

Stride는 필터가 한 번에 이동하는 간격이다.

Stride가 1이면 필터를 한 칸씩 이동한다. Stride가 2이면 두 칸씩 건너뛰며 이동한다.

입력 크기가 7×77 \times 7, 커널 크기가 3×33 \times 3, padding이 0, stride가 2라면 출력 크기는 다음과 같다.

Hout=Wout=732+1=3H_{\text{out}} = W_{\text{out}} = \left\lfloor \frac{7-3}{2} \right\rfloor + 1 = 3

따라서 출력은 3×33 \times 3이 된다.

Stride를 1보다 크게 설정하면 합성곱을 수행하면서 공간 크기를 줄일 수 있다. 이를 strided convolution이라고 한다.

Strided convolution은 다음 효과를 가진다.

  • Feature map을 다운샘플링한다.
  • 이후 계층의 계산량과 메모리 사용량을 줄인다.
  • 깊은 계층이 더 빠르게 넓은 입력 영역을 볼 수 있게 한다.

하지만 큰 stride는 중간 위치의 정보를 건너뛰므로 세부적인 공간 정보가 손실될 수 있다.

%% title: Padding과 Stride에 따른 출력 공간 크기
%% caption: 같은 7 × 7 입력과 3 × 3 커널을 사용해도 padding과 stride 설정에 따라 출력 크기가 달라진다.
flowchart LR
    input["Input 7 × 7"] --> valid["Conv 3 × 3 · P=0 · S=1"]
    input --> same["Conv 3 × 3 · P=1 · S=1"]
    input --> strided["Conv 3 × 3 · P=0 · S=2"]
    valid --> out1["Output 5 × 5"]
    same --> out2["Output 7 × 7"]
    strided --> out3["Output 3 × 3"]

Convolution 계산 예시

다음과 같은 입력이 있다고 하자.

XR3×32×32X \in \mathbb{R}^{3 \times 32 \times 32}

합성곱 계층의 설정은 다음과 같다.

  • 필터 수: 10
  • 커널 크기: 5×55 \times 5
  • Stride: 1
  • Padding: 2

출력 크기

출력 채널 수는 필터 수와 같으므로 10이다.

공간 크기는 다음과 같이 계산한다.

Hout=Wout=32+2251+1=32H_{\text{out}} = W_{\text{out}} = \frac{32 + 2 \cdot 2 - 5}{1} + 1 = 32

따라서 출력 텐서의 크기는 다음과 같다.

YR10×32×32Y \in \mathbb{R}^{10 \times 32 \times 32}

파라미터 수

필터 하나는 입력 채널 3개를 모두 포함하므로 필터 하나의 가중치 수는 다음과 같다.

355=753 \cdot 5 \cdot 5 = 75

필터 하나당 편향 하나를 추가하면 파라미터 수는 76개이다.

필터가 10개이므로 전체 파라미터 수는 다음과 같다.

10(355+1)=76010 \left( 3 \cdot 5 \cdot 5 + 1 \right) = 760

일반적인 합성곱 계층의 파라미터 수는 다음과 같다.

Cout(CinKhKw+1)C_{\text{out}} \left( C_{\text{in}}K_hK_w + 1 \right)

편향을 사용하지 않는다면 마지막 1을 제외한다.

연산량

출력 원소의 개수는 다음과 같다.

103232=1024010 \cdot 32 \cdot 32 = 10240

각 출력 원소를 계산할 때 길이 75의 내적을 수행한다.

따라서 필요한 multiply-accumulate 연산 수는 다음과 같다.

103232355=76800010 \cdot 32 \cdot 32 \cdot 3 \cdot 5 \cdot 5 = 768000

이를 약 0.7680.768 million MACs라고 표현할 수 있다. 곱셈과 덧셈을 각각 하나의 FLOP으로 계산한다면 FLOP 수는 대략 MAC 수의 두 배가 된다.

배치 크기 NN까지 고려한 일반적인 MAC 수는 다음과 같다.

NHoutWoutCoutCinKhKwN H_{\text{out}} W_{\text{out}} C_{\text{out}} C_{\text{in}} K_h K_w

합성곱 계층의 파라미터 수는 공간 크기와 무관하지만, 계산량은 출력 공간 크기에 비례한다.


Receptive Field

수용 영역은 특정 activation이 원본 입력의 어느 범위로부터 영향을 받을 수 있는지를 나타낸다.

첫 번째 계층에서 3×33 \times 3 합성곱의 출력 하나는 입력의 3×33 \times 3 영역만 본다. 하지만 합성곱을 여러 계층 쌓으면 깊은 계층의 activation은 더 넓은 입력 영역에 의존한다.

예를 들어 stride 1인 3×33 \times 3 합성곱을 두 번 적용하면 두 번째 계층의 출력 하나는 원본 입력의 5×55 \times 5 영역에 영향을 받는다.

3+(31)=53 + (3-1) = 5

세 번 적용하면 7×77 \times 7 영역에 영향을 받는다.

5+(31)=75 + (3-1) = 7

Stride가 모두 1이고 커널 크기가 KK로 동일하다면 LL개 계층 이후 수용 영역의 크기는 다음과 같다.

RL=1+L(K1)R_L = 1 + L(K-1)

3×33 \times 3 합성곱에서는 다음과 같다.

RL=1+2LR_L = 1 + 2L

따라서 stride 1만 사용하면 수용 영역은 계층 수에 대해 선형적으로 증가한다.

3 × 3 Convolution을 쌓을 때의 Receptive Field
3 × 3 Convolution을 쌓을 때의 Receptive Field. 도식의 사각형은 feature-map 크기가 아니라 한 activation이 원본 입력에서 볼 수 있는 영역을 나타낸다. 3 × 3 convolution을 지날 때마다 한 변이 2씩 늘어난다.

Stride를 고려한 수용 영역

각 계층의 stride가 다르면 수용 영역은 더 빠르게 증가한다. 정확하게 계산하려면 수용 영역 크기 RlR_l과 원본 입력에서 인접한 activation 사이의 간격 JlJ_l을 함께 추적한다.

초기값은 다음과 같다.

R0=1,J0=1R_0 = 1, \qquad J_0 = 1

ll번째 계층의 커널 크기가 KlK_l, stride가 SlS_l이면 다음과 같이 갱신한다.

Jl=Jl1SlJ_l = J_{l-1}S_l Rl=Rl1+(Kl1)Jl1R_l = R_{l-1} + (K_l-1)J_{l-1}

Stride가 2인 계층을 사용하면 깊은 계층의 인접한 activation이 원본 입력에서 더 멀리 떨어진 위치를 나타낸다. 그 결과 적은 계층만으로도 이미지 전체에 가까운 넓은 영역을 볼 수 있다.

엄밀하게는 네트워크 연결 구조상 영향을 줄 수 있는 전체 범위를 theoretical receptive field라고 한다. 실제로 출력에 큰 영향을 주는 입력 범위는 그보다 좁을 수 있으며, 이를 effective receptive field라고 구분하기도 한다.


1D, 2D, 3D Convolution

합성곱은 이미지에만 한정된 연산이 아니다. 필터를 이동시킬 공간 차원의 수에 따라 여러 종류의 합성곱을 정의할 수 있다.

1D Convolution

1차원 신호 위에서 필터를 한 방향으로 이동한다.

  • 시계열
  • 음성 파형
  • 토큰 시퀀스
  • 센서 데이터

2D Convolution

높이와 너비를 가진 2차원 신호 위에서 필터를 이동한다.

  • RGB 이미지
  • Feature map
  • Spectrogram

3D Convolution

깊이, 높이, 너비를 가진 3차원 공간에서 필터를 이동한다.

  • 비디오의 시공간 처리
  • CT와 MRI 같은 의료 영상
  • Voxel 데이터
  • 3차원 과학 시뮬레이션

여기서 3D convolution의 세 공간 차원과 RGB 이미지의 채널 차원은 구분해야 한다. 일반적인 2D convolution도 입력 채널을 모두 사용하지만 필터가 이동하는 방향은 높이와 너비 두 축이다.


Pooling Layer

Pooling은 feature map의 공간 크기를 줄이는 다운샘플링 연산이다.

합성곱 계층은 다운샘플링과 특징 추출을 동시에 수행할 수 있지만 계산량이 크다. Pooling은 학습 가능한 필터 없이 비교적 저렴하게 공간 크기를 줄인다.

입력이 다음과 같은 크기를 가진다고 하자.

XRC×H×WX \in \mathbb{R}^{C \times H \times W}

Pooling은 각 채널을 독립적으로 다운샘플링한다. 따라서 일반적인 pooling에서는 채널 수 CC가 바뀌지 않고 높이와 너비만 감소한다.

C×H×WC×H×WC \times H \times W \rightarrow C \times H' \times W'

Pooling 계층에는 일반적으로 학습 가능한 파라미터가 없다.

Max Pooling

Max pooling은 각 지역에서 가장 큰 값을 선택한다.

다음과 같은 4×44 \times 4 입력이 있다고 하자.

1321
4658
1232
0124

2×22 \times 2 커널과 stride 2를 적용하면 입력을 겹치지 않는 네 영역으로 나눈다.

각 영역의 최댓값은 다음과 같다.

  • 왼쪽 위 영역의 최댓값은 6이다.
  • 오른쪽 위 영역의 최댓값은 8이다.
  • 왼쪽 아래 영역의 최댓값은 2이다.
  • 오른쪽 아래 영역의 최댓값은 4이다.

따라서 출력은 다음과 같다.

68
24

수식으로는 다음과 같이 나타낼 수 있다.

Yc,i,j=max0u<Kh,0v<KwXc,iSh+u,jSw+vY_{c,i,j} = \max_{ 0 \leq u < K_h,\, 0 \leq v < K_w } X_{c,iS_h+u,jS_w+v}

Max pooling은 최댓값을 선택하므로 비선형 연산이다.

Average Pooling

Average pooling은 각 지역의 평균을 계산한다.

Yc,i,j=1KhKwu=0Kh1v=0Kw1Xc,iSh+u,jSw+vY_{c,i,j} = \frac{1}{K_hK_w} \sum_{u=0}^{K_h-1} \sum_{v=0}^{K_w-1} X_{c,iS_h+u,jS_w+v}

Average pooling은 선형 연산이다. 따라서 average pooling을 사용하더라도 별도의 ReLU와 같은 비선형 활성화 함수가 필요할 수 있다.

일반적인 설정

가장 흔한 pooling 설정은 다음과 같다.

  • Kernel size: 2×22 \times 2
  • Stride: 2
  • Padding: 0

이 설정은 높이와 너비를 각각 절반으로 줄인다.

C×H×WC×H2×W2C \times H \times W \rightarrow C \times \frac{H}{2} \times \frac{W}{2}
Max Pooling의 공간 Downsampling
Max Pooling의 공간 Downsampling. 위의 4 × 4 숫자 예시를 volume으로 보면, 채널 수는 1로 유지되고 각 2 × 2 영역의 최댓값만 남아 공간 면적이 1/4로 줄어든다.

Pooling에서는 일반적으로 padding을 사용하지 않는다. 특히 max pooling에서 0을 padding하면 입력이 음수일 때 경계 부근의 결과가 인위적으로 0으로 바뀔 수 있으므로 주의해야 한다.


Strided Convolution과 Pooling 비교

Strided convolution과 pooling은 모두 공간 크기를 줄일 수 있다.

구분Strided convolutionPooling
학습 가능한 파라미터있다.일반적으로 없다.
채널 수 변경가능하다.일반적으로 유지한다.
다운샘플링 방식학습된 필터로 결정한다.max, average 등 고정 연산을 사용한다.
계산량비교적 크다.비교적 작다.
비선형성합성곱 자체는 선형이다.Max pooling은 비선형이다.

고전적인 CNN에서는 합성곱과 pooling을 번갈아 사용하는 구조가 많았다.

ConvReLUConvReLUPool\text{Conv} \rightarrow \text{ReLU} \rightarrow \text{Conv} \rightarrow \text{ReLU} \rightarrow \text{Pool}

최근 CNN에서는 별도의 pooling 계층 대신 stride 2인 합성곱을 사용하여 다운샘플링하는 경우도 많다. Strided convolution은 다운샘플링 방식 자체를 데이터로부터 학습할 수 있다는 장점이 있다.


서로 다른 크기의 이미지를 Batch로 처리하기

하나의 배치에 포함된 텐서는 일반적으로 크기가 같아야 한다. 따라서 서로 다른 해상도나 종횡비를 가진 이미지를 그대로 하나의 배치로 묶을 수 없다.

이를 해결하는 대표적인 방법은 다음과 같다.

Resize

모든 이미지를 동일한 크기로 조정한다.

구현이 단순하지만 원본 종횡비가 바뀌면 물체의 모양이 왜곡될 수 있다.

Padding

원본 종횡비를 유지한 채 부족한 영역을 0이나 다른 값으로 채운다.

이미지의 형태는 보존되지만 padding 영역 때문에 불필요한 계산이 발생할 수 있다.

Crop

이미지 일부를 잘라 동일한 크기로 만든다.

학습 시 random crop을 사용하면 data augmentation 효과도 얻을 수 있지만 중요한 물체가 잘릴 가능성이 있다.

Aspect Ratio Bucketing

비슷한 종횡비와 해상도를 가진 이미지끼리 같은 그룹으로 묶는다. 각 학습 단계에서는 같은 그룹의 이미지만 하나의 배치로 구성한다.

이 방식은 이미지 왜곡과 불필요한 padding을 줄일 수 있어 대규모 학습 시스템에서 사용된다.


Translation Equivariance

CNN이 이미지의 공간 구조를 존중한다는 성질은 translation equivariance로 설명할 수 있다.

입력을 이동시키는 연산을 TΔT_\Delta라고 하고 합성곱 연산을 ff라고 하자. Translation equivariance는 다음 관계를 의미한다.

f(TΔX)=TΔf(X)f(T_\Delta X) = T_\Delta f(X)

입력을 오른쪽으로 이동시킨 뒤 합성곱을 수행한 결과와, 먼저 합성곱을 수행한 뒤 출력 feature map을 오른쪽으로 이동시킨 결과가 같다는 의미이다.

즉, 이미지에서 어떤 특징의 위치가 바뀌면 CNN의 feature map에서도 해당 특징의 위치가 같은 방향으로 바뀐다.

이 성질은 동일한 합성곱 필터를 모든 위치에 공유하기 때문에 나타난다. 수직 경계선이 이미지 왼쪽에 있든 오른쪽에 있든 같은 필터가 이를 검출한다.

다만 실제 네트워크에서는 다음 요소 때문에 완벽한 translation equivariance가 깨질 수 있다.

  • 이미지 경계와 padding
  • Stride가 1보다 큰 합성곱
  • Strided pooling
  • Resize와 crop
  • 위치에 따라 달라지는 연산

특히 stride가 2인 연산은 임의의 한 픽셀 이동에 대해 완전히 equivariant하지 않다. 일반적으로 stride의 배수만큼 이동할 때 더 자연스럽게 대응한다.

Equivariance와 Invariance의 차이

Translation equivariance는 입력이 이동하면 출력의 위치도 함께 이동하는 성질이다.

f(TΔX)=TΔf(X)f(T_\Delta X) = T_\Delta f(X)

Translation invariance는 입력이 이동해도 최종 출력이 변하지 않는 성질이다.

g(TΔX)=g(X)g(T_\Delta X) = g(X)

이미지 분류에서는 고양이가 이미지의 왼쪽에 있든 오른쪽에 있든 같은 클래스가 출력되어야 하므로 최종 예측은 이동에 대해 가능한 한 invariant한 것이 좋다.

CNN의 중간 feature map은 위치 정보를 보존하기 위해 equivariant하게 동작하고, 마지막의 pooling이나 전역 집계 과정은 위치 변화에 덜 민감한 최종 분류 결과를 만드는 역할을 한다.

%% title: Translation Equivariance에서 Invariance까지
%% caption: 입력 위치의 변화는 중간 feature map의 위치 변화로 이어지지만, 최종 집계 이후의 클래스 예측은 가능한 한 유지되어야 한다.
flowchart LR
    original["원본 이미지"] --> cnn1["CNN"]
    cnn1 --> feature1["원래 위치의 Feature Map"]
    feature1 --> aggregate1["Pooling · Aggregation"]
    aggregate1 --> class1["Class: Cat"]
    shifted["이동한 이미지"] --> cnn2["동일한 CNN"]
    cnn2 --> feature2["같이 이동한 Feature Map"]
    feature2 --> aggregate2["Pooling · Aggregation"]
    aggregate2 --> class2["Class: Cat"]
    original -. "TΔ" .-> shifted
    feature1 -. "TΔ" .-> feature2
    class1 -. "같은 예측" .-> class2

CNN에 내장된 Inductive Bias

CNN은 이미지 처리에 적합한 여러 가정을 네트워크 구조에 미리 포함한다.

Locality

가까운 픽셀끼리 강한 관계가 있을 것이라고 가정한다. 작은 커널을 사용하여 지역적인 패턴부터 학습한다.

Weight Sharing

같은 특징은 이미지의 어느 위치에서도 같은 방식으로 검출할 수 있다고 가정한다. 하나의 필터를 모든 공간 위치에서 공유한다.

Hierarchical Composition

단순한 특징을 조합하여 복잡한 특징을 만들 수 있다고 가정한다.

edgestexturespartsobjects\text{edges} \rightarrow \text{textures} \rightarrow \text{parts} \rightarrow \text{objects}

Approximate Translation Robustness

특징의 절대적인 위치보다 특징 자체의 존재가 중요하다고 가정한다.

이러한 가정을 inductive bias라고 한다. CNN은 완전연결 신경망보다 표현 가능한 함수의 범위를 구조적으로 제한하지만, 그 제한이 이미지의 성질과 잘 맞기 때문에 더 적은 파라미터와 데이터로 효율적으로 학습할 수 있다.


핵심 정리

CNN은 완전연결 신경망에 이미지의 공간 구조를 반영하기 위해 만들어진 구조이다.

완전연결 계층은 전체 입력과 전역 템플릿 사이의 내적을 계산한다. 반면 합성곱 계층은 작은 지역 템플릿을 이미지 전체에 공유하며 적용한다.

합성곱 필터의 개수는 출력 채널 수를 결정한다.

Cout=number of filtersC_{\text{out}} = \text{number of filters}

필터 하나는 입력의 모든 채널을 포함한다.

WfilterRCin×Kh×KwW_{\text{filter}} \in \mathbb{R}^{ C_{\text{in}} \times K_h \times K_w }

합성곱 계층의 파라미터 수는 다음과 같다.

Cout(CinKhKw+1)C_{\text{out}} \left( C_{\text{in}}K_hK_w + 1 \right)

출력 공간 크기는 kernel size, padding, stride에 의해 결정된다.

Hout=Hin+2PhKhSh+1H_{\text{out}} = \left\lfloor \frac{ H_{\text{in}} + 2P_h - K_h }{ S_h } \right\rfloor + 1 Wout=Win+2PwKwSw+1W_{\text{out}} = \left\lfloor \frac{ W_{\text{in}} + 2P_w - K_w }{ S_w } \right\rfloor + 1

합성곱은 선형 연산이므로 여러 합성곱 계층 사이에 ReLU와 같은 비선형 함수가 필요하다.

깊은 계층으로 갈수록 수용 영역이 커지며, 단순한 경계선부터 물체의 부분과 같은 복잡한 특징까지 계층적으로 학습한다.

Pooling과 strided convolution은 feature map을 다운샘플링하고 수용 영역을 빠르게 넓히는 데 사용된다.

CNN의 핵심적인 구조적 특성은 다음 네 가지이다.

  1. Local connectivity
  2. Weight sharing
  3. Hierarchical feature learning
  4. Translation equivariance

CNN은 사람이 경계선이나 색상 특징을 직접 설계하는 대신, 이미지 처리에 적합한 연산 구조만 정의하고 실제 필터의 값은 데이터와 경사하강법으로 학습하는 모델이다.