@Chapter
09. Convolutional NeuralNet 1

@
왜 CNN이라고 하는지. 일반 NN이랑 무엇이 다른지. 알아보자.
이미지 처리를 NN으로 할때 방법론을 CNN으로 하면 제일 좋다. 라는 설명을 많이 하고 있다.
논문이나 이런거 찾아보면 CNN은 이미지 처리 랑 관련지어 설명을 해 줄것이다.

@
feature를 찾는다거나 detecting을 한다든가 인식을 한다든가 이런 작업을 할때 대상 raw 이미지가 있을것이다.

MNIST 샘플은 28*28 픽셀 크기의 이미지를 사용한다. 그런 이미지가 여러장 있을거다. 그리고 이 패키지가 하나의 데이터 셋이 되는 거다.

우리가 이전에 데이터셋이라고 본거는 x, y 의 한 점을 의미 했는데 여기서는 데이터의 집합(이미지)가 하나의 텐서가 되는 거다. 이게 행렬관점에서 2차원(일반적 행렬) 이미지가 될수 있고 RGB칼라를 표현하면 3차원(행렬관점에서)이미지가 될것이다.

@
위에서 논의된 상황을 어떻게 NN으로 구현을 할까?

일반적으로 NN을 구현할떄는
input data x $\rightarrow$ hidden layer H 로 들어간다. 이때 $\theta$ 라는 weight가 주어졌을때,
input data x와 weight $\theta$ 를 각각을 벡터로 생각한다면 $\theta x^{T}$ 이렇게 표현했다.

위 수식에서 $\theta x^{T}$ 은 일반적인 행렬곱이다.

CNN에서는 일반적인 행렬곱 대신에 convolution (곱하고 모두 더하는 연산)을 한다고 생각하면 된다.
그래서 convolution neural net 이다.

@
convolution 연산을 하려면 patch(window, kernal, filter)가 필요하다. patch 에 커버되는 raw 이미지로 만들어진 raw 이미지 행렬의 원소 값들을 patch 의 원소값들과 전부 convolution 하면 하나의 convolved value 가 나온다. 옆으로 아래로 쭉 슬라이딩하면서 전체를 convolution 한다.

patch 하나가 CNN에서는 하나의 weight가 된다.
weight 5개라면 patch가 5개이다.

@
28*28 이미지로 만들어진 input data 입력이 하나 들어왔을 때 이걸 hidden layer 로 가져가야한다. hidden layer의 node 가 5개라면 이미지 행렬이 hidden layer에 있는 각각의 node 에 연결이 될테고 각각의 엣지에 weight 들이 있을 것이다. 각각의 weight가 patch를 의미한다. tf에서는 patch로 5*5크기의 patch 를 사용하고 있다. 처음에는 5*5 크기의 patch 의 원소들이 랜덤으로 초기화가 된다. 그리고 바로! 이 patch, patch안에 있는 원소들을 계속 학습을 시키는 것이다. patch를 트레이닝을 시키면 raw 이미지의 특징을 찾게되고 그러면서 patch 가 인식도 하고 패턴도 알아내게 되고, 여러 처리를 할수 있게 된다.

난 이부분이 이해하기 어려웠다. patch를 하나의 weight로 생각하고 이걸 어떻게 최적화로 수렴시키는가 에 대한 포인트. 이거 이해하고 기억하면 여기서부터는 어렵지 않다.

@
5*5 patch를 28*28 image 행렬에 붙인다. patch1에 있는 값들이 있을텐데 모두 weight1역할이다. 그리고 image 행렬의 원소들과 weight, 그러니까 patch안의 원소들을 convolution 하면서 전체를 sliding 한다. 나온값들은 쌓인다. 그리고 이것은 24*24 크기의 input으로 들어온 이미지 행렬의 특징을 묘사하는 이미지 행렬이다.

@
weight 가 하나가 아니다. hidden layer에서 노드를 5개라고 했으므로 input layer에서 노드 하나 $X_{1}$ 에 input data인 이미지 행렬과 hidden layer 로 연결되는 엣지에는 $w_{1}$ 부터 $w_{5}$ 까지 5개의 patch가 있다.

@
여기서 중요한 포인트는 이미지 행렬과 5개의 weight들이 각각 convolution되어 hidden layer로 들어가게 될텐데, 이 weight들을 5*5 크기의 patch 5개를 뭉친 5*5*5 크기의 한 덩어리로 생각하는 것이다. 그러면 이미지행렬과 weight들이 convolution된 결과값들이 만들어내는 모양은 24*24 크기의 특징묘사이미지행렬이 5개 모인 24*24*5 크기의 한덩어리가 된다. 이렇게 hidden layer에서 input 이미지 행렬과 patch가 convolution된 연산의 결과로 한 덩어리로 작용하는식으로 보는 관점을 convolution hidden layer 라고 한다.

@
convolution layer 를 하고 pooling 이라는 과정을 거친다.

24*24 크기의 특징묘사이미지행렬이 나왔다고 했다. 이 크기를 감소시키는 시도가 pooling 이다.

pooling 과정도 patch 를 사용한다. patch 의 크기는 tf 기준으로 2*2이다.

But, 여기서는 convolution 과 다르게 일일이 다 검사하지는 않고 patch 크기만큼 한번에 이동한다. 특징묘사이미지행렬을 sliding 하면서 2*2크기의 pooling patch의 경우 4개의 원소들을 하나의 값으로 output 시킨다. output 시키는 알고리즘은 다양하다. 가장 큰값을 뽑든지, 평균을 내서 뽑든지, 기타 등등, 어차피 특징을 추출하는거니까 하나의 기준을 세워서 아무렇게나 뽑아도 된다. 결과는 24*24 크기의 특징묘사이미지행렬의 크기가 반으로 줄어든다. 12*12 크기의 크기가 감소된 특징묘사이미지행렬이 된다.

@
위에서 설명한 모든 과정이 하나의 hidden layer 에서 일어난다.

12*12 크기로 크기가 감소된 특징묘사이미지행렬에 다시 weight를 줘서, 즉 다시 patch와 convolution 연산을 통해 특징묘사이미지행렬2 를 뽑아낸다. 그리고 pooling을 해서 크기가 감소된 특징묘사이미지행렬2을 만들어낸다.

그리고 다시 convolution $\rightarrow$ pooling 을 반복하다보면 나중에는 컴퓨터가 연산방식을 통해 처리할수있는 크기의 이미지(tf의 경우는 한 이미지의 크기를 7*7 까지 줄였다.) 로 만들고 기차모양처럼 쭉 쌓는다. 1024개의 7*7 크기의 이미지행렬을 1024개 붙인것과 같이 만든다. 7*7 픽셀크기의 이미지(특징, feature)행렬을 하나의 클래스로 볼 수 있고 그러한 클래스가 1024개 있는 꼴이다.

@
부피 형태의 이미지를 하나의 벡터로 만든다. 그 벡터의 크기는 (7*7*1024) by 1 이다.

@
엄청 세로로 긴 벡터. 이게 hidden layer에서의 output 값이다. 이 output으로 output layer에서 softmax function 통과시켜 값 구하고 cross entropy 구해서 뭔가를 최적화를 하게되면 쭉 나온 값중에 3번 output인 $y_{3}$에서 숫자가 가장 높게 나왔다 그러면 입력된 input data가 3에 있는 이미지구나 이렇게 인식을 하게 되는 거다.

@
이게 기본이고, convolution 한 결과를 ReLu function에 넣는 단계도 있다.

@Chapter
Convolutional NeuralNet 2

@
이전강의를 조금 review 해보자.

28*28 크기 raw 이미지 여러장이 있다. 이걸 extract feature stage에 통과시키고, classfication stage 에 통과시킬 것이다.

@
convolution 을 수행한다면 하나의 patch(비유하자면 하나의 weight)가 있고 이 하나로만 convolution하는게 아니라 patch를 여러개 (마치 NN에서 각각의 input에 weight가 각각 곱해져 hidden layer로 들어가듯이.) 사용한다. 출력되는 각 feature 마다 하나의 patch 가 관계된다고 생각하면 된다. 다른말로 노드 하나하나 당 하나의 patch 가 관계된다.

@
convolution에 대해. patch를 sliding 시켜서 raw image 원소와 patch 원소 끼리 곱하고 더하는걸 convolution 연산이라고 할 수 있다.

@
sliding 하는 patch 가 무슨 의미가 있길래 이게 weight가 되나?

이미지 프로세싱 관점에서 보면 먼저 선처리를 하게 된다. 나는 색깔을 많이 보고싶다. 선을 많이 보고싶다. 이미지 처리의 목적이 있다고 하면 목적을 더 잘 달성시키게끔 하는 그 이미지에 대한 선처리가 필요하다. 선처리는 다른게 아니고 이미지를 흐릿하게 한다든가, 밝게 한다든가, 채널을 바꿔서 그레이를 RGB로 바꾼다든가 혹은 반대로 RGB를 그레이로 바꾼다든가, 엣지를 추출한다든가, 분할하기 좋게 가까운 색의 영역을 단색으로 바꿔버리는기법 등 여러가지가 있다.

그때 사용하는 기법이 여기서는 kernal 이라고 한다. SVM에서도 kernal 얘기를 했었는데, 여기서도 이 patch 를 갖다가 kernal이라고 한다. 커널을 슬라이딩 하면서 weight sum을 해서 다른 이미지를 만든다.

이렇게 만들어진 이미지의 특성을 보면 이 커널에 세팅되어있는 원소들의 값에 많이 좌지우지 된다. 이미지 에디터의 필터가 많은데 그 필터의 종류가 커널의 종류라고 생각하면 된다. 가우시안 필터같은 경우는 3*3 커널을 사용한다고 했을때 가운데 큰 숫자가 들어간다. 그 주변으로 작은숫자, 많이 작은숫자 이렇게 들어간다. 산종모양그래프처럼.

weight sum을 했을때 가운데 큰 수와 곱해지는 image의 값은 큰 weight를 가지게 된다. 작은 숫자들은 convolution 에서 더할때 최종 값에 큰 영향을 못미친다. 커널 안에 원소들은 커널과 곱해지는 원래 이미지의 특성 픽셀의 중요도를 올려주는 역할을 한다.

4귀퉁이의 숫자가 큰 커널이라면 이걸로 슬라이딩하면 어떤 이미지가 나올지 모르겠지만 어쨌든, 4귀퉁이의 영향을 많이 받는 그런 이미지가 나오게 된다.

@
캐인 엣지 같은경우는 커널을 2개 사용한다.

@
이 얘기를 왜했냐면 커널을 만들어보자는 얘기다.

어떤 이미지가 있으면 이 이미지의 특징을 어떻게 잡아야지 내가 원하는 이미지를 만들수있을까 이건 이미지 프로세싱에 대한 얘기고,

우리가 원하는것은 이 이미지가 컴퓨터가 이렇게 알아먹었으면 좋겠다. 고양이 그림을 컴퓨터가 고양이로 분류를 했으면 좋겠다. 이런거다. 우리가 알고있는 것은 이 이미지는 고양이 이미지이다. 라는 사실 하나다. 학습을 시킬때 뭘 학습을 시키냐, 이 이미지를 보여줬을때 고양이로 알아먹을수있도록 고양이 클래스의 확률값이라든가 히스토그램의 값이 높아질수있도록 하는 그런 필터가 sliding 해서 input된 이미지의 feature 을 잘 반영하는 이미지행렬을 만들어 낼 수 있다면 이 이미지를 컴퓨터는 고양이로 인식할수 있다. 이런 개념이다. 그 featrue 이미지를 여러개의 weight로 기능하는 patch 를 이용해서 계속 찾아나가는 것이다. 그 과정에서 어떤 patch는 경계선을 잘 찾도록 학습이 되는 patch도 생길수있고, 어떤 patch는 질감을 잘 찾도록 학습이 되는 patch도 생길수있고, 어떤 patch는 부드러움을 잘 찾도록 학습이 되는 patch도 생길수있고, 이런 patch 들이 다 모여서 계속 반복적으로 sliding해서 결과 이미지를 컴퓨터가 본다면 컴퓨터는 이걸 어떤 클래스로 나누게 될 것이다.

이런 의미로 patch와 sliding 등의 행위를 이해하면 좋을것이다.

@
convolution이 다 끝났다고 가정하자. 끝난 이미지특징묘사행렬을 그대로 사용할 수 는 없다. 다 사용하기에는 아직 이미지특징묘사행렬의 크기가 즉 이미지가 너무 크다. 그래서 down sampling (image 용량 reduction)을 거치게 되는데 그 중에서 pooling 기법을 사용한다. patch를 이용해 이미지행렬에 대해 convolution 을 해서 출력된 이미지특징묘사행렬의 원소들은 원래 이미지에서 특징으로서 중요한 픽셀 혹은 이미지행렬에서 숫자가 큰 원소들이 뽑혀있는 것이다. 따라서 pooling을 통해 큰값만 뽑아내고 작은값은 버려도 특징은 보존되면서 용량은 줄어들게 된다.

@
pooling은 2*2 크기의 patch로 한번에 건너뛰면서 sliding한다. 이미지특징묘사행렬에서 가장 큰 값을 뽑는다. 이게 pooling이다. 24*24크기의 이미지특징묘사행렬이 12*12 크기의 크기가 감소된 이미지특징묘사행렬로 중요한 특징은 보존하면서 용량이 감소된다.

@
pooling이 완료되었으면 나온결과를 가지고 다시 convolution-pooling 을 반복한다. hidden layer에서 노드 끝까지 반복한다. output layer 에서 softmax function을 통과시킨 값을 구하고 cross entropy를 구해서 역전파를 한다. 그럼 학습이 진행이 되게된다(patch 의 원소값들을 업데이트 시켜준다).

@
convolution과 pooling만 수행하는 것은 아니고 ReLu function도 사용한다.

우리는 logistic regression 모델에서 hypothesis functioin으로 sigmoid functiond을 사용했었다. CNN에서는 hypothesis function으로 ReLu function 을 사용하게된다. ReLu function은 exponential에 근사화된 function이라 기울기가 45도 보다는 좀 가파르다. 이 함수의 특징은 이거(0으로 확정된 구간) 아니면 이거(0이 아닌 비례 구간). 0 아니면 양수. 같은 것이다.

어떤 이미지에 대해 patch를 통해 convolution 한 결과를 얻고 pooling까지 했으면 출력된 크기가 감소된 이미지특징묘사행렬의 원소들은 원래 input 이미지에서 중요한 픽셀(feature) 을 담고있는 것이다. 크기가 감소된 이미지특징묘사행렬을 ReLu function에 넣게되면 어떤 threshhold(x=0 에서 값이 딱 변화하는 순간)를 그릴수 있다. x가 0보다 작으면 output값은 0으로 확정된다.

@
ReLu function을 sigmoid function의 대체로 봐도 된다. 계산도 편리하고, 함수가 명확하다 0 이하는 0 근접이 아니라 0으로 확정하기 때문에.

pooling을 한 결과값 행렬 중 어떤 원소가 음수가 나왔으면 Relu function 으로 음수를 제거해줄수 있다.