TigerCow.Door


안녕하세요. 문범우입니다.

이번포스팅에서는 Convolutional Neural Networks에 대해 알아보도록 하겠습니다.


* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.

관련한 상세 내용은 아래 링크를 참고해주세요.

https://hunkim.github.io/ml/



1. Convolutional Neural Networks


이번 포스팅에서 사용되는 슬라이드는 대부분 위의 사진에 나와 있는 주소에서 가져오게 되었습니다.




우리가 알아볼 Convolutional Neural Networks의 기본적인 개념은 고양이 실험에서 시작되었습니다.


고양이에게 어떤 이미지를 보여줬더니, 그림을 읽어들이는 뉴런들이 동시에 동작하는 것이 아니라, 특정 그림의 특정 부분에 대해서만 동작하는 것을 알게 되었습니다.


즉, 고양이가 이미지의 입력을 나누어서 받아 뉴런에서 나누어진 입력들을 처리하게 된 것이죠.


하나의 레이어씩 어떻게 처리되는지 조금 더 자세히 살펴보도록 하겠습니다.


위와 같이 32x32x3 형태의 이미지(또는 벡터)가 존재합니다.

이때 32x32는 크기라고 가정하고, 3은 이미지의 색상의 종류라고 생각해보겠습니다.

그리고 위에서 이야기했던 것과 같이 이미지에 대해 전체적으로 처리하는 것이 아니라, 아래와 같이 빨간색 부분과 같이 일부분을 처리합니다.


이러한 일부분을 우리는 filter라고 부르는데 이 필터의 형태는 우리가 정할 수 있습니다. 예외적으로 이미지의 대한 색의 종류, 3은 고정시키고 단순히 크기에 대한 형태만 우리가 지정할 수 있습니다.

그럼 이 필터는 전체 이미지의 5x5의 영역만 읽어들이게 됩니다.

그리고 그 영역을 읽어서 하나의 숫자를 뽑아내게 됩니다.

이것이 필터의 역할입니다.

근데 이것을 어떻게 하나의 값으로 만들어낼 수 있을까요?

그것은, 위의 사진에서 나온것과 같이 우리가 자주 사용하던 Wx+b 의 형태를 이용해서 하나의 값을 뽑아냅니다.

그리고 여기서 W는 우리가 어떤 영역에 대해서 하나의 숫자를 만들어내는데 사용되는 필터의 값이라고 생각하면 되겠습니다.

그리고 이렇게 결정된 W에 대해서 변하지 않도록 고정하고 전체의 이미지를 훑도록 합니다. 즉 아래와 같이 하나의 필터가 전체의 이미지를 스캔합니다.

위의 그림에서 빨간색, 파란색, 초록색 테두리를 가진 것과 같이 하나의 필터를 한칸 또는 그 이상씩 이동시키며 전체 이미지를 확인합니다.


그럼 위의 그림을 예시로 생각해보면 전체 9x9 의 형태에서 3x3 형태의 필터를 사용하는데 위와 같이 한칸씩 움직이면서 하나의 값을 뽑아내게 되면 뽑아낸 값들은 어떤 형태를 가지게 될까요?

결과값들은 7x7 형태를 가지게 될 것입니다.

이때 우리가 한칸씩 필터를 움직이게 됬는데, 이때 움직이는 크기를 stride라고 합니다. 즉, stride를 2로 설정해보면 아래와 같이 2칸씩 필터가 움직이면서 전체 이미지를 읽게됩니다.



그리고 위와 같이 stride를 2로 설정한다면, 전체 결과의 형태는 4x4 형태를 가지게 될 것입니다.


이를 전반적으로 살펴보면, 우리가 NxN형태의 이미지에서 FxF형태의 필터를 이용했을때 stride 설정하면 위와 같은 식으로 output size를 알아낼 수 있습니다.

그리고 위의 사진에서 stride 를 3으로 설정했을때와 같이 정수로 나누어 떨어지지 않을때는 그 필터의 형태나 stride를 사용할 수 없는 것 입니다.


그런데, 이렇게 사용하게 되면 기본 이미지보다 output 의 size가 작아지면서 어떤 정보가 사라지는 등의 문제가 발생할 수 있습니다.

이를 막기 위해서 우리가 사용하는 방법은 padding이라는 개념입니다.



위의 사진과 같이 기본이미지의 모서리에 0이라는 값으로 채워주는 것을 padding 이라고 합니다.

이렇게 하는 이유는, 이미지의 형태가 급격하게 작아지는 것을 막기 위한 이유와, 이미지의 모서리임을 알려주는 이유 두가지가 있습니다.


위의 사진에서 pad를 1 pixel로 설정하여 output size를 확인해보면 7x7 이 나오게 됩니다. 즉 입력 이미지와 출력 이미지의 size가 같게 됩니다.


지금까지 알아본 것이 기본적으로 하나의 Convolution layer를 만드는 방법입니다.


그리고 이러한 방법을 이용하여 위의 사진과 같이 여러개의 레이어를 만듭니다. 이때 새롭게 이용되는 filter는 이전의 filter와 W의 값이 다를 것 입니다.



그리고 이것을 한개, 두개의 레이어만 만들 것이 아니라 위와 같이 여러개의 레이어를 만듭니다. 그리고 각 레이어의 W값이 다르기 때문에 각 레이어의 값이 서로 다를 것입니다.

그리고 이렇게 만들어진 레이어들의 형태, (?, ?, ?)에서 마지막 세번째 값을 그 레이어의 숫자가 됩니다.


즉 여러개의 레이어를 만들면서 그 결과를 통해 또 다른 레이어를 만들면서 위와 같은 Convolution layers를 만들 수 있습니다.


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


[해당 리뷰는 길벗출판사에서 서적을 지원받고 작성되었습니다.]


딥러닝의 처음을 함께 시작해줄 책


작업환경 설정부터 텐서플로우 기초까지,

딥러닝 기초를 다지고 싶은 분


안녕하세요. 문범우입니다.

이번에 소개해드리고자 하는 도서는 길벗출판사에서 출간한, '모두의 딥러닝'이라는 책 입니다.


최근에 개발자들 사이에서도 머신러닝, 딥러닝은 매우 중요하고 뜨거운 분야가 되고 있습니다.

저도 아직 초보개발자이지만 딥러닝과 데이터분석에 대해서 공부하고자 이것저것 알아보며 학습중인데, 이러한 분들에게 매우 적극적으로 추천드리고 싶은 책입니다.


'모두의 딥러닝'에서 제가 매력적으로 느낀 점들은 아래와 같습니다.


적당한 그림과 사진을 이용한 시각적 효과


보기 좋은 떡이 먹기도 좋다고 하잖아요? 저는 실제로 어떤 책을 고를 때 그 책의 내용이 잘 들어오는지, 잘 읽혀지고 또 읽고싶게 디자인 되어 있는지도 어느정도 신경을 쓰는 편입니다.

물론 그러한 것이 100%는 아니지만 개인적으로 공부할 때는 그런 요소가 어느정도 중요한 편인것 같더라구요.

무조건 색이 화려하고, 이쁘게 만들어야 다가 아니라 여백도 적당히 활용하고 이해하기 어려운 내용에 대해서는 적절한 그림들이 들어가 있어야 내용 흡수도 잘되고 다음날 또 펼쳐보고 싶은 생각이 들기 때문에 고려하는 편인데, 이러한 점은 '모두의 딥러닝'에서 매우 잘 충족시켜주었습니다.

주제가 무작정 세분화 되어있지 않고, 적당히 끊어서 공부할 수 있도록 나누어져 있으며 각 주제네이밍도 잘 되어 있습니다.

책의 내용에서도 코드와 그림을 적당히 이용하면서 깔끔하면서도 이해가 쉽도록 나와있습니다.



초보자를 위한 세심한 설명




사실 IT서적을 읽을때 힘들었던 부분들이, 분명히 책에서는 된다고 했는데, 왜 나는 안되지? 무엇이 문제지? 하면서 부딪히는 부분이라고 생각합니다.

어떤 개발 환경의 문제도 있겠지만, 가끔은 저자가 독자가 당연히 알고 있을 것이라 생각하는 부분에 대한 설명을 생략하기 때문에도 발생하는 문제가 있습니다.

사실상 윈도우에서 개발 환경의 문제를 책에서 모두 다루는 것은 불가능이라 생각하기에 어쩔수 없이 구글링으로 넘어가야 하겠지만, 항상 아쉬웠던건 기초 입문 서적같은 경우에는 주석을 이용해서라도 쉬운 내용들에 대해 함께 코멘트를 달아 놓으면 좀 더 빠르게 이해하고 접근할 수 있지 않을까 라는 생각입니다.

그런데, '모두의 딥러닝' 책에서는 위의 사진과 같이, 책에서 이용하는 파이썬 언어의 기초적인 문법등의 내용 조차 작은 코멘트를 이용해서 함께 설명해주고 있습니다. 물론 언어에 대해서 아시는 분들께서는 저런 내용은 오히려 불필요하다 생각할 수 있겠지만.. 사실상 이러한 것들이 책에서 진도를 나가고, 깊이 이해할 수록 정말 중요한 부분이라고 생각되서 너무 좋은 점이라 생각했습니다.



코드에 함께 작성된 친절한 주석들



이 점도 정말 빠질 수 없이 중요하다고 생각됩니다.

특히나 프로그래밍 분야의 책들에서는 항상 코드가 함께 소개되는데, 앞에서 이론에 대해 열심히 배우고 학습해도 사실상 그 내용들이 코드와 매칭되지 않으면 내가 코드를 직접 작성하면서도 단순히 받아쓰기가 되어버리는 경우가 있고 내가 공부한 내용이 어떻게 적용되고, 어떻게 활용되는지 감이 전혀오지 않을 때도 있습니다.

헌데 '모두의 딥러닝' 책에서는 앞에서 세심한 설명은 물론이고 그 내용들이 코드와 함께 매칭되어 공부할 수 있도록 각 코드별로 주석이 달려 있습니다.

위의 사진과 같이 거의 코드 한줄당 주석 한줄이 달려 있습니다.

직접 코드를 작성하면서 주석도 함께 작성해둔다면 나중에 다시 코드를 보았을 때 복습도 잘 될 것 같고, 스스로 코드만 작성해보고 다음날 자기가 직접 주석을 작성해본다던지 등의 복습방법도 좋을 것 같습니다.



다양한 실습 예제를 통한 실전 감각 익히기


저도 최근에 온라인 강의나 구글링을 통해서 딥러닝에 대해 약간씩 공부하고 있지만, 아직 공부양이 부족하기도 하고, 실제로 예제등을 이용해보지 않아서 인지 내가 공부한 것들이 어떻게 사용되고, 실전에서 어떻게 적용될 수 있는지에 대한 감을 많이 못 잡을 때가 많습니다.

물론 스스로 해결해야 하는 부분이기도 하지만, 기초 입문 서적에서는 간단한 예제들이라도 이용해서 이론과 함께 제공된다면 앞으로의 공부에 더 자극도 되고, 도움도 될 수 있을 것이라 생각됩니다.

'모두의 딥러닝'에서는 초반에 기초적인 이론들을 공부하고 난 후에 간단한 예제들을 바탕으로 실전 감각을 익히는 파트가 잘 준비되어 있습니다.



이렇게 '모두의 딥러닝' 책이 어떤 매력을 가지고 있고, 어떻게 구성되어 있는지 말씀드렸는데 약간의 아쉬운 점이 하나 있었습니다.

사실상 많은 프로그래밍 책에서도 아쉽다고 느낀 점이기도 했는데, 해당 도서를 마무리 하고 나면, 앞으로 어떤 수준의 책을 보는게 좋을 것인지, 같은 출판사에서 어떤 책을 추천해주고 싶은지 등의 간단한 언급이 있으면 좋을 것 같았습니다.

아직 제가 깊이 공부하지 못한 탓도 있겠지만 얼핏 보기에 시중에 기초 입문 서적은 정말 많은데, 그 후 더 깊은 공부를 하기 위해서는 어떤 책이나 논문 등을 보아야 할지 쉽게 감을 잡기가 어렵다고 생각됩니다.

물론 스스로 더 찾아보거나, 직접 프로젝트를 진행하면서 배우는 것도 좋겠지만 이러한 것도 방향을 잡기 힘들때가 있기에 이러한 내용에 대한 코멘트도 함께 있으면 어떨까라는 생각을 해보았습니다.


'모두의 딥러닝' 책을 짧게 요약하고 소개해드리자면,


딥러닝, 텐서플로우, 케라스 활용에 대해 처음이거나, 건들여보았어도 아직 정리가 안된것 같은분, 다양한 실습예제를 통해 실전 감각을 익히고 싶으신 분들에게 정말로 추천드리고 싶습니다.

하지만 나는 딥러닝의 기초적인 이론 내용에 대해서 친구에게 소개할 수 있고, 텐서플로우도 어느정도 자유롭게 다룰 수 있다 하시는 분들에게는 보다 심화적인 책을 찾아보기를 권합니다.


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요. 문범우입니다.

이번 포스팅에서는 dropout과 model ensemble에 대해서 살펴보도록 하겠습니다.


* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.

관련한 상세 내용은 아래 링크를 참고해주세요.

https://hunkim.github.io/ml/




1. Dropout


우리가 dropout을 하는 이유는 바로 아래와 같은 overfitting 때문입니다.



우리가 과거에 알아봤던 것처럼, 훈련 data에 있어서는 100%의 accuracy를 내지만, 실제로 test data에 있어서는 높은 예측율을 내지 못하게 되는 현상이죠.



위와 같이, 파란색 그래프, training 에서는 에러율이 점점 낮아지지만, 실제로 빨간색 그래프처럼 test data를 통해 확인해보니 어느 시점부터 에러율이 더 증가하게 됩니다.


이러한 overfitting은 우리가 더 깊게 만들수록 일어날 확률이 커집니다.

왜냐하면 더 깊어질수록 더 많은 변수가 생기기 때문입니다.


그럼 이를 해결하기 위해서는 무슨 방법이 있을까요?


첫번째로는, 더 많은 데이터를 훈련시키는 것입니다.

또는 feature를 줄여주는 방법도 있을 것입니다.

그리고 우리가 예전에 간단히 알아봤던, Regularization 이라는 방법이 있습니다.



우리가 예전에 알아봤던 것처럼, 위의 식과 같이 처리함으로써 Regularization을 하는 L2regularization도 있습니다.


그리고 Neural Network에서는 또다른, dropout이라는 방법이 있습니다.

dropout이란 쉽게 말해서, 위 그림에서 왼쪽 그림과 같은 모델에서 몇개의 연결을 끊어서, 즉 몇개의 노드를 죽이고 남은 노드들을 통해서만 훈련을 하는 것입니다.

이때 죽이는, 쉬게하는 노드들을 랜덤하게 선택합니다.




쉽게 말해 각 노드들을 어떤 전문가라고 생각해본다면 랜덤하게 몇명은 쉬게하고 나머지만 일하게 합니다. 

그리고 마지막에는 모든 전문가들을 총 동원해서 예측을 하게 합니다.


이러한 아이디어가 dropout 입니다.


실제로 텐서플로우에서 구현하기에도 어렵지 않게 가능합니다.

우리가 원래 만들었던 layer를 dropout함수에 넣어서, 몇 퍼센트의 노드가 일하게 할 것인지 함께 적어줍니다.

위의 코드를 보면 Train에서는 0.7, 즉 70%의 노드들이 랜덤하게 훈련되게 하였습니다.

그리고 실수하면 안되는 점이 Evaluation 과정에서는 dropout_rate를 1로 함으로써 100%의 노드들을 참가시키도록 해야 합니다.



2. Ensemble



우리가 추후, 학습시킬 수 있는 장비가 많을때 사용할 수 있는 또 하나의 방법도 있습니다.

Ensemble이라고 하는 것인데, 위와 같이 여러개의 독립적인 모델을 만듭니다. 이때 훈련 데이터셋은 별도로 해도 되고, 모두 같은 훈련 데이터셋을 이용해도 상관 없습니다.

이때 각 모델의 초기값이 서로 다르기때문에 결과도 약간씩 다를 것입니다.

그리고 이후에 독립적인 모델들을 모두 합쳐서 한번에 예측을 하게 합니다.

즉, 이것은 전문가 한명에게 어떤 질문을 하는 것이 아니고 서로 독립적인 전문가 다수를 모아두고 질문을 하는 것과 같습니다.


실제로 Ensembel을 이용하면 2%~5%까지도 예측율이 올라간다고 합니다.


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요. 문범우입니다.

이번에는 지난 포스팅에 이어서 딥러닝을 잘하는 방법 중 weight의 초기값을 설정하는 방법에 대해서 알아보도록 하겠습니다.


* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.

관련한 상세 내용은 아래 링크를 참고해주세요.

https://hunkim.github.io/ml/




1. RBM(Restricted Belief Machine)


우리가 지난 포스팅에서 위의 그림과 같은 Vanishing gradient 문제에 대해서 알아보았습니다.

그리고 이 문제에 대해서는 Hilton 교수님께서는 4가지 이유를 꼬집었습니다.


위의 4가지 항목중 제일 아래에 있는 것은 우리가 지난 포스팅에서 sigmoid함수 대신, ReLU함수를 사용함으로써 해결할 수 있었습니다.

하지만 하이라이트 된 것과 같이 또 다른 문제도 있었습니다.


이전의 테스트에서도 아래와 같이, 같은 ReLU함수를 사용했음해도 불구하고 cost가 초반에 다르게 변화하는 것을 볼 수 있습니다.


이러한 현상이 발생하는 이유는 우리가 테스트를 할때, 초기값을 랜덤하게 지정해서 발생한 현상입니다.


그럼, 이런 초기값에 대해서 좀 더 자세히 살펴보도록 하겠습니다.

단적으로 초기값을 0으로 설정해보면 어떨까요?

그럼, 위와 같은 그림에서 W를 0으로 둔것이고, 이것이 chain rule에서 사용됩니다. 그럼 x = df/dg * W 이므로 x = 0이 되고, 그 앞에 있는 것들도 모두 0이되면서 gradient가 사라져 버립니다.


따라서, 절대로 초기값으로 0을 주면 안된다는 것을 알 수 있습니다.

그럼 초기값을 어떻게 주어져야 할까요?


이에 대해 2006년 Hilton교수님께서 논문을 쓰시면서 RBM(Restricted Boatman Machine)을 사용함으로써 해결하게 됩니다.

그리고 이러한 RBM을 사용한 네트워크를 DBN(Deep Belief Networks)라고 합니다.


어떻게 동작되는 것 일까요?


먼저, 입력을 재생산 해냅니다.


위의 그림과 같이, 입력값을 weight와 곱해서 b값을 얻어냅니다. 또한 b 유닛아래에 있는 것들에 대해서도 같은 방법을 통해서 값을 얻습니다. 이러한 과정을 Forward 라고 합니다.



그리고, Backward 방법으로, 우리가 얻은 값들과 weight를 통해 위의 그림에서의 b 값을 얻습니다.

그럼 우리가 처음에 입력한 값을 x라고 한다면, x와 b의 값의 차이가 존재할텐데 이 차이가 최소가 될 때까지 weight를 조절합니다.


이렇게 해서 weight를 구하는 것을 RBM이라고 합니다.

그리고 위와 같은 방법을 encoder/decoder라고도 합니다.


실제로 이것을 네트워크 상에서 적용시키기 위해서는 아래와 같은 과정을 가집니다.

여러개의 레이어가 있을때, 입력값 측의 레이어부터 시작하여 layer 1과 layer 2를 encoder/decoder를 수행하고, 이후에 layer2 와 layer3에 대해 수행하며 끝까지 나아가는 방법입니다.


이제 이러한 과정을 통해 각 weight를 구할 수 있고, 그것을 학습시킨다, training한다는 표현보다는 fine tunning 이라는 표현을 사용합니다.

학습하는 것보다 훨씬 더 빨리 진행되는 작업이기 때문이죠.

이러한 fine tunning이 끝나게 되면 이후 우리가 학습시키고자 하는 데이터들에 대해서 label을 붙여서 실제로 training을 진행합니다.



2. Xavier initalize




그런데 실제로 이것을 구현하는데 있어서는 복잡한 과정이 있을 수 있습니다.

하지만 좋은 소식은, 2010년에 발표된 논문에서 우리가 굳이 RBM을 쓰지 않아도, 좋은 초기값을 얻을 수 있다는 Xavier initialize라는 알고리즘이 나왔습니다.


이는 입력의 노드의 개수에 비례해서 초기값을 세팅하면 된다는 식의 알고리즘 입니다.


이를 식으로 간단히 살펴보면, 우리가 좋은 값, 좋은 weight를 얻기 위해서 입력값의 개수 fan_in 과 출력 값의 개수 fan_out을 이용하여 초기값을 주는 것입니다. 이러한 식을 통해 어쩌면 RBM보다 더 좋은 결과를 가질 수 있다고 합니다.


블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요