강몬드의 프로그래밍 이야기

신경망과 딥러닝 5.Gradient descent 학습법 본문

학습/딥러닝

신경망과 딥러닝 5.Gradient descent 학습법

강몬드 2016. 1. 28. 21:55

Gradient Descent Learning Algorithm

   이제 우리는 신경망을 갖고 어떻게 숫자를 인식하게 학습할 수 있는가? 먼저, 학습을 위한 학습데이터가 필요하다. 우리는 분류 결과값을 갖고 손 글씨로 쓰여진 문자들의 이미지들의 집합인 MNIST 데이터 셋을 이용한다. MNIST의 이름은 NIST(표준 기술 미국 국립 연구소)에 의해 수집 된 데이터 셋 중 일부가 수정됐다하여 MNIST라 붙여졌다.


   다음은 MNIST에서 가져온 몇 개의 이미지이다.   


   MNIST 데이터는 두 부분으로 되어 있다. 첫 번째 부분은 60,000개의 이미지 학습 데이터로서 사용되고 이미지는 gray scale이며 28x28크기의 픽셀 값을 갖는다. MNIST 데이터 셋의 두 번째 부분은 10,000개의 이미지 테스트 데이터로서 사용된다. 우리의 신경망이 숫자를 얼마나 잘 학습했는지 평가하기 위해 테스트 데이터를 사용한다. 


   우리는 학습의 입력을 x로 표기한다. 각 학습의 입력은 28x28=784 차원의 벡터이고 벡터의 각 요소들은 이미지의 한 픽셀 값을 가리킨다. 원하는 출력은 y=y(x)로 표기할 수 있다. 여기서 y는 10차원의 벡터이다. 예를 들어, 만약 학습 이미지 x가 '6'이라면 그때 y(x) = (0, 0, 0, 0, 0, 0, 1, 0, 0, 0)이 신경망이 원하는 출력 값이다. 


   우리가 원하는 건 신경망에서의 출력이 모든 학습 입력 x에 대해 y(x)로 근사하도록 가중치와 bias를 찾을 수 있는 알고리즘이다.  목표를 달성하고 정량화하기 위해서 다음과 같은 비용함수를 정의해야한다. 


      여기에서 w는 신경망의 모든 가중치의 집합을 나타내고, b는 모든 가중치, n은 학습 입력의 전체 수, a는 입력 x를 받았을 때 신경망으로부터 계산된 출력 값 그리고 x는 모든 학습 입력의 합이다. 물론 x에 대한 출력 a는 w와 b에 의해 계산되는 값이지만 명시적으로 이러한 종속성을 표시하지 않은 간단한 표기를 유지한다. 표기 ||v||는 벡터 v의 길이 함수다. 우리는 이 C를 이차 비용 함수로 부르기로 하자. 이건 때때로 평균 제곱 오차 또는 단순히 MSE로도 알려져 있다. 이차 비용 함수의 형태에서 우리는 모든 항이 양수이기 때문에 C는 양수라고 할 수 있다. 또한 비용 C(w,b)가 작아지는 시점, 즉 에 가까워 질수록 우리의 학습 알고리즘이 가중치와 bias를 잘 찾아가고 있다고 말할 수 있다. 즉, 우리는 가능한 한 비용을 작게하도록 가중치 및 바이어스를 찾아야 한다. 이를 gradient descent 알고리즘을 사용해서 할 수 있다. 


   2차 비용함수를 왜 소개했는가? 원래 우리는 네트워크에 의해 제대로 분류 된 이미지의 수를 주로 관심을 갖고 있지 않나?  2차 비용같은 대리 지표를 최소화하는 것보다 직접 그 수를 최대화하려고 하는게 정확하지 않나? 그 문제는 분류된 이미지의 개수가 네트워크의 weights와 biases의 적절한 값을 대표하는게 아니기 때문이다. 과거에 해봤듯이 weights와 biases 값의 작은 변화를 준다해도 분류된 이미지의 개수에 어떤 변화가 발생하지는 않는다. 이런 이유로 향상된 성능을 가져오는 weights와 biases의 변화값을 찾기란 어렵다. 우리는 대신 2차 비용과같은 비용함수를 사용하여 비용의 개선을 가져 오도록 weights 및 biases의 변화 값을 쉽게 판명할 수 있다. 즉, 우리가 2차 비용의 최소화에 먼저 초점을 맞춘 이유다.


   왜 위 식과 같은 이차 함수를 사용하는 지 의문이 들 수 있다. 이후 우리는 비용함수를 재검토하고 일부 변경할 예정이다. 그러나 위 식의 비용함수는 신경망 학습의 기본을 이해하기에 적절하기 때문에 일단 이 식을 사용한다. 


   신경망 훈련에서 우리의 목표는 이차 비용함수 C(w, b)를 최소화하는 weights와 biases를 찾는 것이다. 이는 잘 정해진 문제이지만 산만한 구조의 느낌을 저버릴 수 없다. w와 b의 대한 이해와 함수의 배경, MNIST와 같은 구조의 선택 등등이 있다. 우리가 그 구조의 대부분을 무시하고 그냥 최소화 측면에 집중함으로써 큰 이해를 할 수 있다. 이제 우리는 비용함수의 특정 형태, 신경망 연결에 대한 모든 걸 잊어버리고 대신 단순히 많은 변수의 함수가 주어진 상태에서 그 함수를 최소화하는 문제를 상상해보자. 우리는 기울기 하강(gradient descent)이라고 불리는 기술을 알아야한다. 기울기 하강 알고리즘은 최소화 문제를 해결할 때 사용된다. 그럼 이 알고리즘을 사용하여 신경망의 이차 비용함수를 최소화 해보자. 


   이제 함수 C(v)를 최소화한다고 가정해보자. 여기서 v는 실수 값을 가진 많은 변수 v= v1, v2, v3,...를 가리키고 위 비용함수에서 w, b를 v로 대체하였다. 이로써 신경망에 대한 생각은 더 이상 하지말고 C(v)를 최소화 하는 문제에 집중할 수 있다. 함수가 아래 그림처럼 두 개의 변수 v1, v2만으로 이뤄졌다고 상상해보자.  



   우리가 원하는 건 C가 global minimum(지역 최소값)을 갖는 방향을 찾는 거다. 지금은 물론 눈으로 그래프를 살피고 대략적인 minimum을 찾을 수 있다. 그런 점에서 나는 너무나 간단한 function을 보여주고 있었다. 일반적인 function에서 C는 많은 변수를 갖는 복잡한 함수일거다. 그리고 그 function에서 단지 눈대중으로 그래프에서 최소값을 찾기란 어렵다.


   문제를 해결하기 위한 하나의 방법은 미적분을 사용하여 최소값을 찾을 수 있다. 우리는 미분을 계산할 수 있었고 그 값들을 사용하여 C가 극값을 갖는 위치를 찾아야 한다. 운 좋게 변수가 하나거나 적은 수로 이뤄진 함수일 때 적용될 수 있다. 훨씬 많은 변수를 갖게되면 혼돈속으로 빠지게 될 수 있다. 신경망에선 훨씬 많은 변수들을 필요로 한다. - 가장큰 신경망의 경우 10억개 이상의 weight와 bias를 다루는 비용함수를 갖는다. 미적분으로 최소화하는 방법은 먹혀들지 않을거다.


(딱 2개의 변수를 갖는 함수 C를 그려보면서 통찰력을 얻을 수 있다고 주장해놓고, "이봐, 두개보다 많은 변수를 갖게되면 어떻게 하지?" 라고 말하고 있다. 하지만 2개 변수를 갖는 C를 살펴봄으로써 이해를  도우는데 정말로 도움이 됐다고 생각한다.) 


   미적분으로는 할 수 없지만 그와 유사한 적당한 알고리즘이 제안될 수 있다. 우리는 function을 계곡의 종류로 생각한다. 눈을 가늘게 뜨고 위 그래프를 살피면, 계곡처럼 생각 할 수 있다. 그리고 계곡의 경사로 볼을 굴리는 모습을 상상하자. 우리의 경험은 볼이 당연하듯이 계곡의 밑으로 내려간다고 말해준다. 우린 이 생각들을 함수의 최솟값을 찾는데 적용할 수 있지 않을까? 우리는 볼의 시작위치를 랜덤하게 잡고, 계곡의 밑으로 떨어지는 공을 가정해보자. 우린 이 동작을 C의 미분값을(아마도 2차 미분까지) 구함으로서 간단하게 해야한다. 미분 값들은 계곡의 지역적인 형태에 대한 우리가 필요한 모든 것들을 말해줄 것이다. 그리고 어떻게 우리의 볼이 굴러가야하는지 알려준다.


   위에 쓴 내용에 근거하여 너는 마찰과 중력 등등을 고려할 필요가 있다고 생각하면 우리가 뉴턴의 공식을 적용해야한다고 생각할 수 있을 것이다. 사실 우리는 볼의 움직임을 현실적인 조건을 모두 고려하여 바라보진 않는다. 그저 함수 C를 초기화하는 알고리즘을 고안하는 중일뿐, 물리 법칙의 정확한 계산을 원하는게 아니다. 이를 구하는데 있어서 볼의 움직임이 우리의 이해를 도울 수 있다. 그래서 물리적으로 계산을 하기보다는 간단하게 질문을 가져보자. 우리가 오늘 하루 신이되어 물리를 자유자재로 다룰 수 있고, 볼이 어떻게 굴러가야하는지를 명령할 수 있고, 볼이 항상 계곡의 밑바닥으로 가게끔 움직이게 하는 방법을 무엇일까?


   이 질문을 요약하면, 볼을 v방향으로 Δv크기만큼 이동하고, v2 방향으로 Δv크기만큼 이동했을 때 무슨일이 벌어지는지 생각해보자. 함수 C의 변화값을 다음의 미적분 계산할 수 있다.






   우리는 ΔC 값을 negative하게 만드는 Δv과 Δv2 를 구해야 한다. 이 값들이 볼이 계곡으로 내려가게 

하는 값들이 되야한다. 값을 구할때 편의를 위해  벡터로 정의하자. 여기서 T는 transpose, 벡터의 열과 행을 뒤바꿔주는 연산이다. 또 C의 gradient값 를 편미분의 벡터로 표현할 수 있다.  이를 

 gradient 벡터로 정의하자. 



   곧, 위에 함수가 다음처럼 쓰여질 수 있다.


   



   

출처 : http://neuralnetworksanddeeplearning.com/index.html










Comments