딥러닝의 헬로 월드 예제라고 할 수 있는 MNIST 데이터를 CNN 으로 분석하는 방법에 대하여 알아보는 글을 작성해 보고자 합니다. 이 글은 딥러닝이 무엇인지 기본적인 내용을 알고 있는 분을 대상으로 작성하였으므로 딥러닝이란 무엇이며, 텐서플로란 무엇이며, 케라스는 또 무엇인지에 대한 내용을 생략하도록 하고 바로 시작하겠습니다.


[이 CNN 이 아닙니다...]

 1. 데이터 전처리

 MNIST 데이터는 케라스를 이용할 경우 매우 간단히 불러 올 수 있습니다. 


 불러온 이미지 데이터를 X 라 하고 0 ~ 9 까지 붙인 이름표를 Y 라고 명명하도록 하겠습니다. 데이터를 불러와 보면 70,000 개의 데이터가 있습니다. 케라스에서는 이미 70,000개의 데이터 중 불러온 데이터 중 60,000개를 학습 데이터로, 그리고 나머지 10,000개를 테스트 데이터로 사용하도록 설정 되어 있습니다. 


 각각의 데이터는 28 x 28  이미지로 총 784개의 속성을 가지고 있는 2차원 배열 입니다. 학습을 위해 데이터를 784개의 1차원 배열로 바꿔주어야 합니다.


 이 글을 읽으시는 분들은 이미 아시겠지만, MNIST 의 각각의 데이터는 0 ~ 255 사이의 값으로 이뤄진 흑백의 손글씨 이미지 입니다. 0 ~ 255 사이의 값을 그대로 사용해도 되지만 모델의 성능을 위해 0 ~ 1 사이의 값으로 변환 하는 과정을 거치면 좋습니다. 이처럼 데이터의 분산이 클 때 분산의 정도를 바꿔주는 과정을 데이터 정규화 (Normalization) 이라고 합니다. 1차원 배열로의 변환 및 정규화 과정을 학습 데이터와 테스트 데이터 모두에 적용 합니다.


 

 MNIST 데이터를 이용하여 우리가 궁극적으로 하고자 하는 바는 0 ~ 255 사이의 값으로 이뤄진 원본 데이터를 보고, 이 데이터가 0 ~ 9 사이의 숫자 중 어떤 것인지 예측하는 것 입니다. 딥러닝의 분류 문제로 이를 위해서는 원-핫 인코딩 방식을 적용 해야 합니다. 즉, 0 ~ 9까지의 정수 값을 갖는 형태가 아닌 0 이나 1로 이뤄진 벡터로 수정해야 합니다. 만약에 '3' 이라는 숫자라면 3을 [0, 0, 1, 0, 0, 0, 0, 0, 0] 로 바꿔주어야 한다는 것 입니다. 원-핫 인코딩 변환을 위해 케라스의 np_utils 의 to_categorical() 함수를 사용 합니다.


 2. 일반적인 딥러닝 모델링

 데이터 전처리가 끝나면 이제 데이터 모델링을 해보겠습니다. 성능의 비교를 위해 CNN 으로 바로 들어가기에 앞서 일반적인 딥러닝 모델을 먼저 살펴 보겠습니다. 케라스를 사용해 프레임을 만들어 줍니다.


입력 값은 784 개, 은닉층은 512개의 노드가 있으며 출력은 10개인 모델로 은늑층과 출력층의 활성함수는 각각 relu 와 softmax 를 사용하였습니다. 분류 문제 이므로 오차 함수는 categorical_crossentropy, 최적화 함수는 adam 을 사용하겠습니다. 


모델을 실행 할 때, 최적화 단계에서 일정 횟수 이상 반복해도 모델의 성과 향상이 없을 경우 모델을 중단하도록 설정해 주는 것이 좋습니다. 여담으로 저 같은 경우 처음 딥러닝 강의를 들을 때 부팅 되는 것도 힘겨워하던 제 구형 노트북에서 모델을 돌린 적이 있는데 종종 자기 전에 모델 돌려두고 자고 일어나서 출근 하기 전까지 돌아가고 있는 모습을 자주 보곤 했었습니다. 그런데 오히려 오차가 증가하거나 의미 없이 돌아가고 있는 것이였다면 눈에서 습기가...


마지막으로 데이터를 200개씩 각각 30번 실행하게끔 설정하고, 테스트 데이터를 최종 모델의 성과 측정에 사용할 수 있도록 합니다.



 1개의 은닉층을 가지는 기본 딥러닝 모델에 대한 결과를 그래프로 출력해 보면 위와 같은 모습을 볼 수 있습니다. 10번째 epoch 일 때 최적의 결과가 나오고, 이후 10번 더, 즉 20번째 실행까지 시도했을 때 오차(loss)가 더 줄어들지 않자 종료가 되었습니다. 테스트 데이터와 달리 학습 데이터의 오차는 계속해서 줄어들고 있는 것으로 볼 때 과적합(overfitting) 이 일어나기 전에 학습이 무사히 끝난 것으로 보입니다.


 이정도만 해도 훌륭한 정확도를 보입니다. 하지만 이러한 기본 모델에 추가적인 층을 더하고, 옵션을 더한다면 더 좋은 성능을 얻을 수 있습니다. 이제 다 된 딥러닝 모델에 컨볼루션을 뿌려 보겠습다.


 3. CNN

 3.1. Convolution

 CNN (Convolutional Neural Network) 는 입력된 이미지에서 다시 한번 특징들을 추출하는 마스크(혹은 필터, 혹은 윈도, 혹은 커널) 를 추가하는 방법 입니다. 



 그림으로 이해하면 조금 쉽습니다. x  라는 원본 이미지에 h 라는 마스크를 준비 합니다. h 라는 마스크의 각 칸에는 가중치가 드러 있습니다. 그림에서 h(-1, -1) ~ h(1, 1) 이 각각의 가중치 입니다. 이 가중치들은 원본 이미지 x 에 원래 있던 값과 곱해져서 새로 추출된 값이 나옵니다.


 즉, h(-1, -1)*x(m-1, n-1) + .... + h(0, 0)*x(m, n) + ...... + h(1, 1)*x(m+1, n+1) = y(m, n) 이라는 새로운 값이 나오고, 이렇게 나온 값들이 모인 새로운 y 층을 우리는 컨볼루션(합성곱) 이라고 부릅니다. 이러한 마스크를 여러 개 만들 경우 여러 개의 컨볼루션이 나오게 되겠죠.


 케라스를 사용하면 손쉽게 컨볼루션 층을 추가할 수 있습니다. Conv2D 를 사용하면 되는데 파라미터로 대개 마스크의 갯수, 마스크(커널) 사이즈 그리고 입력 되는 값을 전달해야 합니다. MNIST 의 경우 28 x 28 의 흑백의 이미지 이므로 (28, 28, 1) 을 전달 합니다. 마지막으로 해당 층의 활성 함수를 정의 합니다. 이러한 방식으로 컨볼루션 층을 2개 추가해 보겠습니다.



 3.2. Max pooling

 컨볼루션 층을 추가하는 이유는 마스크(커널) 을 이용하여 이미지의 특징을 잘 추출하기 위해서 입니다. 하지만 컨볼루션 층만 추가한다고 해서 이미지의 특징이 바로 도출되기는 어렵고, 여전히 크고 복잡한 경우 풀링(pooling) 혹은 서브 샘플링 (sub sampling) 과정을 한번 더 거쳐 축소하는 과정을 거칩니다. 
 이러한 풀링에는 여러가지 방법이 있으나 대개 많이 사용되는 것이 맥스 풀링(max pooling) 입니다. 맥스 풀링은 정해진 구역 안에서 가장 큰 값만 다음 층으로 넘기고 나머지는 과감하게 버리는 방법 입니다. 이번에도 그림으로 살펴 보겠습니다.



 그림과 같이 원본 이미지를 네개의 구역으로 나누고, 2 x 2 의 맥스 풀링을 적용하면 각각의 구역에서 가장 큰 값인 20, 30, 112, 37을 가지고 새로운 층을 만들어 낼 수 있습니다. 맥스 풀링도 케라스를 사용할 경우 간단하게 모델에 추가할 수 있습니다.


 

 3.3. Drop out 과 Flatten

 컨볼루션 층을 추가하고 맥스 풀링 층을 추가하여 특징을 잘 추출한다고 해서, 무조건 많은 노드와 많은 층을 추가하는 것이 좋은 결과를 보장하지 않습니다. 오히려 과적합에 빠져 제대로된 성능을 얻지 못하는 경우가 생기게 될 가능성이 높아 집니다. 과적합을 피하는 방법과 원칙이 여러 가지가 개발되고 연구되어 왔는데 지금 소개하는 방법 인 드롭 아웃(Drop out) 기법이 자주 사용되는 기법 입니다. 
 드롭 아웃은 간단 합니다. 은닉층에 있는 여러개의 노드 중에서 일부를 사용하지 않는 것 입니다. 학습이 진행 될 때 마다 랜덤하게 은닉층의 노드 몇개를 끔으로써 학습 데이터에 지나치게 과적합 되는 것을 방지할 수 있는 기법 입니다. 케라스 에서 드롭 아웃을 적용 할때 몇 % 의 노드를 랜덤하게 사용하지 않을지를 파라미터로 정하여 아래와 같이 코드를 작성 할 수 있습니다.


 앞서 컨볼루션을 사용하지 않는 기본 모델링에서는 28 x 28 의 이미지를 바로 1차원 배열로 변경하여 학습하였는데, 컨볼루션을 적용할 때는 2차원 배열인채로 다루고 있습니다. 이를 1차원으로 바꿔주는 함수가 Flatten 입니다.


 컨볼루션, 맥스 풀링, 드롭 아웃과 플랫튼까지 적용하고 나면 최종적인 CNN 의 딥러닝 모델링의 모습은 아래와 같다고 볼 수 있을 것 같습니다.



[input] ----> [convolution | relu] ----> [convolution | relu] ----> [max pooling] ----> [drop out] ----> [flatten] ---> [hidden layer | relu] ---> [drop out] ---> [output | softmax]


optimizer = adam



 최종적인 모델링을 실행 시킨 결과는 아래와 같습니다. 최종 결과는 99.28% 였습니다. 데이터 안에 사실상 사람의 눈으로도 구분하기 어려운 글씨들도 있다는 것을 감안했을 때 CNN 으로 거의 대부분의 글씨를 맞출 수 있다는 것을 볼 수 있었습니다.




 

딥러닝이 요즘 뜨고 있다고 해서 

한번 해보고 싶은데 어디서 시작해야 될지 모르시는 분들을 위한 

유명 유료 강의 전격 비교!!

  


  저는 얼마 전 유다시티(Udacity) 의 Deep Learning Nanodgree Foundation 강의를 수료하고, 현재 코세라(Coursera) 에서 신규로 개설된 Deep Learning Specialization 강의 중 첫 번째 서브 카테고리 강의 수강을 완료 했습니다. 




 그렇다고 이제 전문가가 된 것은 아닙니다. 전문가는 커녕 여전히 슈퍼 왕 초보 입니다. 여전히 아는 것은 하나도 없고, 겨우 딥러닝 관련 용어들이 무엇인지 그리고 이제 뭘 공부해야 될지 어렴풋이 보이기 시작한 단계에 서 있는 것 같습니다. 


 저 같이 딥러닝 쪽에 관심은 있으나 어디서 어떻게 시작해야 될지 모르시는 분들은 이 글에서 소개하는 두 강의 중 더 마음에 드시는 것 하나를 선택하셔서 시작하시길 추천 드립니다. 두 강의 모두 저렴한 강의들은 아닙니다. 직장인인 제 입장에서도 선뜻 결제하기엔 망설여 지는 금액이였습니다. 사이트 결제 창에 카드 번호를 한땀 한땀 입력하면서 정말 많은 고민을 했었습니다. 차라리 이 돈으로 낡은 제 노트북을 크고 우람한 데스크탑으로 바꾸는게 낫지 않을까 하는 고민부터 시작해서, 과연 내가 결제 해놓고 강의를 다 끝낼수 있을까 하는 생각까지 오만가지 생각을 하였었습니다.



 그래도 결제 완료 후 강의를 들었을 때 돈이 아깝다는 생각은 들지 않았습니다. 비록 강의를 다 듣고 난 지금도 여전히 초보자이고, 모르는 것 투성이지만 이제 혼자서 뭘 어떻게 공부할 수 있겠다는 생각을 할 수 있게 되었습니다. 그리고 정말 간단한 문제에 대해서는 저 나름대로의 모델링을 해 볼 수 있게 되었습니다. 그런 의미에서 두 강의 모두 비록 유료 강의지만 제 값을 하는 유료 강의라고 생각 합니다.


  


1. 강의 소개


 우선 각각 강의 소개를 해보겠습니다. Udacity Deep Learning Nanodgree Foundation (이하 DLNDF) 는 유다 시티에서 제공하는 인공지능 관련 나노디그리 프로그램을 듣기 위한 기초 강의 입니다. 


DLNDF 링크


 유다 시티의 나노 디그리는 해외에서 어느 정도는 인정 받는 수료증이라고 보시면 될 것 같습니다. 유다 시티는 다양한 나노 디그리 프로그램을 제공하는데, 인공 지능 관련 분야로는 Robotics, Self Driving Car 그리고 Artificial Intelligence  이렇게 세 프로그램을 운영하고 있습니다. DLNDF 는 이 세 프로그램을 듣기 전에 듣는 강좌로 DLNDF 를 수료한 사람은 Robotics, Self Driving Car, AI 나노디그리 프로그램을 등록할 때 우선 등록권 부여 등 일부 혜택을 제공하고 있습니다.



 저 같은 경우 3월에 개설된 반을 신청해서 들었습니다. 아무 때나 등록해서 들을 수 있는 것은 아니고, 2~3 개월 간격으로 신청을 받고 있습니다. 유다시티 사이트에서 Waiting list 에 메일을 등록해 두면 강좌가 오픈할 때 메일을 받을 수 있으니 그때 신청하셔서 들으시면 됩니다.


 Coursera 의 Deep Learning Specialization (이하 DLS) 프로그램은 아무 때나 등록은 가능 하나 강의 시작일이 따로 정해져 있습니다. 코세라의 Specialization 도 어느 정도 인정 받는 수료증 입니다. Nanodgree 든 Specialization 이든 수료증을 목표로 할 정도로 대단한 수료증은 아닙니다만, 그래도 링크드인이나 이력서에 한 줄 써 넣을수 있는 정도는 된다고 생각 합니다. 


DLS 링크


 지난 8월에 처음으로 오픈한 강의이자, 코세라의 설립자이면서 바이두의 인공지능 수장이였다가 지금은 Deeplearing.ai 를 운영하고 있는 Andrew Ng 이 직접 강의하는 강좌 입니다. 


총 5개의 서브 강의로 이뤄져 있으며, 원한다면 모든 강의를 선택하지 않고 각각 한 강의씩 선택해서 들을수도 있습니다. 수료증도 각 서브 강의 별로 받을 수 있습니다. 



2. 강사

 

 코세라의 DLS 는 Andrew Ng 이 직접 강의를 진행 합니다. 그에 반해 유다시티의 DLNDF 은 메인 강사 1명과 딥러닝 및 데이터 사이언스 관련 유명 유투버인 Siraji Raval 가 강의를 진행하고 주차 별로 딥러닝 분야의 유명인들이 나와 강좌를 진행해 줍니다. 특히 GAN 강의의 경우 Ian Goodfellow 가 직접 나와 강의를 진행하기도 합니다. (캐스팅 클라스 ㄷㄷㄷ)  




 결론적으로 코세라의 DLS 와 유다시티의 DLNDF 모두 매우 훌륭한 수준급 강사가 강의를 진행하고 있다고 보시면 될 것 같습니다. 굳이 단점을 각각 찾는다면 DLS 를 진행하는 Andrew Ng 교수님의 경우 강의를 진행하실 때 목소리가 좀 작다는 점, 그리고 DLNDF 의 경우 강사가 여러 명이다 보니 뭔가 통일성이 없는 듯한 느낌을 들 수 있겠습니다. 사실, 둘 다 별 단점 같지도 않은 단점 입니다. 



3. 금액

아무리 대단한 강의라도 유료 강의라면 금액을 신경쓰지 않을 수 없습니다.  


유다시티의 DLNDF 의 경우 전 프로모션 이벤트 기간에 등록하여 원금 $800 을 할인 받아 $599 를 강의료로 결제하였습니다. 프로모션 이벤트가 매번 강좌 오픈할 때 마다 하는 것은 아니나 유다시티에서 종종 할인 이벤트를 하니 Waiting list 에 등록해 두시고 강의가 오픈할 때마다 강의료가 얼마인지 지켜보시는 것도 좋을 것 같습니다.

 

 유다시티의 경우 약 600 ~ 800 달러 정도를 한번 결제하고 나면 끝 입니다. 추가 결제 금액도 없고 수료증 발급을 위한 별도 금액도 없습니다. 결제를 완료하고 나면 AWS 크레딧을 약 100 달러 정도 주어 AWS 환경에서 딥러닝을 돌려 볼 수 있게 해줍니다.


 코세라의 DLS 는 결제 방식이 유다시티와 약간 다릅니다. 매달 $49 씩 결제하는 방식 입니다. 커리큘럼에 대해서도 설명 드리겠지만 DLS 는 크게 5개의 서브 강의들로 이뤄져 있고 각 강의 당 약 3 ~ 5 주 정도 걸린다고 강의 설명에 명시되어 있습니다. 따라서 약 5개월 정도 걸린다고 하면 총 250 불 정도 된다고 보시면 됩니다.


 재미있는 것은 5개의 서브 강의들을 순서대로 듣는 것이 아니라 동시에 들을 수도 있습니다. 따라서 만약에 첫 달에 5개 강의를 모두 동시에 시작해서 한 달만에 모두 듣는다면 50 불만 내고 끝낼수도 있습니다. 하지만 그렇게 한달 만에 끝낼 수 있는 분이시라면 굳이 강의를 안 들으셔도 될 것 같습니다.... 



4. 커리큘럼

유다시티의 DLNDF 는 아나콘다 설치, 쥬피터 노트북 설치와 같은 환경 설정부터 시작해서 Neural Network --> CNN --> RNN --> GAN 순서로 강의가 진행 됩니다. 기초부터 시작해서 자연스럽게 난이도가 올라가서 갑자기 엇 이게 뭐지!? 하면서 당황하게 되진 않습니다. 물론 그렇다고 쉽게 쉽게 강의가 진행되는 것은 아닙니다. 어렵습니다. 하지만 강사들이 나름 자세하게 설명하고 최대한 많은 학습 도구와 자료들을 제공하고 있어 차근 차근 따라가다 보면 못 따라갈 부분도 없습니다.




첫 번째 주제인 NN 까지는 python 과 numpy 만을 사용해서 모델링을 하고 과제를 진행하고, 두 번째 주제인 CNN 부터는 본격적으로 tensorflow 를 사용하고 AWS 환경에서 GPU 를 사용해서 학습시키는 법 등 실용적인 부분을 다루게 됩니다. 


과제는 총 5개의 과제가 나오고 모든 과제를 제출해야 수료증이 나오게 됩니다. 과제별로 데드 라인이 있기는 하지만 전체 강좌가 끝나는 시점 전에만 과제를 제출하면 모두 제출로 인정 해 줍니다. 늦게 제출했다고 점수가 깍이거나 하는 부분도 없습니다.


유다시티 강좌의 장점으로 과제에 대한 리뷰를 말하지 않을 수 없을 것 같습니다. 총 5개의 과제에 대해서 매번 사람이 직접 과제에 대한 리뷰를 해줍니다. 리뷰는 비싼 강의료를 지불한 만큼 매우 자세하게 해줍니다. 파라미터로 어떤 값을 사용하라는 것부터 어떤 함수를 사용하는 것이 더 좋다는 식이나 어떻게 모델링을 변경하면 좋을지 등 라인 바이 라인으로 매우 자세하게 봐주어 도움이 많이 되었습니다.


모든 강의를 마치는데는 약 6개월 정도 소요 됩니다.


개인적인 어려움으로 저는 파이썬을 전혀 다뤄보지 않은채 강의를 시작해서 처음에 애를 좀 먹었습니다. 선형 대수학이나 미분, 확률 통계와 같이 수학적인 부분에 대해서는 강의 내에서 필요한 부분을 집어서 설명해 주기 때문에 어느 정도 따라 갈 수 있었으나 오히려 프로그래밍 적인 부분에서 파이썬을 한번도 안다뤄보고 시작하니 처음에 꽤 허둥 댔었습니다. 그렇다고 파이쎤을 엄청 잘해야 강의를 따라갈 수 있는 것은 또 아닙니다. 강의 들으시긴 전 얇은 책 한권 눈으로 쓱 훝어보시거나 유투브의 파이썬 관련 영상 몇 가지 보시고 시작하시면 좋을 것 같습니다.


코세라의 DLS 도 유사한 커리큘럼을 가지고 있습니다. 크게 보면 Neural Network --> CNN --> RNN 의 순서로 진행되며, Neural Network 자체의 실용적인 부분에 좀 더 집중한 커리큘럼으로 이뤄져 있습니다. DLS 의 경우 좀 더 수학적인 부분을 유다 시티에 비해 자세히 다룬다는 느낌을 받았습니다. 물론 유다시티 강의에서도 수학적인 부분을 다루기는 하나 구현적인 부분에 좀 더 치중한 반면, DLS 는 수학 계산식이 Neural Network 의 각 레이어를 지날 때 마다 어떻게 변하고 업데이트 되는지 하나 하나 따라가면서 이론적인 부분을 좀 더 탄탄하게 해주는 느낌을 받았습니다.


DLS 도 유다시티 강의와 마찮가지로 python 과 tensorflow 를 사용해 과제를 진행 합니다. 매주 1개의 이론 퀴즈와 1 ~ 2개의 프로그래밍 과제가 있습니다. 과제들의 데드 라인이 있으나 각각의 서브 과제 일정이 종료되기 전에만 내면 제출 완료로 인정해 줍니다.



두 강의 모두 과제 제출 일자에 대해서 꽤나 관대 합니다.



5. 강의 방식

코세라의 DLS 의 과제를 진행하는데 제 로컬 PC 에 별도로 설치하거나 세팅해줘야 하는 것은 없습니다. 강좌 서버의 Jupyter notebook 을 열람하여 해당 노트북에서 직접 코드 수정 하고 실행하여 결과를 확인하기 때문에 뭔가 따로 설치해야 하는 수고를 덜 수 있습니다.


위에서 언급했다 싶이 DLS 강의는 수학적인 공식을 기본으로 이론을 설명 합니다. 각 모델들이 수학적인 수식으로 어떻게 표현되어야 하는지에 대해서 매우 꼼꼼하게 설명해 줍니다. 물론, 꼼꼼하게 설명해 준다고 해서 제가 모두 이해 했다는 말은 아닙니다. 


강의는 수식이나 이론적인 측면에서 설명하는데 비해 과제는 꽤나 실용적인 면으로 접근 합니다. 실제 딥러닝 현장에서 사용되는 방법을 최대한 반영해서 프로그램을 구성했다고 합니다. 과제의 경우 노트북 상에 비어진 코드를 채워 넣는 방식 인데, 노트북 상에 힌트들을 엄청 많이 적어 두었습니다. '꼭 너가 이 과제를 너의 힘으로 풀기를 바란다'는 무언의 메시지가 담겨 있는 듯한 느낌을 받을 정도로 친절하게 힌트들을 이곳 저곳에 두었습니다. 이게 장점일 수도 있지만 어설프게 이해 한 다음에 과제를 접했을 때 내가 이해한 것을 바탕으로 푸는 것이 아니라 힌트에 맞추어 과제를 하게 되어 오히려 마이너스 요인이 되기도 했습니다.


유다시티의 강의 방식은 수학적인 요소 보다는 구현 쪽에 좀 더 포커스를 맞춘 느낌이였습니다. 퀴즈의 경우 이론 퀴즈 보다는 코드 구현 퀴즈가 대부분이였고, 강의 별 Jupyter notebook 을 가지고 하니씩 구현해 가면서 이론을 설명해 주었습니다.


DLNDF 는 코세라의 DLS 와 다르게 로컬 PC 에 개발 환경을 셋업해 주어야 강의를 진행하고 과제를 제출 할 수 있었습니다. 강의 가장 초반에 어떻게 환경 셋업을 해줘야 하는지 스텝 바이 스텝으로 가이드 해주어 초보자인 저도 쉽게 셋업할 수 있었습니다. 


코세라의 DLS 는 칠판에 판서를 하듯 필기 위주의 강의가 진행되는데 반해 유다시티의 DLNDF 는 그림 위주로 설명이 진행 됩니다. 그리고 동영상 강의로만 이뤄지지 않고 중간 중간 읽을 거리를 제공 해 주어 이론에 대해서 좀 더 자세하게 설명해 주었습니다. 


DLNDF 의 과제도 코세라의 DLS 와 마찮가지로 꽤나 실용적인 주제의 과제들로 구성 되었습니다. 하지만 GAN 과제인 얼굴 생성 과제의 경우 GAN 을 통해 생성된 얼굴의 퀄리티가 매우 낮았고, 그닥 실용적인 주제라기 보단 연구적인 주제로 보여 개인적으로 좀 아쉬웠습니다.


전체적으로 강의 방식은 두 강좌가 매우 달랐습니다. 어느 쪽이 더 좋은지에 대해 평가하지는 못하겠지만 개인적으로 재미있기는 유다시티 강의가, 이해하기 편한데에는 코세라의 강의가 더 좋았던 것 같습니다.

 


6. 난이도

전 딥러닝 주제 자체가 쉽지 않은 주제라고 생각 합니다. 그래서 강의 자체의 난이도는 상 중 하로 보았을 때 최소 중은 된다고 봅니다. 그리고 아무래도 영어의 제약이 없을 수가 없습니다. 아쉽게도 두 강의 모두 한국어 자막을 지원하지 않고, 강의 컨텐츠가 모두 영어 입니다. 한국말로 배워도 어려운데 영어로 하라니! 


그나마 다행인 것은 두 강의 모두 영문 스크립트를 지원한다는 점과 강의 속도를 조절할 수 있다는 점 입니다. 그래도 여전히 어렵습니다. 그래서 저는 김성훈 교수님의 모두를 위한 딥러닝을 강좌와 병행해서 들어 많은 도움이 되었습니다. 이런 훌륭한 한국말 강의를 무료로 만들어 주시다니ㅠㅠ 충성충성충성


모두를 위한 딥러닝 유투브 링크 


강의 난이도는 둘 다 쉽지 않지만 과제 난이도는 좀 다릅니다. 물론 제가 아직 코세라의 DLS 는 5개의 큰 주제 중 1개만 끝냈기에 단정지어 말할 수는 없으나 확실히 과제 난이도는 유다시티가 좀 더 높습니다. DLS 의 경우 어떻게 짜라는 가이드 라인 뿐만 아니라 힌트까지 쥬피터 노트북에 써져 있어 과제 내용에 비해 난이도는 상대적으로 낮은 편 입니다.



7. 기타

마지막으로 각각 강의에서 제가 생각하는 상대적 장점을 찾아보겠습니다.


우선 유다시티 DLNDF 는 슬랙 커뮤니티가 매우 활발하게 운영되고 있습니다. 한국인 학습자를 위한 채널도 있고, 강의를 듣는 분들끼리 서로 스터디도 하고 모르는 부분을 물어보고 답변도 잘해주며, 운영진들도 신속하게 질문에 답변을 달아주는 편 입니다. 


코세라와 유다시티 모두 모바일 앱이 있긴 한데, 전 코세라 앱이 상대적으로 강의 듣기에는 좀 더 좋았습니다. 코세라는 앱만 가지고 강의를 끝마칠 수 있도록 구성 되어 있는데 반해 유다시티 앱은 완성도가 상대적으로 떨어지는 느낌이였습니다.


이상 위의 내용을 아래와 같이 표로 정리해 보았습니다.  모쪼록 두 유료 강의에 대해서 관심이 있으셨던 분들에게 조금이나마 도움이 되었으면 좋겠습니다. :-) 감사합니다!

 

 DLNLDF

DLS

 강사

Udacity 프로그램 담당 강사 +

Siraji, Andrew Trask, Ian Goodfellow 등 초대 강사 

Andrew Ng 교수

 금액

 $600 ~ $800

매달 $49

 커리큘럼

 6개월

(NN -> CNN -> RNN -> GAN)

 약 5개월

(NN -> CNN -> RNN)

 강의방식

 구현 위주

수학 위주

 난이도

강의 난이도 중 

과제 난이도 상

강의 난이도 중

과제 난이도 중 

 기타

커뮤니티 우수

모바일 앱 (상대적) 우수



  

신경망 (Neural Networks)


우리 인간의 뇌는 무수히 많은 뉴런(neuron) 이라는 신경 세포로 구성되어 있고, 뉴런들은 시냅스를 통해 전기적, 화학적 신호를 서로 주고 받으면서 정보를 저장하는 기능을 수행 한다고 합니다. 뉴런들이 서로 복잡하고 얽혀 주고 받는 신호를 통해 우리 인간은 생각을 하고 감정을 느끼기도 하며 무엇인가를 배우기도 합니다.


머신러닝 기법 중 하나인 신경망, 혹은 인공 신경망은 이러한 뇌의 신경망을 본 떠 만든 알고리즘 중 하나 입니다. 신경망의 경우 요즘 많은 관심을 받고 있는 딥러닝의 기초가되는 알고리즘이기도 합니다.



Perceptron


인공 신경망을 구성하는 가장 기초적인 단위는 퍼셉트론(Perceptron) 입니다. 퍼셉트론은 위의 그림과 같이 1개 이상의 input 값과 bias 값 그리고 활성 함수(activation function) 와 1개의 output 값으로 구성되어 있습니다. 퍼셉트론의 input 들은 각각 weight 값들과 곱해져 활성 함수로 전달 되게 되며, 활성함수의 결과 값으로 output 값을 가지게 됩니다. 


활성화 함수의 종류는 매우 다양합니다. 구성하고자 하는 네트워크의 목적에 따라 Logistic 함수, trigonometric, Softmax ReLU, Sigmoid, Step 함수 등 다양한 함수들을 사용 할 수 있습니다. 활성화 함수를 거쳐 구해진 Output 은 이미 labeling 이 되어진 데이터와 비교하여, 비교된 결과에 따라 weight 값을 업데이트 시켜 주어야 합니다. 


이러한 과정을 무수히 반복하다 보면 Output 과 실제 값과의 차이는 점점 작아질 것이고 어느 정도 정해진 횟수 혹은 error 율에 이르게 되면 이 과정을 종료하면 됩니다. 인공 신경망에서의 학습 이라는 개념은 이러한 weight 값 업데이트 과정이라고 보시면 됩니다. 


인공 신경망을 만들기 위해서는 퍼셉트론으로 이뤄진 레이어를 한층, 한층 추가해 주면 됩니다. 인공 신경망은 기본적으로 입력을 받는 입력 계층 (Input layer) 와 출력 값을 보여주는 출력 계층 (Output layer) 를 가집니다. 그리고 입력 계층과 출력 계층 사이의 모든 계층들은 은닉 계층 (Hidden layer) 로 불립니다. 해당 계층으로 입력되는 값과 출력 되는 값이 직접적으로 보여지지 않기 때문에 은닉 계층이라 칭하고 있습니다.




SciKit-Learn


이번 글의 예제를 직접 돌려보기 위해서는 0.18 버전 이상의 SciKit-Learn 을 설치하여야 합니다. pip 이나 conda 통해서 쉽게 설치할 수 있으며, 관련 내용은 구글을 통해서 쉽게 검색하실 수 있을 것 같습니다. 개인적으로 머신러닝이나 딥러닝을 공부 할때는 conda 를 이용해서 virtual env 를 셋업하시는 것이 정신 건강에 이롭다고 생각 합니다.  Anaconda 다운로드 및 사용법에 대해서는 아래의 링크를 참조하시면 될 것 같습니다.


Anaconda 다운로드 https://www.continuum.io/downloads


How to install Machine Learning Package Using Anaconda



Data


실습을 위한 데이터는 UCI Repository 에서 제공하는 Wine 데이터 를 사용하도록 하겠습니다. 다운로드

이 데이터는 와인이 가지고 있는 13가지 화학 성분에 대한 정보를 가지고 있습니다. 데이터 상의 와인은 모두 이탈리아 한 지역에서 생산된 와인이며, 3종류의 각기 다른 품종으로 구분 됩니다. 


그럼, 인공 신경망을 이용해서 다운로드 받은 데이터를 학습해서, 데이터 상의 화학 성분만을 가지고 어떤 품종인지 예측하는 모델을 만들어보도록 하겠습니다. 



위와 같이 pandas 를 사용하여 데이터를 읽어 드립니다. 앞에서 부터 5개의 데이터의 결과가 아래와 같이 나오면 데이터를 잘 읽어 들인 것 입니다. 인공 신경망을 통해 우리가 알고 싶은 결과는 첫 번째 행인 Cultivator 입니다. Alchol ~ Proline 까지의 데이터가 입력으로 들어 왔을 때, Cultivator(품종) 이 1 인지, 2인지 아니면 3인지 예측하는 모델을 만드는 것 입니다.


  Cultivator  Alchol  Malic_Acid   Ash  Alcalinity_of_Ash  Magnesium  ... (이하 생략)

0           1   14.23        1.71  2.43               15.6        127   

1           1   13.20        1.78  2.14               11.2        100   

2           1   13.16        2.36  2.67               18.6        101   

3           1   14.37        1.95  2.50               16.8        113   

4           1   13.24        2.59  2.87               21.0        118 



데이터에 대한 정보를 좀 더 확인해 보겠습니다. 아래와 같이 wine 데이터의 shape 을 출력해 보면, 178 개의 데이터와 14개의 속성 값을 가지는 것을 확인할 수 있습니다.



(178, 14)



그럼 이제 입력 값과 출력 값을 정의 해 보도록 하겠습니다. 입력 값은 Cultivator 를 제외한 13개의 속성 값들의 집합 입니다. 즉, 위의 178 개의 데이터 중 Cultivator 행을 뺀 나머지 부분이라고 보시면 됩니다. 출력 값은 Cultivator 행만 있는 178 개의 데이터 입니다. 



입력 값 X 와 출력 값 Y 를 정하고 나면 178개의 데이터를 학습 데이터와 검증 데이터로 구분해 줍니다. 학습 데이터는 학습을 위해서만 사용되며, 검증 데이터는 학습된 결과가 제대로 학습 되었는지 확인하기 위해 사용 됩니다.



Data Processing


인공 신경망의 경우 데이터 값들을 정규화 해주지 않을 시, 아무리 학습을 해도 원하는 값을 얻기 어려울 수 있습니다. 신경망 특성 상 스케일링 (scaling) 에 매우 민감하게 반응 합니다. 따라서 학습 데이터와 검증 데이터 모두 데이터에 알맞게 정규화 해 주어야 합니다. 정규화 하는 방법은 여러가지가 있지만 이번 예제에는 sckit learn 에서 제공하는 API 를 이용해 보도록 하겠습니다.



 

위와 같이 학습 데이터를 기준으로 데이터의 전 처리까지 완료 하고 나면 학습을 진행할 수 있습니다.



Training the model


scikit-learn 은 학습을 위한 다양한 API 들을 제공하고 있습니다. 인공 신경망의 자세한 이론적 지식이 없더라도 API 호출 만으로도 학습 모델을 손쉽게 구성할 수 있습니다. 물론, 그렇다고 하더라도 이론적 지식이 없어도 된다는 이야기는 아닙니다. 아무리 많은 기능을 라이브러리가 제공한다고 하더라도 언제 어떻게 쓸 줄 모른다면 소용이 없겠죠.




학습을 위해 1개의 입력 계층과 3개의 은닉 계층, 그리고 1개의 출력 계층으로 이뤄진 인공 신경망을 구성해 보도록 하겠습니다. 각각의 은긱 계층은 30개의 퍼셉트론으로 이뤄지도록 정의 하였고, 정의된 신경망에 학습 데이터의 인풋 X (x_train) 과 출력 Y (y_train) 을 파라미터로 넘겨주면 학습 모델 구성이 완료 됩니다.


MLPClassifier(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9,
       beta_2=0.999, early_stopping=False, epsilon=1e-08,
       hidden_layer_sizes=(30, 30, 30), learning_rate='constant',
       learning_rate_init=0.001, max_iter=200, momentum=0.9,
       nesterovs_momentum=True, power_t=0.5, random_state=None,
       shuffle=True, solver='adam', tol=0.0001, validation_fraction=0.1,
       verbose=False, warm_start=False)


지금은 단순히 모델의 계층만을 구성하였지만 실제로 모델을 객체를 생성할 때 정의 할 수 있는 파라미터들은 위와 같이 매우 많습니다. 파라미터들을 직접 정의해서 바꿔보시거나 계층 수를 늘리거나 줄이거나 혹은 퍼셉트론의 수를 변경해 보시면서 다양한 방식으로 학습을 구성해 보시면 좋을 것 같습니다.



Prediction and Evalutaion



드디어 대망의 마지막 단계 입니다. 학습이 완료된 모델이 얼마나 정확하게 예측하는지 평가해 보도록 하겠습니다.



테스트를 위해 분리해둔 x_train 데이터를 predict 함수의 파라미터로 단순히 넘겨주는 것 만으로 값을 예측해 볼 수 있습니다. 그리고 예측 결과 값인 preditctions 와 x_train 의 실제 값인 y_train 의 결과를 비교해서 얼마나 맞췄는지 평가함으로써 우리가 구축한 모델의 성능을 평가해 볼 수 있습니다.


평가와 관련된 confusion_matrix 와 classification_report 의 결과 값을 한번 보도록 합시다.


               precision    recall  f1-score   support

          0       1.00      0.94      0.97        53
          1       0.97      1.00      0.98        90

avg / total       0.98      0.98      0.98       143


리포트를 보면 위와 같이 약 98%의 정확도를 보이는 모델임을 알 수 있습니다. 이정도면 꽤 훌륭한 모델이라고 할 수 있습니다!
기본적으로 인공 신경망이 어떤 식으로 구성 되어 있는지 그리고 어떤 식으로 동작하는지에 대해서 알아 보았습니다. scikit learn 외에도 tensorflow, PyTorch, Keras 등 다양한 인공 신경망과 딥 러닝을 위한 라이브러리 / 프레임워크 들이 존재 합니다. 하나씩 사용해보고 상황에 자신의 스타일에 가장 잘 맞는 것을 선택하여 공부해 보면 좋을 것 같습니다. :-)



본 글은 아래의 원문을 일부 수정 및 번역 하였습니다.
원문 : www.kdnuggets.com/2016/10/beginners-guide-neural-networks-python-scikit-learn.html/


    서포트 벡터 머신 (Support Vector Machine, SVM)


서포트 벡터 머신은 Linear Classification, 즉 선형 분류 중 하나 입니다. 위의 그림과 같이 별모양과 동그라미가 있을 때 두 도형을 나누는 가장 좋은 boundary 를 찾아야 한다고 할 때 사용되는 머신 러닝 기법 중 하나 입니다. 그림 처럼 2차원일 경우 이 boundary 를 선으로 표현할 수 있지만 더 고차원으로 가게 될 경우 단순히 선형이라 표현하지 않고 hyperplane 이라 부르게 됩니다.


서포트 벡터 머신을 알기 위해서 중요한 기본 개념으로 3가지와 이에 따르는 몇가지 서브 개념들이 있습니다.

1. Margin ( VC Dimension, Shattering, Dichotomy )

2. Support Vector

3. Kernel

그럼 각각이 무엇인지 이론적으로 먼저 살펴보도록 하겠습니다. 


  • Margin - VC Dimension, Shattering, Dichotomy

안드로이드 개발자 분들이라면 margin 에 대해서 많이 보셨을 것 같습니다. 안드로이드를 하다보면 UI 를 그릴 때 각 View 간의 거리를 정할 때 margin 값을 주곤 합니다. 서포트 벡터 머신에서의 margin 도 사실상 동일한 개념 입니다. 위의 예제 그림에서 Class1 과 Class2 를 나누기 위한 선은 무수히 많이 그릴 수 있습니다. 그런데 어떤 선을 가장 잘 분류한 선이라고 표현할 수 있을 까요?

두 클래스 사이을 분류하는 무수히 많은 선, 고차원에서는 hyperplane, 중 margin 을 가장 크게 하는 hyperplane 을 찾는 것이 서포트 벡터 머신 분류를 잘 표현한 것이라고 할 수 있습니다.  

사실 직관적으로 생각해 보면 당연히 분류되는 아이템들 과의 margin 이 가장 큰 hyperplane 을 찾는 것이 가장 잘 분류하는 방법일 것 같긴 합니다. 그런데 왜 그럴까요?

이를 증명하는 개념 중 하나가 VC Dimension 입니다. VC Dimension 은 데이터를 분류하는 SVM 분류기가 얼마나 복잡한 데이터를 분류할 수 있는지를 나타내는 속성 입니다. 

그럼 이제 VC Dimension 을 좀 더 설명하기 위해 Dichotomy 란 개념을 추가적으로 설명해 보겠습니다. Dichotomy 란 어떤 집합이 있다면 이 집합을 둘로 나눈 다는 것 입니다. 예를 들어 A, B, C 라는 점이 있다면 { A }, { B, C} 혹은 { A, B, C}, { } 등으로 총 8 종류로 나누는 것이 가능 할 것 입니다. 이처럼 8 종류로 나누는 것을 Dichotomy 라고 부릅니다. 

그럼 Shattering 은 무엇일까요? 

Shattering 은 SVM 분류기가 Dichotomy 를 모두 표현할 수 있느냐 입니다. 위의 그림 중 마지막 그림을 보시면 + 와 - 를 나누는 선 하나를 표현할 수 있는 방법은 없습니다. 해당 경우의 Dichotomy 는 표현할 수 없는 것 입니다.


결론적으로 VC Dimension, 즉 SVM 분류기가 얼마나 복잡한 데이터를 표현할 수 있느냐의 여부는 Shattering 할 수 있는 가장 많은 데이터의 갯수라고 보실 수 있을 것 같습니다. 


일반적으로 N 차원의 hyperplane 의 VC Dimension 은 N+1 이라고 합니다. 또한 VC Dimension 이 높으면 안 좋다고 합니다. 그리고 Margin 을 최대화 한다는 말의 동치는 VC Dimension 을 줄인다는 말과 동일하다고 합니다.


이상 이론적인 부분에서의 SVM 의 Margin 에 관련된 부분들을 살펴 보았습니다. 다음 글에서 그럼 어떻게 Maximum Margin 을 찾을 수 있을지에 대해서 살펴보도록 하겠습니다.


머신러닝에 대해 공부하다 보면 학습 데이터를 어떤 식으로 구할지 고민하게 됩니다. 인터넷에 이미 많은 데이터 저장소들이 있고 오픈된 데이터들이 많으나 첫 시작점으로 삼을 만한 아주 기초적이고 심플한 데이터를 찾기 오히려 어렵다고 느껴지기도 합니다.


이럴 땐 그냥 만드는 것도 좋은 방법이 될수 있습니다. :)


아래는 소득(income), 부동산(real_estate), 가족수(family) 에 따라 슈퍼리치 인지 그냥 부자인지 중산층인지 가난한 사람인지 판별하기 위한 1000개 짜리 학습 데이터를 만들기 위한 코드 입니다.


값의 신뢰성을 위해 random 값의 범위와 최소 기본 값을 더해주어 각 타입별, 컬럼별 값을 생성하고 이를 종합하여 파일에 써주는 간단한 형태입니다. 간단한 형태의 데이터가 필요한 분들이 사용하시면 좋을 것 같습니다.



2017/03/09 - [CS/ML] - ML101 : 나이브 베이즈 (Naive Bayes) : 베이즈 정리



이전 글에서 알아본 베이즈 정리에 이어, 나이브 베이즈 분류에 대해서 알아보도록 하겠습니다. 아래 그림은 필기체 숫자를 인식하는 나이브 베이즈 분류기의 예제 입니다. 8 x 8 의 행렬이 있고, 해당 행렬에는 총 64개의 feature 값들이 있습니다. 각 feature 의 색이 칠해져 있는 상태에 따라서 숫자를 판별합니다.



예를들어, 3 이라는 숫자의 경우 3행 1열에 색이 칠해져 있을 확률이 매우 낮을 것입니다. 반면에 5행 5열에 색이 칠해져 있다면 3일 숫자의 확률은 매우 높을 것 입니다. 이러한 조건에 대한 확률을 표현한 표를 Conditional Probability Table 이라 하며 위 그림의 오른쪽 표들 입니다. 그리고 각 클래스별 확률을 나타낸 테이블을 Priority Table 혹은 Class Table 이라 부르며 P(Y) 로 정의된 왼쪽 표 입니다. 


P(F3, 1 = on | Y) 는 1 ~ 0 까지 가질 수 있는 결과 값의 Class 들일 경우에 색이 칠해져 있을 확률 입니다. 다시 말해 숫자 3일 경우 F3, 1 에 색이 칠해져 있을 확률은 0.05, 숫자 6일 경우 0.9 라고 할 수 있습니다.


그렇다면 8 x 8 의 숫자가 그려져 있는 어떤 그림이 주어졌을 때 해당 그림의 숫자가 무엇인지 어떻게 판별할 수 있을까요? 지난 글에서 다루었던 베이즈 정리를 바탕으로 이 문제를 풀어보도록 하겠습니다. F0,0 ~ F15,15 총 64개의 CPT 가 주어졌을 때 Class 들의 확률을 구하는 식은 아래와 같습니다.



주어진 Class table 과 CPT 들의 곱을 이용하여 입력으로 들어오는 그림의 상태에 따라 어떠한 숫자인지 값을 구할 수 있고 가장 확률이 높은 Class 값에 맞게 해당 숫자를 예측할 수 있습니다. 


본래의 식은 분모로 P(F) 를 가지는 것이 맞으나 위 문제의 경우  모든 클래스에 대해서 동일한 분모를 가지기 때문에 어떤 클래스 값이 가장 높은지 비율만 구하는 문제에서는 분자의 크기만 아는 것으로 충분하기에 이를 생략할 수 있습니다.



※ 라플라스 스무딩 (Laplace Smoothing)

위의 방법의 경우 인풋 값이 우리가 생각하는 일반적인 모양의 숫자가 들어왔다고 했을 때는 잘 동작할 수 있지만 학습 데이터에 없던 값이 들어오거나 이상 값이 들어올 경우 확률이 0이 되는 값이 나와 정상적으로 분류가 안되는 경우가 있습니다.


이럴 경우 값의 보정을 위해 사용되는 기법이 라플라스 스무딩 기법 입니다. 라플라스 스무딩은 실제로 관찰한 것보다 한번씩 더 봤다고 가정 하는 것 입니다. 즉 확률이 0일 경우를 제외시키는 방법으로 일반적으로 아래의 식과 같이 표현 합니다.





  • Bayes rule

일반인이 암 환자를 진단하는 신규 검사법을 사용하여 검사해본 결과가 양성 반응일 때, 실제로 암에 걸렸을 확률을 구하는 문제가 있다고 해보겠습니다. 이 문제를 풀기 위해 주어진 조건과 조건부 확률을 다음과 같다고 가정하겠습니다.


Y -> 실제 병에 걸렸을 경우 { 1 : true, 0 : false }


X -> 검사 결과 경우 { 1 : 양성, 0 : 음성 }


P ( X = 1 | Y = 1 ) = 0.8 검사의 정확도로 실제 병에 걸렸을 경우, 검사 결과도  양성일 확률

즉, 본 검사는 80% 의 확률로 정확한 진단을 내리고 20% 확률로 실제 병이 걸린 환자에 대해 음성이라는 오진을 내리게 됩니다.


P ( X = 1 | Y = 0) = 0.1 일명 False positive 로 병이 없는데도 불구하고 검사 결과가 양성으로 나올 확률.


P ( Y = 1) = 0.004 일반적으로 암에 걸릴 확률.  



조건을 확인하고 문제를 다시 읽어보도록 하겠습니다. 위와 같은 조건이 주어 졌을 때 암 검진 결과가 양성 일 경우, ( X = 1) 실제로 암에 걸렸을 확률 ( Y = 1) 이므로 우리가 구해야할 문제는 아래와 같습니다.



이 문제는 베이즈 정리를 이용해 풀 수 있습니다. 베이즈 정리의 기본 공식은 다음과 같습니다.



공식으로 확인해 봐도 알겠지만 베이즈 정리는 본래 역확률 (inverse problem) 을 해결하기 위해 사용되는 방법 입니다. P(B|A) 라는 조건부 확률을 알고 있을 때 P(A|B) 를 구하는 방법인 것 입니다. 하지만 공식처럼 단순히 역확률 문제에만 사용되는 것이 아니라 이전 경험을 바탕으로 확률을 추론하는데 사용할 수 있는 방법 이기도 합니다. 주어진 자료를 이용해 새로운 사실의 확률을 구하는 방법, 다시 말해 머신러닝에 사용되기 매우 좋은 방법 입니다. 


앞의 문제는 암 검진 결과가 양성일 때 실제 암에 걸렸을 확률을 구하라는 것이었습니다. 주어진 조건을 공식에 맞추어 문제를 풀어도록 하겠습니다.



머신 러닝의 관점에서 베이즈 정리를 다룰 때 몇가지 알아야할 용어도 있습니다. 위 조건에서 P(Y) 는 암에 걸릴 확률 입니다. 어떠한 자료도 없을 때 특정 사건이 일어날 확률에 대한 가정으로 사전 확률(Prior Probability) 이란 용어가 있습니다. 그리고 가능도(likelihood) 라는 용어도 있습니다. 사건이 일어났다는 가정 하에서 새로이 가지게 된 자료가 관측될 확률을 의미 합니다. 베이즈 정리의 분모는 가능도를 구할때 조건으로 걸린 사건의 확률입니다. 마지막으로 위 문제에서 답에 해당 하는 부분, 사전확률과 가능도를 이용해 구한 답을 사후 확률(posterior probability) 라고 합니다.


사실 위의 문제의 경우 사건의 종류가 단 2개 뿐인 매우 간단한 문제 였습니다. 일반적인 문제나 실제 머신 러닝 적용을 위한 문제에서는 사건의 경우는 2개 이상을 것 입니다. n개의 사건을 가지는 일반적인 베이즈 정리는 다음과 같습니다.


표본 공간 는 서로소인 의 합집합이며

는 위에서 정의된 사건 일때



아래의 그림과 함께 공식을 보시면 더 이해하기 쉬우실 것 같습니다. P(A1|B) 를 구하고 싶다면 조건부 확률의 공식에 따라 분자는 P(A1∩B) 를, 분모는 P(B) 를 가지게 됩니다. 곱셈정리에 따라 분자와 분모는 각각 위의 공식과 같이 변환 되는 것 입니다.

 






2017/02/15 - [CS/ML] - ML 101 : weka practical exercise / 의사결정트리 (1)



 Weka 를 이용해 소스 코드를 생성하고 난 후 해당 코드를 살펴보면, Visualize 를 통해 살펴본 의사 결정 트리의 모양을 그대로 코드로 옮겨 왔음을 확인 하실 수 있습니다. 메소드 명이 임의의 문자로 만들어져 있어 읽기 어려우나, 메소드 내용으로 보았을 때, 최상위 root 부터 leaf 로의 if-else 의 집합임을 확인할 수 있습니다. 그럼 이 코드를 어떻게 활용해 볼 수 있을까요?


우선, 지난 글에서 다운 받으신 .arff 파일의 내용을 아래와 같이 바꾸어 줍니다. 

@data

end_rack,85,85,FALSE,?

end_rack,80,90,TRUE,?

cd_spec,83,86,FALSE,?

std_rack,70,96,FALSE,?

std_rack,68,80,FALSE,?

std_rack,65,70,TRUE,?

cd_spec,64,65,TRUE,?

end_rack,72,95,FALSE,?

end_rack,69,70,FALSE,?

std_rack,75,80,FALSE,?

end_rack,75,70,TRUE,?

cd_spec,72,90,TRUE,?

cd_spec,81,75,FALSE,?

std_rack,71,91,TRUE,?


이 테스트 데이터를 읽어와 분류기가 값에 맞게 분류하는지 알아 보도록 하겠습니다. 테스트 코드는 다음과 같습니다.

테스트 파일을 읽어들이고 인스턴스를 로딩하여 for 루프를 순환하며 classifyInstance() 메서드를 사용하여 값을 얻어 옵니다.



이번 경우에는 classifyInstance() 를 이용하여 실제 매출이 발생했는지 안 했는지를 확인할 수 있는 것 입니다. double 형을 반환된 결과 값은 attribute 의 인덱스를 상징 합니다. 즉, 첫번째 인덱스인 0 은 'yes' 이고 두번째 인덱스인 1 은 'no' 를 가르키게 됩니다.


실행한 결과 값을 확인해 보면,


0.0->yes

0.0->yes

1.0->no

1.0->no

1.0->no

0.0->yes

0.0->yes

0.0->yes

0.0->yes

1.0->no

0.0->yes

1.0->no

0.0->yes

0.0->yes 


와 같이 테스트 데이터를 보고 우리가 학습시킨 모델을 통해 매출 발생 여부를 확인할 수 있게 되었습니다. 이제 테스트 데이터만 형식에 맞게 확보 된다면 매장의 배치 모습만 보고도 매출이 발생할지 안할지를 예측할 수 있게 된 것입니다. :) 



2017/01/16 - [CS/ML] - ML 101 : 머신러닝의 종류

2017/01/19 - [CS/ML] - ML 101 : weka install & arff

2017/01/29 - [CS/ML] - ML 101 : try weka

2017/02/07 - [CS/ML] - ML 101 : 머신러닝 무료 강의 모음



이번 글에서는 음반 매장 내에 위치에 따라 아이돌 그룹 레드벨벳의 CD 판매량을 의사결정트리로 예측할 수 있는 모델을 만들어보도록 하겠습니다. 아래의 훈련용 데이터는 음반 위치, 매대가 눈높이에 있는지 여부, 그리고 실제 구매 여부로 이뤄져 있습니다. 


데이터 분석 작업은 다음의 단계로 이뤄집니다.


1. 훈련용 데이터를 불러와 의사결정 트리를 만들고 해당 내용을 그래프로 확인 한 후,

2. 의사 결정 트리 분류기로 자바 코드를 생성하고,

3. 테스트용 데이터로 자바 코드를 시험함.


우선 아래의 훈련용 데이터를 다운 받으시고, 내용을 확인해 보도록 하겠습니다.

훈련용 데이터

redvelvet.arff


훈련 데이터의 속성은 5가지 입니다. Placement - 음반이 진열된 위치, Prominence - 진열된 음반 중 레드벨벳 CD 비중, Pricing - 판매가격이 정가 대비 할인된 비율, Eye Level - 고객의 눈높이 진열 여부, Customer Purchase - 구매 여부. 이 속성들 중 판매량에 가장 영향을 미치는 속성이 무엇인지 알아 보고 속성 값을 바탕으로 판매량을 예측해 보도록 하겠습니다.

웨카에서 훈련용 데이터를 불러오고, 의사결정 트리를 사용하기 위해 J48 알고리즘을 선택하고 분석을 하게 되면 아래의 결과를 얻을 수 있습니다.


결과를 보면 판매에 가장 큰 영향을 미치는 속성은 placement 입니다. end_rack 에 두었을 때 판매 매출을 높이는데 가장 좋은 값이라고 할 수 있고, cd_rack 에 두었을 때는 가격 요인에 의해 판매 여부가 결정된다고 할 수 있습니다. 마지막으로 std_rack 에 두었을 때는 눈높이에 제품이 있느냐의 여부에 따라 판매 여부가 결정된다고 해석 할 수 있습니다. 


이 내용을 시각화하여 볼 수 있습니다. [Result list (right-click for options) 패널에 있는 알고리즘을 우 클릭하여 Visualize Tree 옵션을 선택하면 아래의 그림을 확인 하실 수 있습니다. 


시각화 뿐만 아니라 분석된 내용을 소스 코드로 확인할 수 있습니다. 웨카를 이용해 생성한 알고리즘 기반의 코드 재사용 및 수정이 가능 한 것 입니다. 아래의 그림과 같이 More Options 버튼을 선택하고 Output source code 를 체크한 후 [start] 버튼을 눌러 다시 한번 웨카 분석을 수행 합니다.



분석이 완료 되면 코드가 별도의 파일로 나오지는 않고 classifier output 화면에 기존 결과 분석 내용과 함께 출력 되게 됩니다. 생성된 코드를 빌드 하기 위해서는 [weka.jar] 가 필요 합니다. 해당 파일은 Weka 를 설치한 폴더에 가시면 있습니다. Eclipse 에 프로젝트를 하나 생성하고 WekaClassifier.java 를 만들어 출력된 내용을 복사 해줍니다. 그리고 Referenced Libraries 에 weka.jar 를 첨부하여 빌드를 수행하시면 됩니다.


소스 코드를 자세히 보시면 WekaClassifier 안에 WekaWrapper 클래스와 실행부인 main 이 같이 존재 하는 것을 보실 수 있습니다. 저는 코드 보기 편하기 위해 WekaClassifier 와 WekaWrapper 를 분리하였습니다. 꼭 그럴 필요는 없지만 Claasifier 에 생성된 함수명을 살펴보시면 랜덤한 이름으로 생성되어 있어 가독성이 많이 떨어집니다. 이에 추후 작업 및 코드 정리를 위해 분리해서 작업하시는 것을 추천 드립니다.


(계속..)

머신러닝을 공부하기 좋은 [무료] 강의들





1) https://www.youtube.com/user/hunkims 
홍콩 과학 기술 대학교 교수님으로 계신 김성훈 교수님의 Youtube 채널 입니다. 머신 러닝 강좌 중 세계에서 가장 유명한 강의를 뽑으라면 Andrew Ng 교수님의 코세라 강의를 들 수 있겠는데요, 해당 강의 같은 경우 실습시 상대적으로 생소한 Octa 나 매트랩을 사용해야 한다는 단점이 있습니다. 요즘 핫한 tensorflow 를 이용해 실습을 하실 수 있고 무엇보다 아름다운 우리 한글을 사용한 강의기에 입문 강의로 강추 드립니다.



2) https://www.coursera.org/learn/machine-learning 
역사와 전통을 자랑하는 머신러닝 입문 강의의 세계 최고봉!! Andrew Ng 교수의 머신러닝 강좌 입니다. 매달 수강 신청을 하실 수 있고 진도에 뒤쳐지지 않도록 관리 해주고 있기 때문에 저와 같은 의지박약 인들도 꾸역꾸역 진도를 따라갈 수 있습니다. 한글 자막도 있으니 영어에 대한 걱정은 접어 두셔도 괜찮을 것 같습니다.



3) https://www.youtube.com/playlist?list=PLWO_EXTnt3sPmlgCeHAiHwaAFwmmusGp6 
머신러닝에 대한 주제라고 하기에는 애매하지만 파이썬에 익숙하신 분 중 데이터 분석에 관심이 있으신 분은 한번쯤 보시면 좋을 강의 리스트 입니다. 파이썬을 이용해 데이터 분석 하는 법에 대해 차근차근 가르쳐 주고 있고, 역시 한글 강의라는 강점이 있습니다. 강좌 하나하나 모두 길지 않아 하루 하나씩 부담 없이 보실 수 있으실 것 같습니다.



4) https://www.youtube.com/playlist?list=PLNfg4W25Tapy5hIBmFZgT5coii1HUX6BD 
동국대학교 홍정모 교수님의 유투브 채널의 플레이 리스트, C++ 로 배우는 딥러닝 입니다. 파이썬과 R 로 꽉 채워져 있는 머신러닝 강의 세계에 한줄기 단비 같은 C++ 강좌 입니다. 사실 랭귀지가 중요한 것이 아니라 이론에 대한 이해가 더 중요하다고들 하나, 내가 가장 잘 아는 언어로 배우는 이론이 더 쉽게 이해 가는 것도 사실이라고 생각합니다. 



5) https://www.youtube.com/channel/UCRyIQSBvSybbaNY_JCyg_vA 
모두의 연구소 이찬우 연구원님의 딥러닝 입문 강의 입니다. 화려한 영상이나 멋진 강의 슬라이드 대신 노트에 필기하면서 강의가 진행되는 영상들로 이루어진 플레이 리스트 입니다. 영상을 보고 있자면 마치 고등학교 때 공부 잘하는 짝꿍이 옆에서 설명해 주는 듯한 느낌이 들기도 합니다. 아날로그적 감성을 좋아하시는 분께 추천 드립니다.



6) https://www.youtube.com/playlist?list=PLzWH6Ydh35ggD2XoOObYqiYByOt8r_wuv 
서울대학교 BI Lab. 겨울방학 Rookie 세미나로 진행된 강좌 목록 플레이 리스트 입니다. 실제 세미나 장면을 녹화한 영상들로 캠퍼스 느낌을 느끼고 싶으신 분들에게 추천 드립니다. 제가 강의를 다 본 것은 아니지만, 난 머신러닝에 대해 1도 모른다! 라는 분들 보다는 대애애충 뭔지 한번 들어봤는데? 라는 느낌을 가지고 계신 분들에게 좋은 강의로 보입니다.



7) https://www.youtube.com/channel/UCWN3xxRkmTPmbKwht9FuE5A 
Sirajology 라는 유투브 채널로 매우 유명한 유부터 중 한분인 Siraj 가 다양한 주제로 짧지만 알찬 비디오들을 공유하고 있는 곳 입니다. 이 채널의 가장 큰 장점은 짧지만 고퀄의 영상미가 느껴지는 영상들 입니다. “40줄의 코드로 애플 주가 예측하기!” 와 같이 toy 예제들을 만드는 법들에 대해서 매우 재미있게 가르쳐 줍니다. 영어 강의지만 영상도 재미나 흥미롭게 보실 수 있을 것 같습니다.

이분 같은 경우 최근 유다시티와 함께 딥러닝 컨텐츠를 제작하고 있습니다.



8) https://www.youtube.com/playlist?list=PLAwxTw4SYaPkQXg8TkVdIvYv4HfLG7SiH 
마지막으로 추천해 드릴 강의는 유다 시티의 머신러닝 입문 강좌 입니다. 강좌 수는 400개가 넘지만 영상 하나당 3분 이내이기에 내가 진도를 잘 나가고 있구나! 하는 착각에 빠지기 쉬운 강좌 입니다. 안타깝게도 한글 자막은 없습니다만 퀄리티로는 최고라고 생각합니다. 매우 매우 강추하는 강좌입니다.



이외에도 입문 강좌는 유투브나 유다시티, 코세라와 혹은 kmooc 과 같은 Mooc 사이트에서 많이 찾아보실 수 있습니다. :-D