간단한 신경망 모델을 만들어보자(1편)


https://gall.dcinside.com/board/view/?id=programming&no=2538887&page=1

간단한 신경망 모델을 만들어보자 (feat. 사이토 고키)주말에 심심해서 도서관에서 시원하게 에어컨이나 쐬면서 책을 읽었다.대충 000번대에서 슥 훑어보다가 딥러닝 분야에서 제일 눈에 띄는 책을 하나 집었다"밑바닥부터 시작하는 딥러닝"(사이토 고키 저, 한gall.dcinside.com





viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73dea8efa11d02831c5a13172a783ed9d276af118494d34acad0acad5429c533e6c36ffa96e81525c3ae59a6b06bd723fe8be07de8861e00491f2



저번 게시글에 이어서 신경망 모델에 대한 개념과 간단한 신경망 모델을 코드로 구현하는 과정을 작성한다.


1편에서는 인공신경망 연구에서 기록상 최초로 등장한 논리 회로와 이를 발전한 퍼셉트론,


가중치 매개변수의 미분값을 구하는 역전파 알고리즘까지 알아보았다.


이번에는 역전파 알고리즘의 개념을 이용하여

가중치 매개변수의 최적값을 모델이 직접 찾아가는 데이터 주도 학습과 이에 대한 개념을 알아보고


간단한 이미지 데이터 분류 모델을 기획하고 코드로 구현해보도록 한다.






데이터 주도 학습


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73dea8efa11d02831c5a13172a783ed9d276af118494d34acad0acad5429c533e6c36ffed3ed6543b496329481572d0936c00795e3ddd444c19ec4d14fc7314




기존 인공신경망 연구에서는 선형 패턴을 넘어 비선형 패턴을 해결할 수 있는 논리 회로를 구현해냈다.

하지만 여전히 입력 데이터에 주어지는 가중치는 연구진들이 직접 설정해 주어야 했는데,


역전파 알고리즘의 등장으로 논리 회로속 매개변수들(가중치, 입력 데이터 등등)의 미분값을 찾아내면

매개변수를 손보기 쉽다는것을 알아냈고,


이를 넘어 처리할 데이터에 대해 초기 매개변수값으로 최초의 최종 출력값(논리 회로를 통해 논리 문제를 풀어낸 답)을 뽑아내면,

인공신경망 모델이 최종 출력값의 오차(논리 문제의 답과 모델이 구한 답과의 차이값)를 줄이는 방향으로

매개변수의 최적값을 찾아가는


외부의 도움 없이 신경망 모델이 스스로 학습하는 자율 학습 방법을 연구진들은 고안해냈다.





가중치 최적값 찾기


가중치의 최적값을 어떻게 찾으면 좋을까?


먼저 퍼셉트론 알고리즘에서 최적의 매개변수 값을 찾는 과정을 보자.


1. 신경망 모델로 풀어내고자 하는 논리 문제(학습 데이터)를 입력 신호로 집어넣는다.


2. 정답에 가까운 신호를 크게 확대하고 오답인 신호를 축소시키는 가중치를 대입한다

(만약 정답이 "YES"라면, "YES"값을 내는 뉴런의 가중치 값을 크게 설정하고, "NO" 값을 내는 뉴런의 가중치 값을 작게 설정해서

최대한 정답이 "YES"값에 가깝도록 설정한다.)


3. 기존의 학습 데이터와 비슷한 데이터를 입력하여 이 또한 올바른 정답을 도출해 낼 수 있는 가중치를 조금씩 수정해 간다.


4. 3의 반복을 통해 비슷한 어떤 데이터들에도 정답에 가까운 값을 도출해내는 최적의 가중치 값을 계산해낸다.



최적의 매개변수 값을 도출해내는 과정은 모델을 학습시키는 과정에서 매번 가중치 값을 수정해서

정답과 최종 출력값 사이의 오차를 줄여나가는 번거로운 작업을 수행했다.


이후 역전파 알고리즘의 등장으로 미분을 이용하면 매개변수의 변화량에 따른 최종 출력값의 변화를 수식으로 쉽게 표현해 낼 수 있게 되었다.


이를 응용하여 매개변수의 최적값을 도출하기 위해 수식으로 표현한 함수들이 여러 등장하였다.




손실 함수


신경망 모델에 학습 데이터를 이용하여 최초로 가중치를 설정하고 최종 출력값을 산출하고 모델을 평가하는데,

이 모델을 평가할 때 기준을 "최종 출력값이 정답에서 얼마나 동떨어졌나?" 라고 하자.

현재 신경망이 훈련 데이터를 얼마나 잘 처리하지 못했냐, 성능이 얼마나 나쁘냐를 지표로 나타내는것을 손실 함수 라고 한다.


어째서 모델의 성능이 얼마나 좋은지를 따지는게 아닌, 모델이 얼마나 못하냐, 얼마나 멍청한가를 따지는게 모델을 평가하는 지표가 되었을까?

신경망 모델은 논리 문제의 대한 정답을 도출해 내기 위한 모델인데, 모델의 정확도를 따지는게 아닌 오류를 따지는 것일까?


이는 최적의 가중치 값을 도출해 내는 데에 "미분"이 중요한 역할을 하기 때문이다.





viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73dea8efa11d02831c5a13172a783ed9d276af118494d34acad0acad5429c533e6c36ffed3ed6543b496329481572d0936c00790960881241ba6aba5d14e3c0



역전파 알고리즘에서 핵심은 "매개변수의 변화에 따른 최종 출력값의 변화량" 이다.

가중치에 대해 최종 출력값을 미분하는것이 역전파 알고리즘의 핵심이고,

더 나아가 최적의 가중치 값을 도출해 내기 위한 최종 출력값을 평가하는 지표를 사용해서


"가중치에 대한 지표의 미분값"을 찾아내는게 최적화를 위한 방법으로 제시된 것이다.


미적분학에서 어떤 함수를 미분하기 위해서는 전제조건이 필요하다.




1. 함수가 주어진 구간에서 끊어진 곳이 없이 연속이어야 한다.


2. 함수가 주어진 구간에서 미분 가능해야 한다.

(미분 가능성은 주어진 구간의 모든 점에서 적어도 한번은 미분할 수 있어야 한다는 의미이다)




이 사실만으로는 아직 정확도를 사용하지 않는 이유를 알 수 없다.


예시를 이용해보자.


어떤 신경망 모델에 100장의 시험 데이터로 테스트를 했을 때 정답을 맞춘 데이터가 50장이라고 한다면, 이 모델의 정확도는 50% 이다.

만약 가중치를 아주 조금 변경하더라도 모델은 여전히 50장의 정답만을 맞출 것이고 모델의 정확도는 여전히 50%일 것이다.

가중치를 계속해서 아주 조금씩 변경하다보면 모델이 51장을 맞출 순간이 올 것이고 이 때의 정확도는 51%이다.


이처럼 모델의 정확도는 이산 분포 형태로 정해져 있어서 미분이 불가능 하거나 대부분의 장소에서 미분값이 0이 된다.

(가중치의 값이 변하더라도 모델의 정확도가 여전히 유지되었다가 특정 값에서 계단식으로 변했다!)


하지만 손실 함수는 모델이 얼마나 못하는지를 연속적인 값으로 나타내기 때문에

가중치 값을 아주 미세하게 변경해도 손실 함수의 값은 계속해서 변화한다.


가령 모델이 내놓은 답과 정답과의 오차를 제곱한 값을 모두 더한 오차제곱합은

초기에는 0.09750000000000000031의 값을 가졌다면, 가중치 값을 아주 미세하게 변경하였을 때 0.09348000000000000005을 가질 수 있다.





기울기와 경사 하강법


그럼 계속해서 최적의 가중치 값을 찾아내는 방법이 무엇있지 알아보자.


위에서 정확도는 미분이 불가능 하거나 대부분의 장소에서 미분값이 0이 되는 것을 알았고,

손실 함수는 연속적인 값을 가지기 때문에 미분이 가능하고 미분값이 0이 되는 구간이 아예 없거나 적다는것을 알았다.


모델을 평가하기 위한 지표로 손실 함수를 이용하는데,

손실 함수는 모델이 얼마나 못하느냐를 따진다고 했다.


손실 함수의 값을 최소로 만드는 값이 곧 최적의 가중치 값이 된다.

(손실 함수의 값이 작아질 수록 모델이 덜 못하고 있다고 할 수 있다!)


손실 함수는 연속적인 값을 가지기 때문에


손실 함수의 그래프를 따라가다 보면 손쉽게 손실 함수의 최솟값을 찾아낼 수 있을 것이다.


하지만 말과는 달리 손실 함수의 최솟값을 찾아내는 일은 쉽지가 않다.


우리가 쉽게 접했던 그래프는 2차 평면에서 그려낸 간단한 그래프였지만,

신경망에서 사용하는 손실 함수의 그래프는 그려내기도 힘든 어려운 그래프 이거나

매개변수의 개수에 따라 2차 평면을 넘어, 3차원 또는 그 이상의 그래프가 될 수도 있다.

(매개변수가 100개가 된다면 이론상 100차원이 될 수도 있다..)


(2차원이 평면이고 3차원이 공간, 4차원이 시공간인데, 100차원이 대체 뭐냐? 라고 할 수 있지만

실제 선형대수학에서는 100차원, 그 이상의 고차원에 대한 수식을 다루기도 한다.. 궁금하면 선형대수학에 대해 공부해보자)




viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73dea8efa11d02831c5a13172a783ed9d276af118494d34acad0acad5429c533e6c36ffed3ed6543b496329481572d0936c00790c3cdc17411c2d503d768354




그물망이 아래로 축 처진듯한 모습의 그림은 매개변수가 2개 이상인 함수를 3차원에서 그린 그래프이다.

이는 3차원에서도 그리기 쉬운 편에 속하고 이보다 굴곡이 더 심한 그래프가 주로 나타난다.


그래프를 그려내기도 힘든 함수들의 최솟값을 찾아내는 효율적인 방법은

"함수가 가장 움푹 패인 저점"을 찾아내는 것이다.


만약 아주 작은 사람을 그래프 위에 올려놓고 최솟값을 찾으러 가라고 시키면, 아주 작은 사람은 내리막길을 따라

가장 낮은 지점을 향해 갈 것이다.


아주 작은 사람의 입장에서 바라보면, 현재 위치 값보다 작은 값을 가지는 지점이 내리막길 끝에 위치해 있는 것이다.


즉, 함수의 기울기가 낮은 값을 따라가다 보면 함수의 최솟값에 도달하게 되고

다른말로 미분값이 낮으면 "최솟값으로 향하는 길"이 형성된다고 볼 수 있다.


"최솟값으로 향하는 길"이라 표현한 이유는


예시로 들은 그물 형태의 그래프는 보이는 지역이 함수 전체 구간에 대해 최솟값을 갖는 지역이다.

하지만 산의 모양처럼 이곳 저곳이 굴곡진 곳에서는 움푹 패여있는 구간이 무조건 최솟값을 갖는 지역이라고 할 수 없다.


기울기가 아래로 향한다고 해서 무조건 적인 최솟값이 아니기에 기울기는 최솟값을 찾는 이정표의 역할을 하는 것이다.


이처럼 모델이 함수의 기울기를 따라 최솟값을 찾아내는 과정을 경사 하강법 이라고 하고,

특정 구역의 최솟값을 찾는 것을 넘어 전역에서 최솟값을 찾기 위한 방법들로


실제 구슬을 올려놓은 것 처럼 물리 법칙을 적용시킨 "모멘텀 기법"

학습률을 감소시키는 AdaGrad, 지수이동평균을 이용한 RMSProp 기법 등이 제시되었고


이런 방법들을 "확률적 경사 하강법" 이라고 한다.




신경망 모델 기획



퍼셉트론으로 대략적인 신경망 모델의 내부 구조를 엿보았고


인공 신경망의 고질적인 문제였던 가중치 값을 사람이 매번 갱신해 주어야 한다는 문제와

최적의 가중치 값을 찾기 어렵다는 문제에 대해


최적의 매개변수 값을 찾는 방법이 수학적으로 제시되었고,

이를 알고리즘으로 구현해내 모델에 적용하면


이윽고 사람의 손을 거치지 않고도 모델이 자율적으로 학습할 수 있다는 것을 알았다.




이제 자율적으로 학습하는 신경망 모델을 만들기 위한 기획을 세워보자.




1. 어떤 데이터를 다루는 모델인가?


2. 데이터를 통해 어떤 결과를 도출하길 원하는가?


3. 모델의 구조는 어떻게 설계할 것인가?




실제로 신경망 모델의 기획 단계에서는 이보다 더 세부적이고 복잡한 항목들을 따지지만,

크게 세 가지만 묶어서 생각해보도록 하자.




어떤 데이터를 다루는 모델인가?


퍼셉트론을 설명하면서 신경망은 논리 문제를 해결하는 구조였다.


어떤 데이터를 다룰 것인지는 곧 어떤 논리 문제를 다룰 것인지를 정하는 것이다.


신경망 모델에서 다루는 데이터에는 주로 이미지 자료, 영상물, 자연어, 음성 데이터 같은 것들이 사용된다.


어떤 데이터를 다루는지에 따라 모델의 구조와 복잡성을 미리 예측할 수 있고

데이터의 전처리, 데이터를 활용하기 위한 기법 등 부가적으로 고려해야 할 사항들이 발생한다.


사용할 데이터를 미리 고려하지 않고 모델을 설계하면 논리 해결을 위한 적합한 과정이 이뤄지지 않을 수 있고

문제를 제대로 해결할 수 없는 모델이 만들어 질 수 있다.




데이터를 통해 어떤 결과를 도출하길 원하는가?


어떤 데이터를 사용할지 정했다면, 데이터들로부터 어떤 결과값을 산출할지, 산출한 데이터를 어떻게 가공할지를 정해야 한다.



고속도로의 상황을 녹화한 영상 데이터들을 사용하는 예시를 들어보면,


영상 속 자동차들의 속도를 계산해서 해당 자동차가 과속을 하는지 아닌지

또는 영상 속 물체가 자동차인지 아닌지를 구별하게 한다거나

운전자의 행동 패턴을 파악하여 운전자의 상태를 구별할 수 있고,


특정 기간 동안 집계된 자동차의 수나 속도를 파악하여

어느 시간대에 고속도로를 이용하는 자동차가 많을지, 언제 차가 막힐지를 예측하는 모델을 구상할 수 있다.


이처럼 어떤 결과를 도출해 내느냐에 따라 주어진 데이터의 논리 문제가 어떤 문제인지를 구분하는데,

어떤 상태인지 분류하는 분류(classification)문제 또는 입력 데이터와 연속적인 값을 예측하는 회귀(regression)문제로 나눌 수 있다.





어떤 논리 문제를 해결하는지에 따라 신경망 모델이 다룰 데이터들의 전처리 방식이 달라지고, 모델의 내부 구조 또한 달라진다.


결과적으로 신경망 모델을 통해 얻고자 하는 결과값과 사전에 준비할 데이터들이 서로 어울려야

개발자가 원하는 방향대로 신경망 모델이 제 기능을 수행할 수 있다.




모델의 구조를 어떻게 설계할 것인가?


어떤 문제를 어떻게 다룰 것인지 정했다면 모델을 어떻게 설계할지 방향성이 주어진것과 다름없다.




7cf3c028e2f206a26d81f6e44280736a8b



그림은 신경망을 간단하게 도식화 한 것이다.


그림으로 보기에는 은닉층이 존재하는것 외에는 퍼셉트론과 큰 차이점이 없다.

신경망에서 데이터를 입력받고 출력하는 아주 간단한 과정을 살펴보자.


1. 입력 계층의 입력 뉴런에서 전처리한 데이터를 입력받는다.


2. 입력 뉴런에서 은닉층의 뉴런으로 전처리한 데이터에 가중치를 곱한 값을 전달한다.


3. 은닉층의 뉴런은 해당 뉴런과 연결된 모든 입력 뉴런들로부터 받은 신호들을 더한 뒤 활성화 함수를 이용해 값을 처리한다.


4. 활성화 함수로 처리한 값에 가중치를 곱해 같은 은닉층의 다음 뉴런에게 전달한다.


5. 입력 뉴런들과 연결된 뉴런과 마찬가지로 은닉층의 뉴런들에게 전달받은 신호들을 모두 더한 뒤 활성화 함수를 이용해 값을 처리한다.


6. 4, 5 단계를 출력 뉴런에 도달할 때 까지 반복한다.


7. 은닉 계층으로부터 신호를 전달받은 출력 뉴런이 최종 출력 값을 출력 데이터로 내놓는다.



여기서 말하는 활성화 함수는 뉴런과 뉴런 사이에 신호(데이터 값)가 전달될 때 가중치를 곱하는 것 처럼

뉴런에서 데이터 값에 변화를 주어 데이터를 보다 복잡하게 하여 세부적인 패턴을 파악하게 하거나

단순하게 하는 등 데이터에 비선형적인 형태를 추가하여 모델의 표현력을 높이고, 데이터를 효율적으로 처리할 수 있게 한다.




예시로 들은 신경망의 간단한 과정들을 통해

신경망을 설계할 때 고려해야 할 사항을 정리해보면 다음과 같다.




1. 입력 뉴런을 몇 개로 지정할 것인가.


2. 은닉층의 뉴런을 몇개로 정하고 몇개의 층을 지정할 것인가

(층이 많아지면 이를 층이 깊어진다고 하고 깊은 층을 가진 신경망을 딮러닝 (deep learning)모델 이라고 한다)


3. 활성화 함수를 각각 어떤 것으로 지정할 것인가


4. 출력 뉴런을 몇 개로 지정할 것인가.


5. 초기 가중치를 어떻게 지정할 것인가.


6. 가중치를 갱신할 방법으로 무엇을 지정할 것인가.




이 외에도 어떤 데이터를 다루고 어떤 결과값을 산출해 내느냐에 따라 추가로 고려해야 할 사항들이 존재한다.










3편에서 "밑바닥부터 시작하는 딥러닝"의 내용을 바탕으로


0~9까지 무작위로 작성된 손글씨 이미지 데이터를 이용하여

해당 이미지에 어떤 숫자가 적혀있는지 분류하는 모델을

파이썬 언어로 작성하고


작성한 모델을 효율적으로 학습시키는 방법과

모델을 개선시킬 수 있는 방법,

신경망과 관련된 다른 기술들을 알아보도록 하자.