오류 역전파
위 발표는 이신정님이 보내주신 발표 자료를 기반으로 참고사항을 추가해 각색하여 만들었습니다. 오류가 있는 부분은 저에게 말씀해주시고, 질문 및 기타 관련 사항 역시, 이신정님 혹은 저에게 말씀해 주시면 됩니다.
다음과 같은 차례로 진행됩니다.
오차 역전파는 말 그대로 기존의 순전파와는 대비되는 개념으로 오차를 출력 노드에서부터 입력 노드로 역으로 전파하는 개념입니다.
오차 역전파를 이해하기 위한 방법은 수식적인 방법과 시각적인 방법이 있는데, 수식적인 방법은 정확하고 간결한 대신 아무래도 접근하기가 어려울 수 있기 때문에 우리 교재에서는 시각적인 계산그래프를 사용하여 오차역전파를 설명합니다.
/*
수식적인 방법 (스토리를 위해 이전에 배운 Gradient Decsent 부터 설명됩니다.) 설명입니다. 그래프가 훨씬 이해 잘되니 넘기셔도 됩니다.
먼저, Loss function에 대해 알아봅시다.
위 식을 보면, y와 y`이 나오는데 이는, 이론적인 값과 예측한 값을 나타냅니다. 또한 우리가 사용할 Loss function은 보통 Squared error loss가 됩니다.
그럼 먼저, Univariate Linear Regression인 경우부터 알아보도록 합시다. Univariate란, 단순화된, 혹은 하나의 속성만 있는 경우를 말하는 데, 후에 나오는 Multivariate와 상반된 개념입니다. (참고)
Linear에 대한 식이 나오고,이를 Loss function으로 구현한 식이 나옵니다. 모든 오류를 합하는 과정도 포함이 됩니다.
이렇게 구한 식이 최소값이 되어야 Regression이 최적화됩니다.(Loss 이므로) 즉 편미분한 값들이 0이 되어야 하고, 그로인해 w0와 w1을 구할 수 있습니다.
이렇게 구한 Loss function은 convex한 형태이며 local minima를 가지지 않습니다.
그렇게 구한 Linear Model은 Solution을 주지 못하는 경우가 자주 있습니다. 따라서 변화량을 다음 예측에 반영하는데, 이를 알다시피 Gradient Descendent라고 합니다.
여기서 a는 학습률입니다.
이런 update rule은 두가지정도로 사용을 하는데, Batch Gradient Descent와 Stochastic Gradient Descent입니다.
Batch는 묶음으로 진행하며, 느리지만 수렴을 보장합니다.
Stochastic의 경우, 한번에 하나씩 진행하며, 빠르지만 수렴을 보장하지 못합니다.
이런 Update Rule을 수식으로 연산해 보면 다음과 같아집니다.
Multivariate Linear Regression의 경우 변수가 여러개일 경우입니다. 기본적인 방법은 동일합니다만, 여러 변수가 있다보니 행렬을 이용해 계산합니다.
이제 앞 내용과 달리, Linear Classifier를 보겠습니다. Linear하므로 A와 같이 되는 것이 이상적이지만 b처럼 되는 경우도 있을 것입니다.
즉, Linear하므로, step function으로 진행 되는데 그 수식은 다음과 같습니다.
Update Rule에 의해 진행을 하면 다음과 같은 그래프들이 나옵니다. 진행 사항들을 보면 10만번을 진행해도 전혀 나아지지 않는 경우도 있으나, Learning rate를 조절하는 것으로 수렴하도록 조절을 할 수는 있습니다.
따라서 우리는 좀더 나은 결과값을 위해 임계치 함수로서 Logistic function을 이용합니다. (위의 경우 sigmoid 함수에 wx를 정의역으로 설정한 것입니다.)
이를 수식으로 표현하면 다음과 같습니다.
그로 인한 결과를 이전과 비교했을 때 상당히 개선됨을 볼 수 있습니다.
그럼 이제, Neural Network를 도입해봅니다. 위 그림은 매우 단순화 시킨 그림이지만 그 목적이 무엇인지만 알면 됩니다.
bias값을 바꾸는 것으로 임계치 값을 이동시킵니다.
이런 network는 구조적으로 2가지가 있는데, Feed-forward와 Recurrent 입니다.
Feed-forward 는 feedback이 없거나 Loop가 없는 경우입니다.
Recurrent는 이전의 결과가 앞으로 올 결과에 영향을 미치는 경우입니다.(참고)
feed-forward 함수의 예시입니다.
이런 경우 알다시피 XOR는 적용하기 힘들다는 것을 알고 있습니다.
이를 수식화해서 진행해보겠습니다. weight를 어떻게 Learning할 것인가에 대한 수식입니다.(g는 activation function)
input들이 동일한 형태(boolean, integer 등)일때 혹은 Majority같이 다수 중에서 어떤값이 더 많은가를 체크하는 경우, Perceptron Learning은 output을 매우 잘 예측합니다. 그러나 Descrete하거나 Continuous같이 다양한 형태에 대해서는 Decision Tree가 더 효율이 좋습니다.
즉, 이미지같은 경우, 하나의 이미지가 데이터라 볼 때, 같은 종류의 데이터를 나누는 것이므로(어떤 속성이 더 많은 영향을 미치나 알아보는 것) 잘 하지만 Restourant 문제같은경우는 그렇지 못합니다.(Node들이 매우 다른 경우)
이런 단점을 조금 극복해보자(single layer는 너무 단순하다)는 의미에서 나온 것이 Multi Layer입니다.
즉, Hidden unit이 새롭게 나오게 되는데, 쉽게 말해 input을 한번 가공을 하여, 새로운 input을 적용시키는 것입니다.
보통 hidden units는 exponential로 필요합니다. 그 예시가 나와있습니다.(n으로 나누는 이유는 001, 010, 100이 같기 때문에)
위 그래프는 아래설명으로 나와있습니다. (두 임계함수를 합한것은 ridge 형태, 그런 ridge형태를 합하면 bump형태)
앞서 single Layer의 경우에선 한번의 weight들만 update하면 됬지만, 지금은 중간 hidden layer에 관해서도 업데이트가 되어야 합니다.
따라서, 출력이 다시 input이 되는 연산이 필요합니다.
그 수식 연산은 다음과 같습니다. output을 그 전단계에서 활용하는 형태가 될 것입니다.
이것을 반복하면 error는 줄어들게 됩니다. 단, local Minima에 빠질 수 있습니다.
그렇게 하면 4 hidden unit이 있을 때, Decision Tree만큼은 아니지만 추론에 크게 문제 없을 정도로 추론이 가능해집니다.
여기서, 값이 더욱 복잡하거나, output을 모를 때, Layer가 더욱 깊어진다면 Deep Neural Network가 될 것입니다.
*/
계산그래프는 계산을 노드와 화살표로 표현합니다.
노드는 원으로 표기하고 원 안에 연산 내용이 포함됩니다.
계산그래프를 이용하면 다음과 같이 장문의 문제를 심플한 그림으로 표현이 가능하고, 여기서 연산자인 곱셈만을 연산으로 취급해 다음과 같이 사과의 개수나 소비세를 변수 취급하여 표현할 수 있습니다.
또한 계산 그래프는 ‘국소적 계산’을 통해 결과 값을 얻게 되는데, 가령 여러 식품들과 사과를 산다고 할 때, 여러 식품들이 어떤 계산과정을 거쳐 값이 나오던지 간에 이 값과 사과의 값만을 더해주는 것으로 최종 결과를 얻을 수 있다는 것입니다.
국소적 계산 뿐 아니라 계산 그래프를 사용하는 이점 중 하나는 역전파를 통해서 미분을 쉽게 계산할 수 있다는 것입니다.
앞의 문제에서 사과의 값이 올랐을 때 총 지불 금액이 얼마나 오를까 하는지를 알고 싶을 때 다음과 같이 국소적 계산을 통한 미분값을 역으로 전달하게 되면 다음과 같은 결과를 얻을 수 있습니다. 이것은 사과의 값이 아주 조금 올랐을 때, 지불금액은 그 조금 오른 값에 2.2배만큼 오른다는 뜻이 됩니다.
이처럼 역전파의 계산 절차는 신호를 E라 했을 때 E에 노드의 국소적 미분을 곱해 다음 노드로 전달하는 것이 됩니다.
이 때 역전파를 하는 과정에서 사용되는 개념이 바로 연쇄법칙입니다. z와 t 두 개의 함수가 있다고 할 때 우리는 z를 x에 대해 미분하려면 합성함수 미분법에 입각하여 식을 나타낼 수 있고, 이것이 바로 연쇄법칙입니다.
앞의 식을 계산그래프로 나타내면 다음과 같습니다. (**2는 제곱 기호)
역전파 되는 값은 각각의 노드에 들어온 입력 신호의 미분 값입니다.
덧셈 노드에 대한 역전파는 단순히 입력 값을 그대로 흘려보냅니다.
곱셈 노드에 대한 역전파는 순전파 때의 입력 신호들을 서로 바꾼 값을 곱해서 흘려보냅니다. 이는 일반 수식을 미분할 때를 생각하면 이해가 잘 되실 겁니다.
(덧셈의 경우 z = x+y, 곱셈의 경우 z = xy)
구현 코드입니다.
ReLU함수는 출력이 0 이상이면 값을 그대로 전파하고, 0 이하이면 0 을 전파하는 함수입니다.
시그모이드 함수 역시 ReLU 함수와 마찬가지로 오차역전파를 위해 사용되는 함수이나, 이번 장에서는 시그모이드 함수가 아닌 ReLU함수를 이용하여 이층신경망을 구현하였습니다.
어파인 변환은 행렬의 내적과 같은 의미로 사용되어, 가중치 신호의 총합을 계산하기 위한 계층입니다.
행렬 모양이 (2,), (2,3), (3,)과 같이 표기된 이유는 넘파이에서의 shape 함수의 출력과 형태를 통일시키기 위해서 입니다.
구현 코드입니다.
소프트 맥스 계층은 앞에서의 순전파 때의 출력 값을 정규화시켜 확률과 같은 형태로 표현하기 위한 계층입니다.
여기서 소프트 맥스에 대한 손실함수로 교차 엔트로피 오차를 사용합니다.
이렇게 하면 소프트맥스 계층의 결과가 (y1-t1, y2-t2, y3-t3)처럼 신경망의 현재 출력과 정답 레이블의 오차를 있는 그대로 나타낼 수 있습니다.
이제 전체적인 개요를 살펴보면, 신경망 학습을 하기 위해 미니배치를 통해 훈련 데이터들을 무작위로 가져오고(다른 방법들도 많습니다.) 이 때의 손실 함수 값을 줄이기 위해 각각의 가중치 매개변수의 기울기를 구합니다.
이 기울기가 가중치의 값을 어떻게 조정할 지에 대한 척도가 됩니다. 그리고 기울기에 따라 가중치의 값을 적절하게 갱신하는 동작을 계속적으로 반복해서 오차를 줄이는 것이 목표입니다. 오차역전파는 기울기를 산출하여 매개변수를 갱신하는 부분이 됩니다.
전체 코드 중에서 이번 장에서 중요하게 다룬 부분입니다.
먼저 앞에서 구현한 어파인 계층과 ReLU계층을 번갈아가며 계층을 쌓고, 마지막 계층을 소프트맥스(교차 엔트로피 오차 함수가 적용된)로 하여 출력을 냅니다.
그리고 가중치 매개변수의 기울기를 오차역전파를 통해 구하게 됩니다.