본 포스팅은 ‘밑바닥부터 시작하는 딥러닝 2’ 교재를 참고했습니다.
신경망의 학습
학습되지 않은 신경망은 좋은 추론을 할 수 없다. 따라서 학습을 먼저 수행하고, 학습된 매개변수를 이용해 추론을 수행해야 한다.
손실 함수
신경망 학습에는 학습이 얼마나 잘 되고 있는지를 알기 위한 척도가 필요하다.
손실이란 신경망이 예측한 결과를 비교하여 예측이 얼마나 나쁜가를 산출한 스칼라 값으로, 성능을 나타내는 척도이다.
이것을 구하는 것이 바로 손실 함수이다.
우리는 소프트맥스와 교차 엔트로피 오차를 통해 손실 함수를 구현할 것이다.
소프트맥스
$$ p_k = \frac{\exp{(s_k)}}{\sum_{k=1}^{n}{\exp{(s_k)}}} \quad for \ k=1,2,\dots,k \tag{1} $$
[식 1]에서 소프트맥스 함수의 출력의 각 원소 $p_k$는 $0 \leq p_k \leq 1,\space p_k \in \mathbb{R}$ 이다.
따라서 소프트맥스의 출력은 확률로 해석할 수 있다. 우리는 이것을 교차 엔트로피 오차에 입력할 것이다.
교차 엔트로피 오차
$$ Loss = - \sum_{k}t_k \log{p_k} \tag{2} $$
[식 2]에서 $t_k$는 $k$번째 클래스의 정답 레이블이다. $t = \begin{bmatrix} 0, 1, 1 \end{bmatrix}$ 과 같이 one-hot vector로 표기한다.
one-hot vector는 단 하나의 원소만 1 이고 그 외에는 0인 벡터이다.
미니 배치를 고려하면 교차 엔트로피 오차의 식은 아래와 같이 바뀌게 된다.
$$ Loss = - \frac{1}{N} \sum_{n} \sum_{k}t_{nk} \log{p_{nk}} \tag{3} $$
[식 3]에서 $N$은 미니 배치의 개수, $t_{nk}$는 $n$번째 데이터의 $k$차원째의 값, $p_{nk}$는 신경망의 출력, $t_{nk}$는 정답 레이블이다.
이는 N으로 나눠서 1 개당의 평균 손실 함수를 구하는 것이다. 미니배치의 크기에 관계없이 항상 일관된 척도를 얻을 수 있다.
행렬의 미분
신경망 학습의 목표는 손실을 최소화하는 매개변수를 찾는 것이다. 이때 중요한 것이 바로 미분과 기울기이다.
행렬을 입력이나 출력으로 가지는 함수를 미분하는 것을 행렬 미분이라고 한다. (정확하게는 편미분이다.)
또한 행렬미분에는 분자중심 표현법과 분모중심 표현법 두 가지가 있는데, 본 포스팅에서는 분모중심 표현법으로 서술하겠다.
행렬 미분에 대한 상세한 정의는 여기를 참고하기 바란다.
$$ \frac{\partial L}{\partial \mathbf{x}}= \begin{pmatrix} \frac{\partial L}{\partial x_1} & \frac{\partial L}{\partial x_2} & \cdots & \frac{\partial L}{\partial x_n} \end{pmatrix} \tag{4} $$
$L$은 스칼라, $x$는 벡터인 함수 $L=f(x)$가 있을 때, $x_i$에 대한 $L$의 미분은 $\frac{\partial y}{\partial x_i}$로 쓸 수 있으며, 이를 정리하면 [식 4]와 같다.
$$ \frac{\partial L}{\partial \mathbf{W}}= \begin{pmatrix} \frac{\partial L}{\partial W_{11}} & \cdots & \frac{\partial L}{\partial W_{1n}} \\ \vdots & \ddots \\ \frac{\partial L}{\partial W_{m1}} & & \frac{\partial L}{\partial W_{mn}} \end{pmatrix} \tag{5} $$
$\mathbf{W}$가 $m \times n$ 행렬이라면, $L = g(\mathbf{W})$ 함수의 기울기는 [식 5] 같이 쓸 수 있다.
여기서 중요한 점은 $\mathbf{W}$와 $\frac{\partial L}{\partial \mathbf{x}}$의 형상이 같다는 것이다. 이 성질을 이용하면 매개변수 갱신과 연쇄 법칙을 쉽게 구현할 수 있다.
연쇄 법칙
우리는 신경망의 학습을 위해 각 매개변수에 대한 손실의 기울기를 구해 매개변수를 갱신할 것이다. 신경망의 기울기는 오차역전파법 (back-propagation)을 통해 구할 수 있으며, 이 때 필요한 것이 연쇄 법칙이다.
$y=f(x)$와 $z=g(y)$라는 두 함수가 있을 때, $z=g(f(x))$이다.
$$ \frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x} \tag{6} $$
$x$에 대한 $z$의 미분은 [식 6]과 같이 $y=f(x)$의 미분과 $z=g(y)$의 미분을 곱해 구할 수 있다. 이것이 바로 연쇄 법칙이다.
즉, 함수가 아무리 복잡하더라도 개별 함수들의 미분을 통해 효율적인 계산을 할 수 있다는 것이다.
가중치 갱신
신경망의 학습은 다음 순서로 수행된다.
graph LR a((미니배치))-->b((기울기 계산))-->c((매개변수 갱신))-->a
우선 미니배치에서 데이터를 선택하고, 이어서 오차역전파법으로 가중치의 기울기를 얻는다. 이 기울기는 현재의 가중치 매개변수에서 손실을 가장 크게 하는 방향을 가리킨다. 따라서 매개변수를 그 기울기와 반대 방향으로 갱신하면 손실을 줄일 수 있다. 이것이 바로 경사하강법이다.
확률적경사하강법
확률적 경사하강법 (Stochastic Gradient Descent)은 무작위로 선택된 데이터(미니배치)에 대한 기울기를 이용하여, 현재의 가중치를 기울기 방향으로 일정한 거리만큼 갱신한다.
$$ W \gets {W} - \eta {\frac{\partial {L}}{\partial {W}}} \tag{7} $$
[식 7]에서 갱신하는 가중치 매개변수는 $\mathbf{W}$ 이고, $\mathbf{W}$에 대한 손실 함수의 기울기는 $\frac{\partial {L}}{\partial {W}}$이다. $\eta$는 학습률 (learning rate)을 나타내고, 0.01이나 0.001 같은 값을 미리 정해서 사용한다.
이것을 파이썬으로 구현하면 아래와 같다.
|
|
신경망 예제
이전 포스팅에서 설계한 신경망에 Softmax 레이어와 Cross Entropy Error 레이어를 새로 추가해 보자.
graph LR x(x)==> A(Affine) A==> B(Sigmoid) B==> C(Affine) C==>D(Softmax) t(t)==>E D==>E(Cross Entropy Error) E==>F(L)
$\textbf{x}$는 입력 데이터, $\textbf{t}$는 정답 레이블. $L$은 손실을 나타낸다.
Sigmoid의 역전파 구현
Sigmoid의 수식은 $y=\frac{1}{1+\exp{(-x)}}$이다. 그 미분은 아래 [식 7]과 같다.
$$ \frac{\partial y}{\partial x} = y(1-y) \tag{8} $$
이를 파이썬으로 구현하면 아래와 같다.
|
|
Affine의 역전파 구현
Affine의 역전파는 MatMul 노드와 Repeat 노드의 역전파를 수행하면 구할 수 있다.
|
|
TwoLayerNet 구현
Sigmoid와 Affine 레이어의 back-propagation을 구현했으니, 이제 TwoLayerNet
클래스를 완성해 보자.
|
|