데이터분석/Deep Learning

텐서플로우 입문기 (3) - 인공신경망을 이용해서 펜글씨 예측

늘근이 2016. 12. 24. 21:31

MNIST데이터를 가지고, 실제 인공신경망을 돌려볼수 있다. 

이 데이터는 아래와 같이 여러 숫자들을 손글씨로 쓴것들을 모아놓은 데이터인데, 5000개의 데이터가 존재하며 이는 모두 레이블링 되어있으므로 실제로 학습결과를 판단하기에 용이하다.



다만, 실제로 저런 손글씨중에는 우리가 알아보기 힘든 손글씨도 존재하긴 하다. 3의 첫번째 글자는 저게 3인지 8인지 구분하기가 상당히 어렵고, 8의 열네번째 경우도 8이라고 보기 힘든 글씨체나 다름이 없다. 기계한테 독심술까지 강요할수는 없다.


따라서 약 90퍼센트의 확률만 때려맞춰 줘도 평타는 치는 경우라고 할수 있겠다.



텐서플로우에서 제공하는 이러한 숫자필기 이미지들을 가지고 하면 되는데 이는 다음과 같이 간단한 코드로 가져오기가 가능하다.



이제 가져온 이미지를 텐서에 넣어놓고 가지고 놀면 된다.


깃허브에 올려져 있는 오픈소스이므로, 주석질만 해서 다시 가져다 놓는다.




 실제로 어떤 시스템이나 무언가를 배울때, 주석질이나 아니면 그 코드를 다른방식으로 써보는게 도움이 많이 된다고 한다.


선형회귀분석을 떠올려본다. 선형회귀분석이란 말그대로 선형, 직선을 좍 그어서 방정식을 구할수 있는 경우 이를 이용한 분석방법을 말한다. 보통의 방정식은


 y = a * x + b


와 같은 형식을 띄는데, 고등학교를 졸업한지가 상당한 시간이 되었으므로 아래와 같이 좀더 간지나게 써볼수있다.


y = W * x + b


b는 편향(bias)라는 멋진말로 불러주고 W는 가중치(Weight) 라는 멋진말로 불러주자. 

다만 우리는 선형방정식 하나가 아니라 신경망 하나하나가 저러한 방정식을 내포하고 있는 인공신경망을 통해서 훈련을 시키게 된다. 즉, x가 여러개가 들어올수 있다는 것이며 이에 각각의 가중치가 적용될수가 있다는 말이다. 


펜글씨 하나의 이미지를 생각해보자. 고정된 이미지의 크기가 100 * 100이라면, 그리고 훈련으로 주는 몇천개의 이미지가 다 이 형식을 띄고있고 제법 중앙에 잘 정리되서 몰려있다면 우리는 100 * 100 개의 픽셀을 검사해서 각각의 픽셀에 대해 각각 저러한 멋진 방정식을 적용해볼수가 있다. 


이를 아래와 같이 쓸수 있다. 


z = b + 시그마 xiWi




즉,  xi 에서 i는 총 픽셀을 말한다. 즉, 100 * 100이면 만개가 튀어나올것이고 이는 컴퓨터는 냅다 계산해버리는 소수의 양이다. 물론, 이러한 이미지가 5000개 있으면 100 * 100 * 5000이므로, 아 암산이 안되네.. 하여튼 많다. 중요한건 사실 이 계산은 대규모 병렬처리로 빠르게 끝내버릴수도 있다는것. 그래서 보통은 오버워치나 하려고 사둔 그래픽카드가 드디어 인류역사에 발전적인 방향으로 쓰이게 된다.


어쨌든, 방정식을 통해 튀어나는  z은 하나의 규격으로 통일되어야 한다. 지금 이 상태로는 십만이 나오고 일억이 나오고 통제가 안되기 때문에 0~1 사이의 숫자를 가지게끔 해주어야 한다. 이는 시그모이드 함수를 이용하면 된다. 


만약 출력에서 두가지 이상의 클래스로 분류하고 싶으면 소프트맥스 함수를 활성화 함수로 사용하면 된다. 소프트맥스 함수는 예를들어 0~9 까지의 클래스가 존재한다고 치면 (여기서는 이렇다.)


0 - 1%

1 -  2%

...

8 - 90 %

9 - 1 %


합계 100%


이러한 식으로 결과를 튀어나오게 해준다. 이는 보통 두단계가 있는데 첫번째는 이미지가 어떤 레이블에 속하는지 근거( evidence ) 를 계싼하는과정, 두번째는 각 레이블에 대한 확률로 변환하는 것이다. 


픽셀에 대한 하나하나가 어떤 숫자에 속할 확률이 좌르륵 있으면 이 결과를 다 합산하든지 아니면 뭔가 계산을 통해서 최종적으로 제일 높은 확률의 숫자를 추정할수 있게 되고 그놈이라고 판단할수가 있다. 


이때 쓰는것이 소프트맥스 함수이며 소프트맥스 함수는 입력값을 모두 지수값으로 바꾸면서 조금더 가중치를 중요하게 만들어 준다. 


이러한 과정이 드러난것이 위의 코드이다. 


다만 추가된 것이 있다면  교차 엔트로피 비용함수와 경사하강법을 통해서 조금씩 모델을 향상시켜 나간다는 것이며, 이것이 바로 역전파 (백프로파게이션, backpropagation)알고리즘 이란것이다. 위의 코드에서는 학습속도 0.01을 따른다. 


위의 코드를 넣고 돌려보면 나의 경우는 0.91 ~ 0.92 사이의 예측정확도가 튀어나왔다. 이정도면 굉장히 쓸만하지않은가!


그냥 생각한건데, 일반적인 엑스레이나 다른 흑백사진같은 경우에도 특정부위에 문제가 생길수있는 부분만을 중앙을 잘맞춰서 학습시키면 병변을 골라내는 것에 있어서도 상당한 정확도로 예측이 가능하지 않겠능가!


다만, 주식예측이나 금융시장의 경우 이미지와 같은 데이터가 아니기때문에 사회학적으로 좀더 분석해야하기 때문에 쉽게 쓰일 수 없는 부분이 많은 것처럼 느껴진다.


이제 빵사러가야지