본문 바로가기

Research/DeepLearning

convolutional neural network 무식하게 분석하기 - 1

convolutional neural network 무식하게 분석하기 입니다. 이 포스트는 그 첫번째이고, 저도 처음 공부하는거라 틀린것이 매우 많을꺼고 이해못하는 것이 존재합니다. 또한 잘못 이해할수도 있겠죠^^; 하지만, 현재는 그냥 넘어갈지언정 언제가 새로운 자료를 찾아내거나 새롭게 이해하면 그때그때 업데이트 할것입니다. 즉, 이 포스트가 공개될지라고 완성본은 절대 아니라는 점을 기억해두시기 바랍니다.


최근 이미지 분류의 Hot 이슈는 머니머니해도 CNN기반의 Deep Learning입니다. 거의 꼭 알아야하는 수준으로 발전하고 있어서 저도 공부좀 해볼랍니다. 

여기서는 초보인지라, 하나의 CPU기반 오픈소스를 분석해가면서 웹의 다른 이런저런 자료를 찾아가면서 이해할것같네요. 


기본 소스 :  https://github.com/xingdi-eric-yuan/single-layer-convnet 

저작인의 블로그 : http://eric-yuan.me/cnn/

따라서, 소스에대한 질문은 이분에게로.ㅎ


저는 그냥 무식하게 소스 분석함으로써 대충 CNN의 이해해 볼려고합니다.

참고로 이소스는 CPU기반으로 OpenCV상에서 Run합니다. 컴파일 및 2틀동안 돌리면 mnist의 숫자 인식률이 블로그대로 98%정도 나오네요.


이 소스 CNN 구조는, 

1. 1개 Conv layer - 8 convolution kernels (13 * 13 size)

2. 1개 Pooling layer (Pooling dimension is 4 * 4)

3. 2개 full connected layer (Each has 200 hidden neurons)

4. 1개 Softmax regression layer

 

같습니다. 그럼 이런 순서로 해볼랍니다.




1. INPUT VALUE

당연히 이미지인데 1채널의 Gray 이미지입니다. (이 후속 버전은 3채널을 적용하고 있습니다.) 여기서는 숫자인식이 목적인지라..

cv::Mat 타입으로 저장하는 2차원의 이미지(w, h)의 28x28 사이즈의 필기체 숫자 이미지를 받습니다.




2. Convolutional Layer



2.1 2d Convolution 연산

CNN의 이름에서 보듯이 Convolution은 가장 중요한 Key입니다. Convolution 한국말로 하면 회선(나선형) ? 

정확하게 하면, 일정 크기의 커널 크기를 이용하여 입력이미지에서 Kernel 사이즈 만큼 주위 픽셀과 kernel과의 곱에 대한 Weighted Sum입니다. 


잘 설명된 예를 찾아보니, [링크] 여기가 잘 나와있네요.



[원본 링크]

개념 자체는 그다지 어려운 편은 아닙니다.



2.2 2d Convolution 연산 소스


// A Matlab/Octave style 2-d convolution function.

// ref)

//      http://www.songho.ca/dsp/convolution/convolution2d_example.html

//      http://blog.timmlinder.com/2011/07/opencv-equivalent-to-matlabs-conv2-function/

Mat conv2(Mat &img, Mat &kernel, int convtype){

        Mat dest;

        Mat source = img;

        if(CONV_FULL == convtype) {

                source = Mat();

                int additionalRows = kernel.rows-1, additionalCols = kernel.cols-1; // 12x12


                // convolution 연산에 따른 boundary 처리 함수 - 가장자리 픽셀을 특정한 방법으로 확장시켜 조금 더 큰 영상을 생성 - Padding

                //      NxN kernel이면, (N-1)/2 만큼 확장 -> 최종적으로 상하좌우를 확장시키기 때문에 결국, (N-1)만큼 확장

                //      -> copyMakeBorder( src, dst, top, bottom, left, right, borderType, value );

                //              BORDER_CONSTANT: Pad the image with a constant value (i.e. black or 0)

                //              BORDER_REPLICATE: The row or column at the very edge of the original is replicated to the extra border.

                copyMakeBorder(img, source, (additionalRows+1)/2, additionalRows/2, (additionalCols+1)/2, additionalCols/2, BORDER_CONSTANT, Scalar(0));

        }


        Point anchor(kernel.cols - kernel.cols/2 - 1, kernel.rows - kernel.rows/2 - 1); // kernel's center


        int borderMode = BORDER_CONSTANT;

        Mat fkernal;


        // This is equivalent to a rotation by 180 degrees. The reason for flipping is the reflection of the kernel (minus sign) in the convolution

        // formula: http://en.wikipedia.org/wiki/Convolution#Definition

        // if not flip, -> it is not convolution -> it is correlation

        flip(kernel, fkernal, -1); // -1 : 상하 좌우 반전 - rotation by 180 degree


        // convolution 수행 함수

        filter2D(source, dest, img.depth(), fkernal, anchor, 0, borderMode);


        if(CONV_VALID == convtype) {

                dest = dest.colRange((kernel.cols-1)/2, dest.cols - kernel.cols/2).rowRange((kernel.rows-1)/2, dest.rows - kernel.rows/2); // 원상복귀 - subregion roi extracting!!i

        }

        return dest;

}




2.3 Convolution Layer

layer도 크게보면 WxX+b의 일부분이다.

즉, W = Kernel이고 X는 입력값 그리고 b는 bias일뿐이다.

WxX는 입력한 이미지에서 Convolution 결과이다. 다시 말해 특별한 형태가 아니라, NN의 basic에 충실하다는 의미!!

이 개념을 이해하면 쉬울듯하다. 이해하고 나서 차아보니 

여기에 잘 나타나있는듯 [링크]



즉, 위의 그림 구조를 충실히 따른다는 의미이다.(바로 위 링크에서 참조, v는 weight);


Weight는 Kernel이고 따라서, 학습에 의해 계산된다. 이 의미는 사용자가 임의의 정의된 Kernel를 사용하지 않는다는 것이다. 예를 들어, Canny Edge detection에서, robert kernel같은 미리정리된 커널이 아니라 순전이 학습를 통해 이루어진다.


전체 과정을 보면, 



이런식으로 볼수 있다.

1. convolution

2. activate function

3. pooling



convolution result :  16 , 16

-0.399 -0.392 -0.242 -0.391 -0.426 -0.018 0.174 0.087 -0.250 -0.337 -0.155 0.011 -0.018 -0.019 0.019 0.029

-0.292 -0.425 -0.386 -0.446 -0.513 -0.249 0.062 -0.010 -0.223 -0.388 -0.296 -0.059 -0.058 -0.027 0.088 -0.024

-0.164 -0.555 -0.588 -0.558 -0.414 -0.460 -0.239 -0.143 0.002 -0.353 -0.409 -0.126 0.185 0.089 0.033 -0.152

-0.089 -0.647 -0.700 -0.545 -0.501 -0.596 -0.288 -0.091 0.091 -0.288 -0.463 -0.113 0.270 0.241 0.068 -0.001

-0.084 -0.745 -0.799 -0.627 -0.512 -0.393 -0.279 -0.030 0.074 -0.209 -0.421 -0.016 0.271 0.264 0.031 -0.016

0.063 -0.550 -0.649 -0.547 -0.523 -0.394 -0.255 -0.114 -0.195 -0.460 -0.683 -0.377 -0.112 0.061 0.032 -0.072

-0.060 -0.421 -0.645 -0.612 -0.360 -0.305 -0.295 -0.165 -0.195 -0.425 -0.728 -0.547 -0.144 0.157 0.176 -0.035

0.038 -0.158 -0.465 -0.481 -0.392 -0.217 -0.378 -0.362 -0.269 -0.526 -0.832 -0.683 -0.220 0.223 0.348 -0.047

-0.029 -0.019 -0.409 -0.559 -0.579 -0.426 -0.607 -0.634 -0.477 -0.533 -0.877 -0.654 -0.245 0.138 0.117 -0.131

0.008 0.059 -0.321 -0.678 -0.621 -0.363 -0.430 -0.549 -0.512 -0.662 -0.957 -0.882 -0.548 -0.027 -0.009 -0.291

0.047 0.076 -0.106 -0.499 -0.581 -0.392 -0.182 -0.147 -0.287 -0.601 -0.850 -0.859 -0.513 -0.202 0.059 -0.024

-0.070 -0.121 -0.098 -0.354 -0.589 -0.424 0.006 0.221 0.048 -0.317 -0.530 -0.584 -0.278 -0.119 -0.002 0.041

0.021 0.088 0.064 -0.043 -0.408 -0.516 -0.141 0.153 0.110 -0.169 -0.311 -0.321 -0.024 0.140 0.332 0.401

0.121 0.233 0.166 0.162 -0.114 -0.286 -0.074 0.347 0.512 0.480 0.149 0.075 0.293 0.564 0.543 0.345

0.227 0.327 0.284 0.319 0.099 -0.238 -0.032 0.208 0.515 0.521 0.207 -0.057 0.231 0.555 0.670 0.351

0.022 0.059 0.080 0.189 0.123 -0.151 -0.132 0.221 0.377 0.455 0.277 -0.129 0.009 0.380 0.474 0.204

ReLU result :  16 , 16

0.000 0.000 0.000 0.000 0.000 0.000 0.174 0.087 0.000 0.000 0.000 0.011 0.000 0.000 0.019 0.029

0.000 0.000 0.000 0.000 0.000 0.000 0.062 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.088 0.000

0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.002 0.000 0.000 0.000 0.185 0.089 0.033 0.000

0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.091 0.000 0.000 0.000 0.270 0.241 0.068 0.000

0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.074 0.000 0.000 0.000 0.271 0.264 0.031 0.000

0.063 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.061 0.032 0.000

0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.157 0.176 0.000

0.038 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.223 0.348 0.000

0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.138 0.117 0.000

0.008 0.059 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000

0.047 0.076 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.059 0.000

0.000 0.000 0.000 0.000 0.000 0.000 0.006 0.221 0.048 0.000 0.000 0.000 0.000 0.000 0.000 0.041

0.021 0.088 0.064 0.000 0.000 0.000 0.000 0.153 0.110 0.000 0.000 0.000 0.000 0.140 0.332 0.401

0.121 0.233 0.166 0.162 0.000 0.000 0.000 0.347 0.512 0.480 0.149 0.075 0.293 0.564 0.543 0.345

0.227 0.327 0.284 0.319 0.099 0.000 0.000 0.208 0.515 0.521 0.207 0.000 0.231 0.555 0.670 0.351

0.022 0.059 0.080 0.189 0.123 0.000 0.000 0.221 0.377 0.455 0.277 0.000 0.009 0.380 0.474 0.204







'Research > DeepLearning' 카테고리의 다른 글

Softmax Regression  (1) 2015.01.12