기획자 본인만큼 잡다한 블로그

greentec.egloos.com

포토로그




신경망 알고리즘 - XOR 문제, 와인 분류 문제 AI


오래 전부터 공부해왔지만 별다른 진전이 없었던 신경망 알고리즘을 다시 공부하기 시작했다. 일단 한번 배워 놓으면 여러 가지 분야로 응용이 가능한 유익한 학문이다.

신경망 알고리즘은 보통 전통적인 문제 해결법(전통적 알고리즘. DP, 이진탐색 등)으로 풀 수 없는 문제들을 풀기 위해 사용된다. 신경망 알고리즘에 대해 알기 위해 이 글을 찾아온 사람들은 퍼셉트론의 역사와 마빈 민스키의 책 <퍼셉트론>이 제기한 퍼셉트론 무용지물설, 그리고 다층 신경망의 등장으로 이러한 한계를 돌파한 사실 등에 대해서는 이미 수많은 입문서와 인터넷 article을 통해 많이 접했을 것이므로 여기서는 신경망의 정의나 역사에 대해 많이 다루지 않으려고 했으나... XOR 문제 해결 이야기를 해야 하므로 결국 조금은 이야기를 하고 넘어가야 할 것 같다.

주의 : 수학적인 내용은 가급적 다루지 않으므로 필요하신 분들은 다른 참고서적을 보시기 바랍니다. 죄송합니다 (_ _)



1. 퍼셉트론

- 내용을 아는 분들에게는 비교적 지루한 이야기일 수 있으므로 2번으로 넘어가는 것이 좋다.

퍼셉트론은 간단히 말하면 인간의 신경 세포 하나를 흉내낸 것이라고 할 수 있다. 학창 시절 생물 시간에 배운 내용 중에 자극(stimulus), 반응(response), 역치(threshold)라는 것이 있었다. 특정 자극이 있다면 그 자극이 어느 역치 이상이어야만 세포가 반응을 한다는 것이다.

예) 짜게 먹는 사람은 자기가 평소에 먹는 만큼 음식이 짜지 않으면 싱겁다고 느낀다(역치 이하의 자극은 무시).
싱겁게 먹는 사람이 짜게 먹기 시작해서 오랜 시간이 지나면 예전에 먹던 싱거운 음식에 만족하지 못한다(역치가올라감).


인간의 뇌는 수많은 신경 세포로 구성되어 있는데 이 신경 세포의 행동을 정확하게는 물론 알 수 없지만 위처럼 자극, 반응, 역치 같은 현상을 모델화하여 흉내낸 것이 퍼셉트론, 즉 신경 세포를 모델화한 객체이다.

퍼셉트론을 학습시키는 방법은 간단한데, 보통 목표치(ideal)를 정해주고 현재 계산한 값(output)이 목표치와 다르면 그만큼의 오차를 다시 퍼셉트론에 반영해서 오차를 줄여나가는 방법을 쓴다. 

이런 퍼셉트론을 여러 개 병렬로 배열하여 층(layer)를 만들고, 그 층을 여러 개 배열하면 다층 퍼셉트론이 된다.


위에서 간단하게 소개한 마빈 민스키의 <퍼셉트론>이라는 책은 퍼셉트론의 한계를 지적하는 책인데, 이런 퍼셉트론이 밑에서 소개할 XOR 문제를 해결할 수 없다는 것이다. XOR 문제는 매우 간단한 편에 속하는 문제인데, 이것을 할 수 없다면 그 외의 여러 문제들도 해결할 수 없다는 말이 된다. 이 때문에 신경망 연구계는 한때 암흑기에 접어들었다가 다층 퍼셉트론의 소개로 다시 부흥하여 현재에 이르게 된다. 여기서 다층이라는 말이 무슨 뜻인지는 아래에서 설명하기로 한다.


2. XOR 문제

간단하게 XOR 문제 해결 사례와, 그것을 응용한 와인 분류 문제 해결 사례를 공유하려고 한다. 

XOR 문제는 간단하게 생각하면 XOR 논리 회로를 만드는 것이다. AND는 둘 다 1일 때만 결과 값이 1이 되고, OR는 둘 중 하나라도 1이면 결과 값이 1이 된다는 것은 다 알고 있을 것이다. 이런 사실을 정리하면 아래와 같다.



그런데 XOR은 eXclusive OR, 배타적 논리합이라는 정의대로 둘 중 하나"만" 1일 때 1이 된다.




이걸 그래프로 표현하면 아래와 같은데, AND, OR과 달리 XOR은 선형 불가능성이라는 문제를 제기한다. 입력층이 하나, 출력층이 하나인 신경망은 아래 그림처럼 2차원 평면을 직선으로 분리해서 해를 찾을 수 있다. 
아래 그림에서 decision boundary 1 아래는 0, 위는 1이라면 OR이고, decision boundary 2 아래는 0, 위는 1이라면 AND가 된다.



여기서 글의 초점을 잃어버리는 분들이 있을 수 있다. 신경망을 설명하다가 갑자기 웬 그래프? 
이렇게 생각해보자. 수학적으로 신경망이 어떻게 동작하는지는 생각하지 않고, 신경망은 직선을 나타낸다고 생각하는 것이다. 아마 중학교 수학부터 일차부등식을 일차함수로 나타내서 해를 구하는 방법을 썼던 것으로 기억한다.


근본적으로 이 그림과 같은 문제다. 다만 구하는 해는 평면이 아니라 (0, 0), (0, 1), (1, 0), (1, 1)의 네 점이고, 그 네 점을 둘로 가르는 선을 찾는 문제라고 생각하면 이야기가 간단해진다.

AND와 OR의 경우는 다시 보면 각각 아래와 같이 나타낼 수 있다.



하지만 XOR은 어떻게 나타낼 것인가? 직선으로는 나타낼 수 없다. 그럼 곡선으로?




거짓말같지만 정말 이렇게 접근한 게 아래의 방법이다. 


위에서 본 그림에 더해서 은닉층(hidden layer)라는 하나의 층을 더 만들면 신경망이 그리는 모양이 직선이 아니라 다양한 모양으로 변할 수 있다. 이에 대한 증명은 아래의 서적을 참고하자. (R. Rojas: Neural Networks, Springer-Verlag, Berlin, 1996, CH6.)

그러면 이제 이 구조의 신경망으로 학습을 시키면 되느냐? 그것은 아니고, 한가지 과정이 더 필요하다. 예를 들어 0, 0이라는 입력이 들어왔을 경우 함수에 따라 제대로 계산을 할 수 없는데, 이를 위해서 무조건 1을 입력하는 퍼셉트론 하나씩을 각 층에 더해준다. 아래 그림에서 빨간색 원이 그에 해당한다.




완성된 프로그램을 wonderfl.net에 올려 놓았다. 프로그램이 매우 느리고 비효율적이며 하드 코딩이 많은데, 인터넷에서 찾아본 다른 사람들의 코드는 이미 객체화, 구조화가 완료된 코드라서 나는 일부러 알아보기 쉽도록 식을 그대로 써서 작성했다.




프로그램의 탐색이 100% 잘 실행되지는 않기 때문에 에러 그래프가 같은 지점을 맴돌고 있으면 "Reset" 버튼을 눌러줘야 한다.

위 프로그램에서 Reset 버튼을 누르는 것은 마치 광활한 언덕 위의 한 점을 랜덤하게 선택해서 목적지까지 가는 길을 찾는 것과 같다. 선택된 시작점이 운좋게 목적지와 가까울 수도 있지만, 때로는 아주 멀고 목적지와의 사이에 울퉁불퉁한 언덕이 잔뜩 있을 수도 있다. 탐색 알고리즘이 아주 좋거나 시야가 잘 확보되어 있다면 어디에 떨어지더라도 목적지까지 금방 갈 수 있겠지만, 그렇지 않다면 많은 점을 선택해서 최대한 빨리 탐색점에 도달하도록 하는 것도 좋은 방법이다. 이런 방법이 바로 유전 알고리즘(genetic algorithm)이다.

신경망 알고리즘과 유전 알고리즘을 결합한 방법도 자주 쓰이는 문제 해결법인데, 다음에는 이 주제를 다룰 수 있었으면 좋겠다. 그만큼 실력이 늘어야 이 주제를 더 다룰 수 있을 것 같다.



3. 와인 분류 문제

위의 프로그램으로 와인 분류 문제도 풀어보았다. 와인 분류 문제는 이 분야에서 아주 유명한 문제이다. 
관련된 이야기를 잠시 소개하면(http://www.iainpardoe.com/armaba/extraprob06.htm),
프랑스 보르도 지역에서 나는 와인은 매우 좋은 품질을 가지고 있지만 해마다 기후가 다르기 때문에 와인의 맛에도 영향을 미친다. 때문에 포도를 수확한 해(빈티지)에 따라 달라지는 가격을 와인 전문가(소믈리에)들이 예측하고 있었다.
하지만 <Liquid Assets : The International Guide to Fine Wine>이라는 신문에서 경제학자 세 명이 회귀 분석을 통해 런던 경매장에서의 와인 가격을 예측했다(http://commonsenseatheism.com/wp-content/uploads/2011/01/Ashenfelter-Bordeaux-Wine-Vintage-Quality-and-the-Weather.pdf). 그들은 빈티지, 평균 온도, 강수량 등으로 와인 가격을 전문가들보다 정확하게 예측해냈다는 "기계가 인간을 대신한다"스러운 슬픈 이야기이다. 

뭐 어쨌든 이와 비슷하게 이 글에서 다룰 것은 와인을 분류하는 문제이다. 여기서 주어지는 데이터는 알코올 도수, 마그네슘 함유량 등, 색깔 등이다. 이것들로 와인이 어느 등급인지 예측하는 것이다.

원본 데이터는 이곳(http://neuroph.sourceforge.net/tutorials/wines1/download/original.txt)에 있고, 0~1 사이의 입력으로 표준화시킨 값도 이곳(http://neuroph.sourceforge.net/tutorials/wines1/download/NormalizedDataSet.txt)에 있다. 나는 0~1 사이의 표준화시킨 값을 사용했다.

우측 상단에서 입력층, 은닉층, 출력층 노드와 각 노드 간의 연결 가중치(weight)를 확인할 수 있는데, 가중치가 양수이면 파란색, 음수이면 붉은색을 띠도록 했다. 가중치에 따라 어느 정도 선의 굵기가 달라진다. 가중치에 대한 내용은 이 글에서 다루지 않았으므로 궁금하신 분은 다른 참고 서적을 보는 것이 좋을 것 같다.



사실 이런 문제들은 너무 유명하고 MATLAB이나 R을 이용하면 금방 풀 수 있지만, 직접 코드를 짜서 돌려봤다는 것에 의의를 두려고 한다. 이전에는 개념적으로만 알고 있던 신경망 알고리즘에 대한 이해가 조금 깊어진 것 같다.

이상 매우 긴 글을 마친다. 원래 여러 번에 나눠서 쓰려고 했지만, 쓰다보니 끝내야 할 것 같아서... 부득이하게 한 번에 쓰게 되었다.


참고 링크
--------
- 자바로 구현된 신경망 프레임워크이다. 사용하기 쉬운 데이터들이 많이 나와 있다. 프로그램을 돌리는 방법과 여러 번 다르게 실험했을 떄의 비교도 친절하게 설명하고 있어서 여러 모로 참고하기 좋은 사이트이다.

2. Machine Learning 강의 요약 : http://sanghyukchun.github.io/42/
- Machine Learning의 세계적인 권위자 Andrew Ng 교수의 강의 요약본. 한국어라 가뭄의 단비 같았다. 요약도 매우 잘 되어 있다. 



덧글

  • 엄마쟤또먹어 2017/08/10 18:15 # 삭제 답글

    안녕하세요~ 설명 정말 잘봤습니다. 그런데 프로그램 링크 눌러보면 플래쉬(일본) 제작 프로그램으로 들어가지는데 이게 맞는건가요?? 저도 그림에서와 같이 한번 해보고 싶은데 사용방법좀 알려주실 수 있을까요~?
  • 기획자 2017/08/11 16:26 #

    안녕하세요. 원래 프로그램을 호스팅해주던 사이트가 서비스 종료되어서, 그 링크로 이용하실 수가 없습니다. 그래서 안되는 줄 알았는데, 누군가 그 사이트의 프로그램을 다 옮겨놓았네요.
    http://fl.corge.net/user/greentec/
    이 링크에서 확인해보실 수 있습니다. 저도 시간날 때마다 하나씩 제 개인 홈페이지로 옮겨놔야겠네요. 댓글 달아주신 덕분에 찾았습니다. 감사합니다.
  • 엄마쟤또먹어 2017/08/17 15:10 # 삭제 답글

    감사합니다~^^
댓글 입력 영역

애드센스