CS231n Lecture 4 - Neural Networks and Backpropagation

LECTURE 글 목록
목차

핵심 한 줄 정리

Neural network는 여러 linear transformation 사이에 nonlinearity를 넣어 복잡한 함수를 표현하고, backpropagation은 chain rule을 이용해 loss가 각 parameter에 미치는 영향을 효율적으로 계산하는 방법이다.

이전 강의와의 연결

Lecture 3에서는 loss function을 정의하고, regularization과 optimization으로 좋은 weight를 찾는 방법을 봤다.
하지만 지금까지의 모델은 여전히 linear classifier라서, 선 하나로 나눌 수 없는 데이터에는 한계가 있다.

이제 Lecture 4에서는 이 한계를 넘기 위해 여러 개의 linear layer 사이에 nonlinearity를 넣는 neural network를 본다.


Two-layer Neural Network

기본 형태:

h=max(0,W1x)h = \max(0, W_1x) s=W2hs = W_2h

한 줄로 쓰면:

s=W2max(0,W1x)s = W_2 \max(0, W_1x)
  • xx: input vector
  • W1W_1: input -> hidden layer weight
  • hh: hidden layer activation
  • W2W_2: hidden -> output layer weight
  • ss: output score
  • max(0,)\max(0, \cdot): ReLU activation

Bias 포함:

h=max(0,W1x+b1)h = \max(0, W_1x + b_1) s=W2h+b2s = W_2h + b_2

Activation Function

Activation function의 역할:

  • Linear transformation 사이에 nonlinearity를 추가한다.
  • 복잡한 decision boundary를 만들 수 있게 한다.
  • Neural network가 nonlinear problem을 풀 수 있게 한다.

ReLU:

ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x)

Piecewise form:

ReLU(x)={xif x>00if x0\text{ReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ 0 & \text{if } x \le 0 \end{cases}

ReLU gradient:

ddxReLU(x)={1if x>00if x<0\frac{d}{dx}\text{ReLU}(x) = \begin{cases} 1 & \text{if } x > 0 \\ 0 & \text{if } x < 0 \end{cases}

주의
x=0x = 0에서는 미분 불가능하지만, 구현에서는 보통 0 또는 1 중 하나로 처리한다.


Dead Neuron

ReLU의 문제:

  • 입력이 계속 음수이면 output이 계속 0이다.
  • Gradient도 0이므로 weight update가 잘 안 된다.
  • 이 상태를 dead neuron이라고 한다.

Leaky ReLU:

LeakyReLU(x)={xif x>0αxif x0\text{LeakyReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha x & \text{if } x \le 0 \end{cases}
  • α\alpha: 작은 양수
  • 음수 영역에서도 gradient가 완전히 0이 되지 않는다.

Sigmoid와 Tanh

Sigmoid:

σ(x)=11+ex\sigma(x) = \frac{1}{1 + e^{-x}}
  • output range: 00부터 11 사이이다.

Tanh:

tanh(x)=exexex+ex\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
  • output range: 1-1부터 11 사이이다.

주의:

  • 값을 좁은 범위로 squash한다.
  • 입력 절댓값이 커지면 gradient가 작아진다.
  • Vanishing gradient 문제가 생길 수 있다.
  • Hidden layer에서는 보통 ReLU 계열을 많이 쓴다.

Fully Connected Network와 MLP

MLP 구조:

h1=ϕ(W1x+b1)h_1 = \phi(W_1x + b_1) h2=ϕ(W2h1+b2)h_2 = \phi(W_2h_1 + b_2) s=W3h2+b3s = W_3h_2 + b_3
  • ϕ\phi: activation function
  • h1h_1, h2h_2: hidden layer activation
  • ss: output score

핵심:

  • Fully connected network는 이전 layer의 모든 neuron이 다음 layer의 모든 neuron과 연결된 구조이다.
  • Layer가 많아지면 표현력은 커진다.
  • 하지만 학습 난이도와 overfitting 위험도 커진다.

Network Capacity와 Regularization

Hidden neuron 수가 많아지면:

  • model capacity가 커진다.
  • 더 복잡한 function을 표현할 수 있다.
  • decision boundary가 복잡해질 수 있다.
  • overfitting 위험이 커진다.

강의 핵심:

  • 보통 network size 자체를 주된 regularizer로 쓰지는 않는다.
  • 어느 정도 큰 network를 두고 regularization strength를 조절하는 경우가 많다.

Computational Graph

Computational graph:

  • node: 연산
  • edge: 값이 흐르는 방향
  • input에서 loss까지 계산 과정을 graph로 표현한다.

예시:

s=f(x,W)s = f(x, W) L=Ldata(s,y)+R(W)L = L_{\text{data}}(s, y) + R(W)

장점:

  • 복잡한 함수를 작은 연산 단위로 나눌 수 있다.
  • 각 node의 local gradient만 계산하면 된다.
  • Chain rule로 전체 gradient를 구할 수 있다.

Backpropagation

Forward pass:

  • input -> output 방향으로 값을 계산한다.

Backward pass:

  • loss -> input 방향으로 gradient를 전파한다.

용어:

  • upstream gradient:

    • 뒤쪽 node에서 현재 node로 들어오는 gradient이다.
  • local gradient:

    • 현재 node의 output을 input에 대해 미분한 값이다.
  • downstream gradient:

    • 현재 node가 앞쪽 node로 전달하는 gradient이다.

핵심 식:

downstream gradient=upstream gradient×local gradient\text{downstream gradient} = \text{upstream gradient} \times \text{local gradient}

직관
뒤에서 온 gradient에 현재 node의 local derivative를 곱해서 앞쪽으로 넘긴다.


자주 나오는 Gate Pattern

Add gate:

z=x+yz = x + y zx=1\frac{\partial z}{\partial x} = 1 zy=1\frac{\partial z}{\partial y} = 1
  • Upstream gradient가 양쪽 input으로 그대로 전달된다.

Multiply gate:

z=xyz = xy zx=y\frac{\partial z}{\partial x} = y zy=x\frac{\partial z}{\partial y} = x
  • 한쪽 gradient를 구할 때 반대쪽 값이 곱해진다.
  • Swap처럼 생각하면 된다.

Copy gate:

  • 하나의 값이 여러 경로로 사용되는 경우이다.
  • Backward pass에서는 여러 경로에서 온 gradient를 더한다.
Lx=L1x+L2x\frac{\partial L}{\partial x} = \frac{\partial L_1}{\partial x} + \frac{\partial L_2}{\partial x}

Max gate:

z=max(x,y)z = \max(x, y)
  • Forward pass에서 선택된 쪽으로만 gradient가 흐른다.
  • 선택되지 않은 쪽 gradient는 0이다.

헷갈린 수식 / shape

Two-layer Neural Network Shape

입력 차원 DD, hidden neuron 수 HH, class 수 CC라고 하면:

xRDx \in \mathbb{R}^{D} W1RH×DW_1 \in \mathbb{R}^{H \times D} hRHh \in \mathbb{R}^{H} W2RC×HW_2 \in \mathbb{R}^{C \times H} sRCs \in \mathbb{R}^{C}

흐름:

  • xx: DD차원 input
  • W1xW_1x: HH차원 hidden representation
  • W2hW_2h: CC차원 class score

체크
Matrix multiplication이 가능한지 항상 shape으로 확인해야 한다.


Activation Function이 없을 때

Activation function이 없으면:

s=W2W1xs = W_2W_1x

합치면:

W3=W2W1W_3 = W_2W_1

결국:

s=W3xs = W_3x

핵심
Nonlinearity가 없으면 layer를 여러 개 쌓아도 linear model이다.


Backpropagation 예제: f(x,y,z)=(x+y)zf(x, y, z) = (x+y)z

함수:

f(x,y,z)=(x+y)zf(x, y, z) = (x+y)z

중간 변수:

q=x+yq = x + y f=qzf = qz

값:

x=2,y=5,z=4x = -2,\quad y = 5,\quad z = -4

Forward pass:

q=x+y=2+5=3q = x + y = -2 + 5 = 3 f=qz=3(4)=12f = qz = 3 \cdot (-4) = -12

Local gradient:

qx=1\frac{\partial q}{\partial x} = 1 qy=1\frac{\partial q}{\partial y} = 1 fq=z\frac{\partial f}{\partial q} = z fz=q\frac{\partial f}{\partial z} = q

값 대입:

fq=4\frac{\partial f}{\partial q} = -4 fz=3\frac{\partial f}{\partial z} = 3

Chain rule:

fx=fqqx=(4)(1)=4\frac{\partial f}{\partial x} = \frac{\partial f}{\partial q} \frac{\partial q}{\partial x} = (-4)(1) = -4 fy=fqqy=(4)(1)=4\frac{\partial f}{\partial y} = \frac{\partial f}{\partial q} \frac{\partial q}{\partial y} = (-4)(1) = -4

최종:

fx=4\frac{\partial f}{\partial x} = -4 fy=4\frac{\partial f}{\partial y} = -4 fz=3\frac{\partial f}{\partial z} = 3

헷갈린 점
xx, yyff에 직접 연결된 것이 아니라 qq를 거쳐 연결된다. 그래서 chain rule이 필요하다.


Sigmoid Derivative

함수:

f(w,x)=11+e(w0x0+w1x1+w2)f(w, x) = \frac{1}{1 + e^{-(w_0x_0 + w_1x_1 + w_2)}}

Linear part:

a=w0x0+w1x1+w2a = w_0x_0 + w_1x_1 + w_2

Sigmoid 적용:

f=σ(a)f = \sigma(a)

Sigmoid:

σ(a)=11+ea\sigma(a) = \frac{1}{1 + e^{-a}}

Derivative:

dσ(a)da=σ(a)(1σ(a))\frac{d\sigma(a)}{da} = \sigma(a)(1-\sigma(a))

핵심
Forward pass에서 σ(a)\sigma(a)를 저장해두면 backward pass에서 derivative를 바로 계산할 수 있다.


Scalar, Vector, Matrix Gradient Shape

Scalar to scalar:

dydx\frac{dy}{dx}
  • derivative도 scalar이다.

Vector to scalar:

xRNx \in \mathbb{R}^{N} LRL \in \mathbb{R} LxRN\frac{\partial L}{\partial x} \in \mathbb{R}^{N}
  • gradient는 xx와 같은 shape이다.

Vector to vector:

xRNx \in \mathbb{R}^{N} yRMy \in \mathbb{R}^{M}

Jacobian:

yxRM×N\frac{\partial y}{\partial x} \in \mathbb{R}^{M \times N}

원소별 의미:

Jij=yixjJ_{ij} = \frac{\partial y_i}{\partial x_j}

핵심
Loss LL은 scalar이므로, 어떤 variable에 대한 gradient는 그 variable과 같은 shape을 가진다.


ReLU Vector Backpropagation

ReLU는 element-wise operation이다.

y=max(0,x)y = \max(0, x)

원소별:

yi=max(0,xi)y_i = \max(0, x_i)

Jacobian은 diagonal matrix이다.

yixj=0if ij\frac{\partial y_i}{\partial x_j} = 0 \quad \text{if } i \ne j

대각 원소:

yixi={1if xi>00if xi0\frac{\partial y_i}{\partial x_i} = \begin{cases} 1 & \text{if } x_i > 0 \\ 0 & \text{if } x_i \le 0 \end{cases}

ReLU backward:

dxi={dyiif xi>00if xi0dx_i = \begin{cases} dy_i & \text{if } x_i > 0 \\ 0 & \text{if } x_i \le 0 \end{cases}
  • dyidy_i: upstream gradient
  • dxidx_i: downstream gradient

주의
실제 구현에서는 큰 Jacobian을 만들지 않고, xi>0x_i > 0인 위치에만 gradient를 통과시킨다.


Matrix Multiplication Backpropagation

Forward:

Y=XWY = XW

Shape:

XRN×DX \in \mathbb{R}^{N \times D} WRD×MW \in \mathbb{R}^{D \times M} YRN×MY \in \mathbb{R}^{N \times M}

원소별:

Yn,m=d=1DXn,dWd,mY_{n,m} = \sum_{d=1}^{D} X_{n,d}W_{d,m}

Upstream gradient:

dY=LYdY = \frac{\partial L}{\partial Y}

Backward rule:

dX=dYWTdX = dY W^T dW=XTdYdW = X^T dY

Shape 확인:

dYRN×MdY \in \mathbb{R}^{N \times M} WTRM×DW^T \in \mathbb{R}^{M \times D} dXRN×DdX \in \mathbb{R}^{N \times D}

따라서 dXdXXX와 같은 shape이다.

또한:

XTRD×NX^T \in \mathbb{R}^{D \times N} dWRD×MdW \in \mathbb{R}^{D \times M}

따라서 dWdWWW와 같은 shape이다.

핵심
Matrix multiplication의 backward는 반드시 shape으로 검산해야 한다.


Jacobian을 직접 만들지 않는 이유

Matrix multiplication을 Jacobian으로 직접 표현하면 너무 크다.

예시:

  • Mini-batch size: 64
  • Feature dimension: 4096
  • Jacobian을 직접 저장하거나 곱하는 것은 비효율적이다.

대신 operation별 backward rule을 사용한다.

dX=dYWTdX = dY W^T dW=XTdYdW = X^T dY

정리
Deep learning framework는 거대한 Jacobian을 직접 만들지 않는다. 연산별로 효율적인 backward function을 쓴다.


과제에서 확인할 것

  • 놓치지 말 것은 lecture 2 reading assignment / slides에 포함된 hinge loss, SVM loss 예시이다.
  • Softmax loss만 보는 것이 아니라, hinge loss가 score를 probability로 바꾸지 않는다는 점을 같이 확인한다.
Li=jyimax(0,sjsyi+Δ)L_i = \sum_{j \ne y_i} \max(0, s_j - s_{y_i} + \Delta)
  • 이번 강의에서 구현과 직접 연결되는 부분은 two-layer neural network의 forward pass와 analytical gradient 계산이다.
  • 특히 강의에서 강조한 흐름은 다음이다.
forward passthenbackward pass\text{forward pass} \quad \text{then} \quad \text{backward pass}
  • 과제에서 따로 체크할 만한 강의 언급은 다음 정도이다.
    • hinge loss / SVM loss는 lecture 2 reading assignment에 예시가 있음
    • optimizer 세부 내용은 lecture 3 참고
    • two-layer neural network 구현은 dimension 설정, forward pass, loss 계산, analytical gradient 계산 흐름을 확인