2 분 소요

본 글은 2021년 4월에 강의한 스탠포드 대학의 “Convolutional Neural Networks for Visual Recognition” 2021년 강의를 듣고 정리한 내용입니다.
개인 공부 목적으로 작성되었으며, 설명이 맞지 않거나 글 오타가 있으면 알려주시길 바랍니다.

원본 링크 : cs231n.stanford.edu
한글 번역 링크 : aikorea.org - cs231n
강의 링크 : youtube - 2017 Spring (English)




Neural Networks

  • 신경망(Neural Networks) : 인공 뉴런이나 노드로 구성된 인공 신경망 1
  1. Linear score function
    • $f=Wx$
  2. 2-layer Neural Network
    • $f=W_2max(0, W_1x)$

    • 여기서 비선형 함수인 $max(0,x)$를 이용한다.
    • 만약, 비선형 변환없이 선형 함수만 계속 추가되면 다시 입력의 선형 함수가 되어버린다.

    • 기존 linear layer 행렬곱에 의한 스코어 함수 $f=Wx$에서 가중치 행렬 $W$의 각 행이 클래스 각각의 탬플릿과 비슷한지 비교하였다.
    • 하지만, 각 클래스마다 오직 하나의 템플릿만 가지고 있는데, 다중 레이어 신경망은 다양하게 이미지를 분류할 수 있게 해준다.
  3. 3-layer Neural Network
    • $f=W_3max(0, W_2max(0,W_1x))$



Activation functions

  • 활성화 함수(activation function) : 입력된 데이터의 가중 합을 출력 신호로 변환하는 함수 2
    • 이전 레이어에 대한 가중 합의 크기에 따라 활성 여부가 결정된다.
  • 다음은 활성화 함수의 종류이다.



Example feed-foward computation of a neural network

import numpy as np

f = lambda x: 1.0/(1.0+np.exp(-x)) # 활성화 함수 정의(시그모이드)
x = np.random.randn(3, 1)
h1 = f(np.dot(W1, x) + b1)
h2 = f(np.dot(W2, h1) + b2)
out = np.dot(W3, h2) + b3


  • 다음은 계산 과정의 전반적인 그림이다.

여기서 편향(bias)를 추가해 주는 이유는 파라미터의 선호도를 조절해주기 위해서이다.


Setting the number of layers and their sizes


Types of regularization



Backpropagation

  • 이제 어떻게 그레이디언트를 계산할 것인지가 남아 있다.
  • Analytic gradient를 계산할 때 computational graph를 이용하면 어떠한 함수도 표현이 가능하다.

미분은 각 변수가 해당 값에서 전체 함수(expression)의 결과 값에 영향을 미치는 민감도와 같은 개념이다.

  • 초록색 숫자는 피드포워드 값, 빨간색 숫자는 미분값이다.
  • $\frac{\partial f}{\partial y}$는 연쇄법칙(chain-rule)을 이용해 계산할 수 있다.
  • $\frac{\partial f}{\partial x}$는 연쇄법칙(chain-rule)을 이용해 계산할 수 있다.


  • 위 그림과 같이 각 노드가 local gradient를 갖고 있으며, backpropagation을 통해 상위 노드 방향으로 전달되고, 이것을 이전 노드가 전달받아 그 노드의 local gradient와 곱해주면서 나아간다.
  • upstream gradient : 노드의 output에 대한 gradient (이미 계산)
  • local gradient : 해당 노드내에서만 계산되는 gradient
  • downstream gradient : 노드의 input에 있는 변수에 대한 gradient 3


  • 다음은 역전파를 계산하는 다른 예시이다.

lecture_4-84

  1. 1/x gate

    • $f(x)=1$ $\to$ $\frac{df}{dx}=-1/x^2$
    • $(1.00)(\frac{-1}{1.37^2})=-0.53$
  2. +1 gate

    • $f_c(x)=c+x\to$ $\frac{df}{dx}=1$
    • $(-0.53)(1)=0.53$
  3. exp gate

    • $f(x)=e^x\to$ $\frac{df}{dx}=e^x$
    • $(-0.53)(e^{-1})=-0.20$
  4. *-1 gate

    • $f_a(x)=ax\to$ $\frac{df}{dx}=a$
    • $(-0.20)(-1)=0.20$
  5. + gate

    • $(0.20)(1.00)=0.20$
    • $(0.20)(1.00)=0.20$
  6. + gate

    • $(0.20)(1.00)=0.20$
    • $(0.20)(1.00)=0.20$
  7. * gate

    • $w_0=(0.20)(-1.00)=-0.20$
    • $x_0=(0.20)(2.00)=0.40$
  8. * gate

    • $w_1=(0.20)(-2.00)=-0.40$
    • $x_1=(0.20)(-3.00)=-0.60$



Patterns in gradient flow

  1. add gate : 항상 출력의 미분을 전방 전달(forward pass)에 상관없이 모든 입력에 균등하게 분배한다.

  2. mul gate : local gradient는 입력 값이고 이는 chain rule 동안 출력에 대한 그레이디언트로 곱해진다.

    • 이 과정을 forward와 backward API로 직접 구현하면 다음과 같다. (Pytorch)

     class Multiply(torch.autograd.Function):
       @staticmethod
       def forward(ctx, x, y):
         # backward에서 사용하기 위해 일부 값을 저장해야 한다.
         ctx.save_for_backward(x, y) 
         z = x * y
         return z 
       @staticmethod
       def backward(ctx, grad_z): # upstream gradient
         x, y = ctx.saved_tensors
         # upstream gradient와 local gradient를 곱셈
         grad_x = y * grad_z # dz/dx * dL/dz
         grad_y = x * grad_z # dz/dy * dL/dz
         return grad_x, grad_y
    
  3. max gate : 미분을 정확히 하나의 입력(앞으로 전방 전달하는 동안 가장 높은 값을 가진 입력)으로 분배한다.



Gradients add at branches

  • 만약 그레이디언트가 양쪽에 있다면, 각각을 더해주기만 하면 된다.



Summary

  • 완전 연결망(Fully-connected) Neural Networks : 선형 함수와 비선형 함수의 스택(stack)으로, 선형 분류기보다 훨씬 많은 표현력(representational power)를 가지고 있다.
  • 역전파(backpropagation) : 모든 입력(input)/매개변수(parameter), 그 사이의(intermediate)의 그레이디언트(gradient)를 계산하기 위해 계산 그래프를 따라 연쇄규칙(chain-rule)를 재귀적(recursive)으로 적용한다.
  • 구현은 노드가 정방향(forward), 역방향(backward) API를 구현하는 그래프 구조를 유지한다.
  • 정방향(forward) : 연산 결과를 계산하고 그 사이사이 계산에 필요한 값을 메모리에 저장한다.
  • 역방향(backward) : 연쇄규칙(chain-rule)을 적용하여 입력에 대한 손실 함수(loss function)의 그레이디언트를 계산한다.





References

댓글남기기