진화 연산은 여러면에서 매력적입니다. 공간에 대한 분포를 잘 모르고, 문제정의만 하면 왠만큼 해를 구할 수 있다는 것이야 말로 엄청난 매력이라 할 수 있죠. 복잡한 수학이 들어가 있지도 않고, 알고리즘만 이해할 수 있으면 누구나 쉽게 구현하고 접근할 수 있습니다. 이런 장점으로 많은 사랑을 받아왔죠.


그러나 이 부분이 진화 연산의 장점이면서 동시에 한계입니다. Evolutionary Strategies 나 기타 Covariance Matrix Adaptation 기법 등이 나왔지만, 여긴 수학의 영역에 약간의 진화연산의 Mutation 의 기법이 들어갔다고 보는게 맞을 것 같습니다. 또는 Mutation 이라는 것이 확률적이라 표현하는 확률의 기법이 들어갔다고도 볼 수 있겠네요. 거의 Random 에 가까운 속성으로 인하여, 해를 찾아도 왜 찾았을 까에 대해서 물음표가 생기고, 다시 한번 수행하더라도 꼭 그렇게 찾을 수 있다는 보장을 하기도 어렵습니다.


흡사, 문제 풀이를 로또와 같이 한다고 느끼는 사람도 있을 것 입니다. 아직은 주어진 해 공간에 대해 모두 시험해볼 수 없으니 이것을 대체하여 로또의 확률을 느끼는 것과 같이 대량의 시험을 해보는 그런 상황으로 비추어지기도 할 것이고, 언젠가 양자컴퓨터나 기타 더 강력한 컴퓨팅 환경이 주어졌을 때, 모든 경우의 수에 대해 시뮬레이션을 해보고 그 결과를 얻어내는 것과 진화 연산의 차이가 없어지는 날이 오겠죠.


이런 한계는 Genetic Programming 에서 더 심하게 나타납니다. 우리는 주어진 수식에 대해 파라미터를 계산하거나 신경망이나 기타 접근 방식을 통해 수식 자체를 근사화하여 모사하는 행위를 하지만, 이것은 값을 따라가도록 하는 어떤 방향성을 Loss-function 으로 정의하여 그 근거를 가지고 있습니다. 물론, Back-propagation 이 편미분이 연속적으로 연결되어 있는 chain-rule 이라는 것도 확인할 수 있습니다.


그러나 수식 자체를 Tree 형태로 표현한 것에 대해서 수식 자체가 갖는 공간적 표현을 수학적으로 모사하지 못합니다. (지금은 하고 있는데, 제가 모르고 있는 것일 수도... ) Tree 의 특정 위치를 교환하거나, 전혀 다른 Sub-tree 로 교체하여 수식을 풀어나간다고 하지만, 그 자체에 대해 어떤 수학적 근거를 갖는지에 대해서는 설명하기가 어렵습니다. 특히나 Fitness function 의 정의가 어떤 방향으로 유도한다고는 하지만, 이것이 항상 그 방향으로 유도되어 나아가는 것도 아니라는 것을 확인할 수 있습니다.


예전에 Tree 의 Distance Metric 을 정의한 여러가지 사례가 있었는데, 이 Distance Metric 은 비교적 Tree 의 차이에 대해 정의할 수 있었고, 이 Metric 을 통해서 특정 Tree 형태로 수렴할 수 있도록 Guidance 로 사용할 수 있었습니다. 문제는 Tree 의 구조적 형태가 좋은 해와 그렇지 않은 해를 구분하기에는 적절치 않았다는 것에 있었죠. 즉, 우리가 어떤 형태의 Tree 로 해를 유도한다고 해도, 사실 그 구조를 가진 해가 좋은 해인지를 판별할 방법이 없었습니다.


Genetic Programming 이나 Grammatical Evolution 은 진화 연산 중에서 Tree 구조를 사용하여 새로운 구조를 만들어나 갈 수 있다는 장점이 있지만, 반면 연속적인 시간 변화에 대한 값으로 주어진 결과물을 모사하기 위한 어떤 구조를 만들어낸다는 측면에서 2차원으로 주어진 데이터를 전혀 다른 공간의 형태로 Mapping 하는 일종의 Black-box Optimization 으로 생각하기에 아직은 수학적으로 접근할 수 있는 부분에 한계가 있는 것 같습니다.


언젠가는 연속적인 시계열 데이터나 기타 일련의 알고리즘을 Tree 나 다른 형태로 Mapping 하는 수학적 방법에 대한 제안이 있을지 모르겠습니다만, 이러한 부분이 극복되지 않는다면 결국 진화연산은 항상 랜덤에 의존하는 그런 최적화 방식으로 치부되지 않을까 싶습니다. Schema 이론이나 기타 몇가지 이론이 있지만, 그렇다 해도 말이죠.

예전에 tensorflow 를 처음 사용할 때, 리눅스 설치때문에 엄청나게 고생했었던 기억이 있다.


특히나 CUDA를 사용하는 부분에서, 노트북(GT 650M 사용)이 개발환경이다보니 일반적인 설치파일을 그냥 다운받는 것으로는 문제가 있어 많은 시간이 소모되었었는데,


얼마 전에 Ubuntu 16.04 버전으로 버전업하고, 그때의 과정을 되풀이 했는데, 너무나 쉽게 되었다.


1. Ubuntu 16.04 버전 설치


2. 그래픽카드 드라이버 설치

    sudo add-apt-repository ppa:graphics-drivers/ppa

    sudo apt-get install nvidia-370   

    설치 이후 재부팅하여, nvidia-settings 로 정상 설치 확인


3. CUDA 설치

    sudo apt-get install nvidia-cuda-toolkit

    example 이 필요하면, nvidia 사이트에서 다운


4. cuDNN 설치

    /usr/include, /usr/lib 에 설치함(기존에는 /usr/local/cuda ... 에 설치)

    CUDA v7.5 기준 v5 설치


5. anaconda2 설치

    https://www.continuum.io/downloads

 

6. tensorflow 설치 (설치시점에는 v0.11 사용함)

    http://tensorflow.org 참조


세상에... nouveau blacklist 따위도 필요 없고, 그냥 잘 된다.

진작 16.04 로 옮겨갈걸 그랬네...;;

예전에 처음 신경회로망을 배우고, 알고리즘으로 학습을 모사할 수 있다는 것에 대해서 상당한 매력을 느꼈었는데, 잘 정제되어 있는 학습데이터가 없이는 결과가 좋지 않았기에 그 이후로 크게 관심을 두고 있지는 않았었다. 한동안 그러다가 비전과 관련한 분야에 대해 공부하면서, 특징점을 추출하기 위한 부분을 신경망을 활용하여 드라마틱한 성능의 향상을 보여주는 것을 보고 다시 관심을 가지게 되었었다.

 

신경망에 대해 다시 관심을 갖기 시작했던 때에는 호기심에 한창 CUDA로 GA에서 실수최적화 기법을 사용하는 알고리즘들을 병렬화시키는 부분에 대한 개발하고 있었다. 그래서 처음에는 당연히 가중치 계산에 대해서 예전보다 더 큰 규모의 신경망을 보다 빠르게 학습시키는 것에 대해서만 생각하고 있었다. 

 

CUDA 를 처음 활용하면서, 그때 오류역전파 알고리즘을 구현하고, 10계층에 5천개 정도의 뉴런을 학습시키는 프로그램을 만들어 돌리면서, 진짜 빠르다는 생각은 하고 있었지만, 사실 제대로 최적화가 안되었었다. 아주 단순한 문제에 대해서 5천개의 뉴런을 학습한다는 게 가당키나 한 말인가? Learning Set이 5천개의 뉴런을 학습시킬 만큼 다양한 데이터 셋을 갖출리가 만무했고, 당연히 결과는 수렴 속도는 진짜 빠르네 였을 뿐이다. 물론, 그 당시에는 왜 안될까에 대해서 계속 의문이 있었을 뿐이었지만...

 

시간이 좀 지나고 나서, CNN 과 RNN 에 대해서 알게 되었다. 처음 CNN 이나 RNN 을 접했을 때에는 그 부분에 대해 정확히 이해하지 못하고, 단순히 더 계층화 되고, 다른 형태의 전달함수를 사용하지 했을것 같다는 정도로 생각했던게 문제 였다. 결론적으로 다시 하나씩 곱씹어보고 당연히 비전쪽에 잘 맞춰져 동작할 수 있겠구나 라는 생각이 들게 되었지만... 이 시점에 나는 학습데이터를 충분히 확보하지 못하는 시점에도 어느정도의 목표를 향해 결과를 보여줄 수 있는 특성이 있는 진화 신경망 쪽에 더 관심이 많았다.

 

회사에 오고나서는 신경망이나 진화연산과 같은 머신러닝 기법을 사용하기가 참 힘들었다. 가장 큰 장벽은 확률적. 그리고 언제나 동일한 해를 보장하지는 않는다는 점. 그런 부분을 이해시키는 것이 너무 말도 안되는 일이었다. 내가 일하는 곳이 산업용 로봇을 만드는 곳이니 당연한 것이기도 했다. 비교적 최근에 다시 고장예지나 다른 분야에 이러한 기법들을 사용할 수 있다는 것에 대해서 사람들이 인지하기 시작한건 참 다행이라 생각한다.

 

어쨌든, 신경망은 CNN과 RNN 이후로 눈부신 발전을 거듭하고 있고, 더 많은 연구자들과 함께 획기적인 결과물들이 쏟아져 나오고 있다. 놀랍고, 경이롭다. 언젠가는 내가 연구하는 여러가지 기법들 중, 나로 인하여 이러한 폭발적인 연구 성과를 보여줄 수 있기를 희망한다.

 

 

이책의 저자인 페드로 도밍고스는 기호주의자(Inverse Deduction), 연결주의자(Back-propgation), 진화주의자(Genetic Programming), 베이즈주의자(Bayesian Inference), 유추주의자(Support Vector Machine)로 머신러닝의 다섯 종족을 구분해두었다.

 

머신러닝의 기본서 같은 책이라 추천받아 봤는데, 세상에나... 난 진화연산을 머신러닝의 한 분파로 분류해줄 줄은 몰랐다.

 

진화연산을 공부하면서 항상 고민되던 부분이 어떻게하면, 진화의 부분을 학습과 같이 수행할 수 있도록 하는가에 대한 것이었다. 예를 들면 역전파 알고리즘은 항상 결과의 피드백으로 가중치의 값을 변경해나아가는데, 이 과정을 하나의 목표를 향한 학습이라 볼 수 있다.

 

그런데, 진화 연산에서의 선택은 많은 부분에 있어서 랜덤이다. 물론 진화연산을 이용한 수치최적화 부분에서의 일부 연산 방식의 경우, 결과값을 기반으로하여 점점 본래의 값을 변화시켜 나아가기 때문에 일종의 학습처럼 보일 수 있다. 그러나 유전프로그래밍의 연산자는 트리의 어떤 한 노드를 선택하여 하위 전체 노드를 변경하거나, 랜덤으로 특정 노드를 특정 트리나, 노드로 변경하는 방식이 대부분이다. 그렇기에 이를 학습이라보기는 항상 어렵다고 생각하고 있었는데, 이를 머신러닝의 한 분류로 넣어줄 줄은 몰랐다.

 

이 책에서도 물론 의문을 제기하고 있긴 하다. 여전히 유전프로그래밍이 문제를 해결하는 방식이 수많은 탐색공간을 뒤지는 탐색의 결과인지, 진화를 모델링한 것의 효과인지는 불분명 하지만... 이라는 단서를 달아서. 그리고 나 역시도, 이 부분에 대해서 공감은 하지만, 순수한 랜덤 탐색으로만 찾아낼 수 있는 결과에 비해 항상 더 우수한 결과를 보여줄 수 있는 것은 진화의 모델링에 의한 결과라고 생각한다.

 

아무튼 흥미로운 관점이고, 머신러닝의 다른 부분에 대해서도 다시 간단하게 살펴볼 수 있는 좋은 기회였다.

+ Recent posts