Home Deep Learning Basics (딥러닝 기초)
Post
Cancel

Deep Learning Basics (딥러닝 기초)

Introduction

딥러닝의 목적은 함수 근사이다. 예를 들어 입력이 2배가 되는 함수를 구한다면 $y = 2x$로 쉽게 구할 수 있을 것이다. 어떤 문제든지 입력과 출력이 있다. 딥러닝은 굉장히 복잡한 문제에 대해 출력을 보이는 하나의 함수를 구하는 방법이다.
조금 더 구체적으로 보자면 딥러닝은 크게 추론과 학습으로 나눌 수 있다. 주어진 입력에 대해 추론을 한 후 이를 바탕으로 다시 학습을 진행한다. 이를 수없이 반복하면 반복적 패턴을 발견하고 점점 합리적 추론을 이끌어낸다. 이는 사람과 유사하다. 사람도 처음에는 어떤 일에 대해 종종 잘못된 결과를 내지만 일을 하면서 점점 발전한다. 이것이 딥러닝에도 그대로 반영되어있다.
딥러닝에서 추론은 순전파(forward propagation), 학습은 역전파(backward propagation)를 통해 이루어진다. 추론이라는 과정은 입력 -> 출력 방향이기 때문이고, 학습은 출력 -> 입력 방향으로 피드백이 이루어지기 때문이다. 이러한 과정을 거쳐 어떤 문제를 해결하는 하나의 함수를 구하는 것이다.

이 포스트에서 출처를 명시하지 않은 자료는 모두 Deep Learning from Scratch의 자료이다.

Neural Network

먼저 딥러닝에서 신경망을 구축해야한다. 신경망이란 다음과 같다.

신경망은 인간 두뇌의 작동 방식을 반영함으로써 컴퓨터 프로그램이 패턴을 인식하고 AI, 머신 러닝 및 딥 러닝 분야의 일반적인 문제점을 해결할 수 있도록 지원합니다. (출처: IBM)

신경망은 다음과 같이 구성된다. (출처: IBM) test

위 그림을 보면 알 수 있지만 신경망은 입력층(Input layer), 은닉층(Hidden layer), 출력층(Output player)로 구성된다.
각 층은 여러개의 노드(뉴런)로 구성되며 각 노드당 하나의 값을 가지고 있다고 생각하면 된다. 인접한 층끼리는 서로 상호작용을 하는데 신호(입력)를 받는 층의 각 노드는 신호를 주는 층의 모든 노드로부터 신호를 받는다. 이때 신호가 바로 입력($x$)에 그 유명한 신경망 매개변수($w$)가 곱해진 $wx$ 값이다.

Note: 몰론 엄밀하게는 편향(bias, $b$)이라는 값 역시 들어온다.

Forward Propagation

구체적으로 신경망의 처리 과정 중 추론 과정인 순전파에 대해 알아보자. 신경망의 장점은 국소적 범위에서의 원리만 알면 전체가 동일하게 동작한다는 것이다.
신경망은 여러 순차적인 층(layer)으로 구성되며 어떤 데이터를 입력할 시 각 층을 지나 올바른 최종 결과를 추론하는 것이 목표이다. 이 때 순전파란 입력 데이터에 대한 출격값을 신경망의 연속적인 층의 앞 방향으로 전달하는 연속적인 연산 과정을 의미한다.
신경망은 아래와 같은 그림처럼 처리된다. 아래 그림의 신경망은 입력층 -> 1층 -> 2층 -> 출력층으로 입력층, 은닉층(2개), 출력층으로 구성된다.

위 그림에서 1층의 첫번째 노드 $a_1^{(1)}$의 값은 $a_1^{(1)} = x_1w_{11}^{(1)} + x_2w_{12}^{(1)} + b_1^{(1)}$을 통해 구해진다. 이때 입력은 $x_1, x_2$, 신경망 매개변수는 $w$, 편향은 $b$이다. 특히 위 그림에서 편향 $b$를 위해 입력층에 값이 $1$인 노드를 추가했다. 이는 위 식에서 $1 \times b$라고 생각하기 위해서이다. 다소 변수 구성이 복잡한데 다음 그림에서 변수 구성에 대해 설명한다.

위 그림에서 매개변수 $w_{12}$의 $1$이 다음 층이고, $2$가 앞층이라 다소 헷갈릴 수 있다. 이렇게 설정된 이유는 이후에 연산을 처리할 때 신경망 매개변수가 다음층에 귀속된 것처럼 취급하기 때문이다.

다시 원래로 돌아와서 순전파 연산을 생각해보면 $a_2^{(1)}, a_3^{(1)}$ 연산은 기존 $a_1^{(1)}$을 구한 방식과 동일하다는 것을 알 수 있으며 $a_1^{(1)} = x_1w_{11}^{(1)} + x_2w_{12}^{(1)} + b_1^{(1)}$ 연산을 확장해 간단한 벡터 표기로 나타낼 수 있다.

\[\textbf{A}^{(1)} = \textbf{X} \cdot \textbf{W}^{(1)} + \textbf{B}^{(1)}\]

각 식의 구성 요소

  • $\textbf{A}^{(1)} = \begin{bmatrix} a_1^{(1)} & a_2^{(1)} & a_3^{(1)} \end{bmatrix}$
  • $\textbf{X} = \begin{bmatrix} x_1 & x_2 \end{bmatrix}$
  • $\textbf{W}^{(1)} = \begin{bmatrix} w_{11}^{(1)} & w_{21}^{(1)} & w_{31}^{(1)} \\
    w_{12}^{(1)} & w_{22}^{(1)} & w_{32}^{(1)} \end{bmatrix}$
  • $\textbf{B}^{(1)} = \begin{bmatrix} b_1^{(1)} & b_2^{(1)} & b_3^{(1)} \end{bmatrix}$

위와 같이 입력 신호에 대한 은닉층에서의 가중치 합 벡터 $\textbf{A}$의 각 원소는 활성화 은닉층의 활성화 함수(activation function) $h(x)$에 의해 변환된다. 활성화 함수는 신경망에서 가중치 합을 변환해주는 함수로 노드(뉴런)이 활성화될지 말지 결정한다. 단순히 가중치 합 계산에서 끝나는 것이 아니라 활성화 함수를 통해 신경망의 표현을 좀 더 풍부하게 해준다.
활성화 함수에는 여러 함수가 사용되는데 구체적인 함수는 아래에서 설명하도록 하겠다. 지금은 값을 변형시킨다는 정도만 알고있어도 충분하다.

아래 그림은 연산된 가중치 합 벡터 $\textbf{A}$를 활성화 함수를 통해 $\textbf{Z} = h(\textbf{A})$로 변환하는 과정을 보여준다.

위에서 변환된 결과인 벡터 $\textbf{Z}$는 다시 다음 층에 대한 입력이 되어, 위에서 진행했던 연산 과정을 반복해 최종 출력층까지 진행된다.

1층 $\rightarrow$ 2층2층 $\rightarrow$ 출력층

참고로 위 마지막 출력층의 활성화 함수가 $\sigma$로 나오는데, 이는 출력층의 활성화 함수로 은닉층에서 사용되는 활성화 함수와 보통 다른 함수를 쓰기 때문에 다르게 표시했다.

지금까지 순전파 과정을 알아보았다. 그런데 위의 추론 과정을 보면 우리는 각 층에서 단순히 입력 데이터에 대한 가중치 곱을 더한 후 활성화 함수를 통해 변형한 것밖에 하지 않았다.

\[\textbf{A} = \textbf{X} \cdot \textbf{W} + \textbf{B} \\ \textbf{Z} = h(\textbf{Z})\]

위 과정이 왜 추론 과정인걸까? 신경망은 단순한 위 과정을 통해 어떻게 합리적 추론을 이끄는 걸까?
예를 들어 $y = w_1x_1 + w_2x_2 + b$라는 함수가 있다고 해보자. 이 함수는 알겠지만 평면 방정식으로 3차원 공간에서 임의의 평면을 표현한다. 즉, 우리는 어떤 입력 데이터 $x_1, x_2$를 $w_1, w_2, b$를 통해 평면 영역 위의 점으로 나타낼 수 있다. 각 층에서의 신호 계산은 차원만 다를 뿐 위와 유사한 선형 방정식에 신호를 변형시키는 활성화 함수만 존재한다. 그런데 층이 여러개가 있다는 것은 위의 연산이 연속적으로 발생한다는 것이고, 이는 신경망 전체를 바라보았을 때 하나의 합성함수를 구성한다.
아주 간단한 예시를 들어보자. 1층에 가중치 곱 함수 $t = a_1x$와 활성화 함수 $s = t^2$, 2층에 $u = a_2s$와 $y = \sin(u)$가 있다고 해보자. 이들의 합성함수는 $y = \sin(a_1^2a_2x^2)$으로 가중치 곱을 구하는 선형 함수와 간단한 비선형 활성화 함수 만으로 완전히 새로운 비선형 함수를 만들었다. 이와 같이 여러번 합성된다면 이 합성함수는 더욱 정교해질 것이다. 즉, 층이 깊어질수록 표현력은 높아지는 것이다. 이 합성함수의 매개변수에 올바른 값이 존재한다면 우리는 위와 같은 신호 변환과 전달만으로도 입력에 대한 추론을 할 수 있다. 따라서 우리의 목표는 신경망을 구축하고 데이터 패턴에 따른 올바른 신견망 매개변수를 찾는 것이다.

Activation Function

신경망 학습 이전에 중요한 한가지를 알고 넘어가야한다. 바로 활성화 함수이다.
활성화 함수는 합성함수를 만들 때 가중치 곱에 대한 합을 구하는 선형 함수를 비선형 함수로 변환시켜주는 굉장히 중요한 함수이다. 단순 선형 함수들의 합성함수는 선형함수이기 때문에 합성의 의미가 없다. 즉, 층을 깊게 하는 의미가 없다. 층 하나로 하나의 선형 함수가 표현되며 이것만 학습시키면 선형 함수로만 구성된 여러 층을 학습 시키는 것과 동일하다. 따라서 활성화 함수는 반드시 비선형 함수여야한다.
여기서는 책에서 소개된 아주 기초적인 몇개의 활성화 함수만 소개한다.

Sigmoid

주로 은닉층에서 사용되며 수식은 아래와 같다.

\[h(x) = \displaystyle\frac{1}{1 + e^{-x}}\]

그래프

ReLU

주로 은닉층에서 사용되며 수식은 아래와 같다.

\[\begin{aligned} h(x) = \begin{cases} x & (x > 0) \\ 0 & (x \leq 0) \end{cases} \end{aligned}\]

그래프

Softmax

주로 분류 문제를 풀 때 출력층에서 사용된다. Softmax 함수의 특징은 출력 노드의 값이 0 ~ 1 범위로, 출력 총합은 1이다. 즉, Softmax 함수의 출력은 일종의 확률이다. 수식은 아래와 같다.

\[y_k = \displaystyle\frac{e^{a_k}}{\sum_{i=1}^n{e^{a_i}}}\]

위 식에서 $n$은 출력층의 뉴런 수, $a$는 입력, $y_k$는 출력층의 뉴런 중 $k$번째 출력이다.

Backward Propagation

추론 과정을 살펴봤으니 이제 학습 과정을 살펴보자. 신경망 학습이란 결국 최적의 신경망 매개변수 $\textbf{W}$와 편향 $\textbf{b}$를 찾는 과정이다. 신경망이 입력에 대해 어떤 결과를 추론했을 때, 그 추론은 맞을 수도 있고 틀릴 수도 있다. 특히, 학습 초기에는 거의 대부분 틀린다. 신경망이 어떤 추론을 이끌어냈을 때 그것이 올바른 답인지 아닌지 피드백을 해야할 필요가 있다. 피드백을 반영해야 학습이라고 할 수 있는 것이다.
피드백을 하기 위해선 먼저 올바르게 추론했는지 평가를 해야한다. 이러한 평가를 나타내기 위해 흔히 손실 함수를 사용한다. 손실 함수란 말그대로 최적값으로부터 얼마만큼 손실인지 여부를 나타내는 함수이다. 따라서 손실이 작으면 작을 수록 올바른 정답을 유추했다고 평가할 수 있다.
우리는 손실 함수가 미분 가능하다고 가정할 때 최소값에 해당되는 위치는 극소일 것이다. 어떤 함수의 극소를 찾는 방법은 여러가지가 있지만 가장 일반적으로 쓰이는 방법은 경사하강법이다. 경사하강법이란 현재 위치에서의 함수의 기울기(경사)를 활용해 일정 부분만큼 하강하는 방법이다. 함수의 기울기는 그 함수가 증가 함수인지, 감소 함수인지를 나타내는 중요한 지표이다. 즉, 기울기를 통해 우리는 함수값이 작아지는 방향을 알 수 있으며 그 방향으로 이동하다보면 원하는 최적 위치에 도달할 수 있다.

손실 함수

손실 함수는 수없이 많겠지만 이 책에서 소개하는 손실 함수는 2개이다.

Mean Squared Error

평균 제곱 오차(mean squared error, MSE)는 가장 자주 쓰이는 손실 함수 중 하나이다. 예측값과 실제값의 차이인 오차의 제곱을 평균을 낸다.

\[E = \displaystyle\frac{1}{2}\displaystyle\sum_k{(y_k - t_k)^2}\]

$y_k$는 예측값, $t_k$는 실제값이며 $\displaystyle\frac{1}{2}$은 미분 시 상수항을 1로 만들기 위해서이다.
평균 제곱 오차는 제곱의 합이기 때문에 반드시 0보다 크거나 같다. 따라서 우리의 목표는 평균 제곱 오차를 0으로 도달시키는 것이다.

Cross Entropy Error

교차 엔트로피 오차(cross entropy error, CEE)는 분류 문제에서 자주 사용되는 손실 함수 중 하나이다. 우리는 분류 문제에서 Softmax 활성화 함수를 출력층에서 사용한다. 그렇기 때문에 최종 Output은 확률이다. 예를 들어 0 ~ 9까지의 숫자 분류 문제가 있다면 최종 output은 입력 데이터가 0 ~ 9 중 각각에 해당될 확률 분포이다. 우리는 Softmax를 통해 확률 분포를 얻었고, 확률 분포에 대한 오차를 구하려고 한다.

먼저, Entropy 개념에 대해 간략하게만 알아보자. Entropy는 간단히 말하면 불확실성의 수준이다. 우주는 엔트로피가 증가하는 방향으로 진행된다는 그 유명한 말은 누구나 알것이다.

아래 그림을 보자.(출처: Towards Data Science)

우리가 삼각형과 원 둘 중에 하나를 랜덤하게 선택한다고 할 때 어느 컨테이너가 가장 불확실성이 클까? 당연히, 2번째 컨테이너일 것이다. 1번째 컨테이너는 삼각형을, 3번째 컨테이너는 원을 뽑을 확률이 압도적으로 높지만 2번째 컨테이너는 삼각형이 뽑힐지, 원이 뽑힐지 모른다. 이것이 불확실성이다.

이러한 Entropy 개념을 활용한 손실 함수가 교차 교차 엔트로피 오차이다. 수식은 아래와 같다.

\[E = -\displaystyle\sum_k{t_k\log{y_k}}\]

$y_k$는 예측값, $t_k$는 실제값이다.
교차 엔트로피 오차의 입력은 확률이기 때문에 항상 0 ~ 1사이의 값이다. 따라서 $\log$ 함수의 특성 상 교차 엔트로피 오차는 반드시 0보다 크거나 같다. 따라서 우리의 목표는 교차 엔트로피 오차를 0에 도달시키는 것이다. 아래는 $\log$함수의 그래프이다.

$\log$함수 그래프

교차 엔트로피와 관련된 자세한 내용은 아래 링크를 참조하길 바란다.

Towards Data Science

오차역전파법 개요

최적의 신경망을 만들기 위해서는 신경망 매개변수의 최적값을 찾아야한다. 신경망 매개변수에 따른 추론 능력이 어느정도인지 평가하기 위해 손실함수를 정의했다. 결국 손실함수는 신경망 매개변수에 의한 합성함수이며 손실 함수 값을 최소로 만들기 위해 신경망 매개변수를 조절해야한다. 경사하강법을 사용하면 손실 함수의 기울기 정보만 알면 최적값을 찾을 수 있다. 즉, 우리는 신경망 매개변수 $\theta$에대한 손실함수의 변화량인 $\displaystyle\frac{\partial L}{\partial \theta}$를 구해야 한다.

기울기를 구하기 위한 방법은 여러가지가 있다. 가장 간단한 방법은 수치미분이다. 수치미분 기법은 함수의 원형을 몰라도 기울기를 구할 수 있다는 장점이 있지만, 계산 속도가 느리다. 딥러닝에서는 계산의 효율성을 위해 오차역전파법이란 개념을 사용한다.

합성함수 미분

오차역전파법의 핵심은 합성함수 미분이다. 위에서 언급했듯이 손실함수는 신경망 매개변수에 의한 합성함수이다. 다음과 같은 합성함수가 있다고 할 때 합성함수 미분은 간단히 구할 수 있다.

\[y = f(t), \; t = g(x) \\ \dfrac{dy}{dx} = \dfrac{dy}{dt}\dfrac{dt}{dx}\]

위 합성함수의 도함수는 $f(t)$의 도함수인 $\dfrac{dy}{dt}$와 $g(x)$의 도함수인 $\dfrac{dt}{dx}$의 곱으로 구성된다. 즉, 합성함수 미분은 합성함수를 구성하는 각 함수의 미분의 곱일 뿐이다.

신경망 연산 과정 분리

앞서 언급했듯이 합성함수 미분은 각 함수의 미분의 곱이다. 따라서 우리는 신경망의 연산 과정을 쪼갤 필요가 있다. 말 그대로 합성함수의 형태로 만들어주기 위해서이다. 각각의 연산 과정을 계층이라고 한다.
신경망 연산 계층은 모듈화의 가치가 있는 최소 단위로 나눈다. 또한 각 계층은 순전파와 역전파 함수가 반드시 구현되어야한다.(이에 대해서는 좀있다 소개한다.) 예를 들면 Sigmoid나 ReLU 등의 활성화 함수는 하나의 계층이다. 입력에 대한 가중치 총합을 구하기 위한 신경망 매개변수와의 행렬 내적 연산 역시 하나의 계층으로 나타낼 수 있다. 특히 이 행렬 내적 계층을 Affine 계층이라고 부른다.
이 방식의 장점은 각 계층이 국소적 계산만하면 된다는 점에 있다. 이로 인해 모듈화가 쉽고, 여러 계층을 조합해 새로운 신경망을 쉽게 만들 수 있으며, 연산 속도에도 큰 이점이 있다.

구조

오차역전파법의 구조는 앞서 언급했듯이 각 계층은 순전파와 역전파 함수가 구현되어있으며 국소적 계산만을 담당한다. 순전파 함수와 역전파 함수는 오차역전파법의 핵심이다. 순전파는 앞서 언급했듯이 입력에 대한 연산 결과를 앞(forward) 층으로 전달하는 연속적인 과정이다. 즉, 입력층 -> 출력층 방향으로의 연산 과정이다. 반대로 역전파는 출력층 -> 입력층으로 연산 결과를 전달하는데 이 때 연산 결과가 바로 원함수의 도함수의 함수값인 기울기이다. 아래 그림을 보자.

신경망 계층 구조 그림

위 그림은 신경망 연산을 위한 계층 구조이다. $2$와 유사한 그림 데이터를 입력했을 때 최종 출력층에서 각 정답 Layer에 대한 확률을 출력하고 있다. 이 과정이 순전파이다. 그와 동시에 피드백을 하기 위해 기울기를 구해야하는데 그 기울기를 구하기 위해 출력층 -> 입력층으로 다시 전달하는 과정이 역전파이다. 이 때 각 계층은 순전파와 역전파 함수가 구현되어있으며 국소적 계산만을 담당한다. 즉, 각 계층은 하나의 단순한 원함수와 원함수의 도함수로만 구성된다.

각 계층의 순전파, 역전파 함수

순전파와 역전파 함수를 구현한 각 계층을 조합해 신경망을 만들 수 있다고 했다. 몇가지 예시를 살펴보자.

ReLU 계층

ReLU는 활성화 함수로 하나의 계층을 구성할 수 있다. 아래는 순전파에 사용되는 ReLU 함수이다.

\[\begin{aligned} y = \begin{cases} x & (x > 0) \\ 0 & (x \leq 0) \end{cases} \end{aligned}\]

그렇다면 역전파 함수는 어떨까? 그냥 단순히 위 함수를 미분하기만 하면 된다.

\[\begin{aligned} \dfrac{\partial y}{\partial x} = \begin{cases} 1 & (x > 0) \\ 0 & (x \leq 0) \end{cases} \end{aligned}\]

Sigmoid 계층

순전파 함수는 아래와 같다.

\[y = \dfrac{1}{1 + e^{-x}}\]

Sigmoid 함수를 미분하자. 고등학교를 나왔다면 위 함수의 미분 자체는 어렵지 않을 것이다.

\[\dfrac{\partial y}{\partial x} = \dfrac{e^{-x}}{(1 + e^{-x})^2}\]

다만 위 식을 그대로 사용하지는 않는다. 위 식을 변형하면 지수계산을 하지 않고도 값을 얻을 수 있어 계산 속도를 증가시킬 수 있다. 위 식을 $x$에 대한 식이 아닌 $y$에 대한 식으로 변형하면 다음과 같다.

\[\dfrac{\partial y}{\partial x} = \dfrac{1}{1 + e^{-x}}\dfrac{1 +e^{-x} - 1}{1 + e^{-x}} = y(1-y)\]

즉, 위와 같이 $y$에 대한 식으로 변형하면 순전파때 구한 $y$값을 추가적인 지수 연산 없이 단순한 곱셈과 뺄셈만으로 미분의 결과를 얻을 수 있다.

Affine 계층

Affine 계층은 입력과 신경망 매개변수 $\theta$의 행렬 내적 연산을 수행하는 계층이다. 따라서 수식 자체는 단순한 선형방정식으로 간단하다. 다만 행렬 내적의 성격상 좌측의 열과, 우측의 행 차원의 크기를 동일하게 해야만 수행 가능하므로 주의해야한다. 순전파 함수의 수식은 아래와 같다.

\[y = \textbf{X} \cdot \textbf{W} + \textbf{b}\]
  • $\textbf{X}$: 이전 layer의 value
  • $\textbf{W}$: 가중치
  • $\textbf{b}$: 편향

역전파 함수를 구할 때는 입력과 신경망 매개변수가 행렬임을 고려해 미분을 해야한다.

\[\dfrac{\partial L}{\partial \textbf{X}} = \dfrac{\partial L}{\partial \textbf{Y}} \cdot \textbf{W}^\text{T} \\ \dfrac{\partial L}{\partial \textbf{W}} = \textbf{X}^\text{T} \cdot \dfrac{\partial L}{\partial \textbf{Y}}\]

증명 과정은 생략한다.

오차역전파법 구성

지금까지 오차역전파법을 만들기 위해 합성함수 미분과 신경망 계층 개념을 알아보았다. 위 계층들을 조합하면 신경망이 완성된다. 입력층에 데이터를 입력만 하면 값이 계층을 따라 연산 후 전달을 반복해 데이터의 흐름을 만들 수 있다.

References

[1] Github WegraLee/deep-learning-from-scratch
[2] IBM 신경망

This post is licensed under CC BY 4.0 by the author.