CNN(Convolution Neural Network)

본 게시물은 LGaimers 4기 Module 6의 주재걸 교수님의 딥러닝 강의를 수강 후 요약하였으며, 추가적인 자료는 Google, Arxiv 등에서 검색하였습니다.


 

주재걸 교수님 CNN 강의듣고 드디어 묵은 체증이 싹 가신 느낌

인턴하면서 CV 프로젝트들을 위주로 많이 진행하고 또 겪어왔지만, 솔직히 옆에서 무슨 말들을 하는지 감으로만 알아들었지 정확히 알아듣진 못했는데(...) (감으로만 이해하고 있었다는 뜻... 아무래도 CV 를 3일만에 배웠으니까....)

Aimers강의를 들어가면서 머신러닝 딥러닝 개념부터 시작해서 다시 기초를 쌓으니 뭔가 좀 이해가 가는 생각에 너무 기뻐서 CNN 개념을 함께 정의... 공부해보고자 들고왔습니다 ^__^ vVㅎㅎ (이제 드디어 논문을 이해해가며 읽을 수 있을거같음 ㅠ)

 

그럼 레쓰고

 

역시나 틀린 부분이 있다면 댓글로 정정해주시면 감사하겠습니다🤗


CNN(Convolution Neural Network) 란?

CNN, 즉 Convolution Neural Network는 합성곱 신경망이라고도 하며, 말 그대로 Convolution 연산 수행을 하는 neural network를 말합니다. CNN, RNN, FCN(Fully connected layer) 등 모두 각기 다른 방식으로 동작하는 Neural network의 종류이죠.

 

CNN의 경우에는 물체를 규정짓는 부분, 부분의 요소 패턴들이 있다는 것을 활용해서 요소 패턴들을 잘 검출하고 인식하는 과정들을 통해 convolution net을 동작시킵니다.

 

 주로 아래와 같은 Task 들에서 이용됩니다.

  • Classificaiton
  • Retrieval
  • Skeleton (관절, 움직임 인식 등?)
  • Detection

 

The evolution of the CNN architecture

 

 

 다음과 같이 Neural network 가 진화해 온 역사를 살펴 볼 수 있는데요, 2015년 이후에는 사람의 물체인식 성능을 능가하는 퍼포먼스를 보여주기 시작합니다.

 

Activation map

 

그럼, CNN 이 어떻게 동작하는지 천천히 살펴볼까요?

 

그림1

 

다음과 같은 두 개의 이미지가 존재한다고 생각해 봅시다.

Convolution Neural Network의 특징은 이미지의 특징적인 요소 패턴들을 추출하여 인식과 같은 기능들을 수행함에 있습니다.

 

두 개의 이미지를 포개어 겹쳐 보았을 때, 겹쳐지는 부분을 1, 겹쳐지지 않지만 이미지 내에 존재하는 픽셀을 x 처리한다면 아래와 같은 그림이 되겠죠?

그림2

따라서 이렇게 단순히 이미지를 포개고 픽셀 단위로 일치하는지 일치하는지 여부를 확인하다면, 정확한 이미지의 구분이 어려울 것입니다.

따라서 우리는 이미지 전체가 아닌 부분의 패턴을 이용합니다!

 

먼저, 각 이미지의 부분들을 보았을 때 패턴이 일치하는 부분이 존재한다면 특정 class 에 존재할 수 있는 작은 특정 패턴들을 정의하고, 그 패턴들이 주어진 이미지 상에 있는지를 판단합니다. 위의 그림1 처럼 말이죠.

 

따라서 CNN 에서는 filter (혹은 Kernel) 이라는 개념이 존재합니다. 작은 크기의 filter라는 이름의 특정 패턴이 존재하는(이미지의 부분적인 패턴) 창을 이용해 이미지 자체를 훑어가면서 해당 패턴이 존재하는지 존재하지 않는지를 확인하는 것이죠.

이 때, 패턴이 존재하는지 존재하지 않는지 여부를 확인하기 위해 사용하는 연산이 바로 Convolution 연산입니다.

 

filter convolution

 

예를 들어, 위의 그림처럼 왼쪽의 9*9 형태의 filter가 존재한다고 할 때, 이 이미지는 원본 이미지를 훑어가면서 해당 패턴이 그 특정 부분에 존재하는지를 연산합니다. 패치의 값과 이미지에서 같은 위치에 존재하는 픽셀값을 서로 곱함으로써 각 픽셀별로 패치와 매칭이 됐는지, 안됐는지를 두 픽셀간의 곱셈으로 나타내는 것이죠. 또 이 곱셈들을 모두 합하고 해당 필터의 크기 (패치의 크기)를 나누면 패치와 매칭되는 정도를 정량적으로 나타낼 수 있습니다.

 

그렇게 정량적인 결과를 나타낸 것을 우리는 Activation map, (활성화 지도)라고 합니다.

Activation map

 

이렇게 패치를 주어진 입력 이미지에 가능한 모든 위치에 오버랩을 시켜서 매칭되는 정도를 얻게 되면 결과 이미지(Activation map)가 되는 것이죠.

 

특정 이미지 패턴을 1개의 filter(=kernel)이라고 했을 때, 각 패턴마다 원본 이미지에 대한 Convolution 연산을 구하면 filter 개수만큼의 activation map을 구할 수 있습니다. (#filter = #activation map)

Activation map

해당 필터에 대한 Activation map 을 구하고 그 최종 결과값을 모두 concate 하여 최종 Activation map 을 뽑아내는 것이죠

3 Channel Activation map

 

컬러 이미지의 특성상, RGB Channel 의 3개 채널 이미지가 존재한다고 가정할 때, 다음과 같이 3 Channel Activation map 을 그려보는 과정도 생각할 수 있습니다. 입력 채널 각각에 들어가게 될 이미지 패치들이 하나의 Convolution filter를 이루는 것이죠.

 

Convolution Layer

 

Feature map Output size

 

Feature map의 출력 크기는 아래 공식을 이용하여 계산할 수 있습니다. 

 

Convolution layer output size

  • $W_{out}$과 $H_{out}$은 각각 출력 특성 맵의 너비와 높이입니다.
  • $W_{in}$과 $H_{in}$은 각각 입력 특성 맵의 너비와 높이입니다.
  • $F$는 필터(커널)의 크기입니다. 필터가 정사각형이 아닌 경우, 각각의 차원에 대해 다른 값을 사용해야 할 수 있습니다.
  • $P$는 패딩의 크기입니다. 패딩은 입력 특성 맵의 가장자리에 추가된 0의 레이어로, 종종 입력 데이터의 공간적 크기를 유지하기 위해 사용됩니다.
  • $S$는 stride의 크기로, 필터가 입력 특성 맵을 통해 이동하는 간격을 의미합니다.

 

여기서 의미하는 padding, stride 에 대해 설명해보겠습니다.

 

Padding

 

먼저, padding 입니다.

 

padding

 

 다음과 같이 convolution 을 진행할 때, filter는 특정 크기의 사이즈를 가지고 있습니다. (이미지 상 2*2가 되겠죠?) 하지만 이 filter를 이용해서 원본 이미지를 훑다 보면 특정 부분은 더 많은 횟수로 훑게 되고, 가장자리 부분은 오직 한번만 훑게 된다는 단점이 존재합니다. 공정하게 정보 전달이 안되겠죠. 따라서 원본 이미지 겉 부분으로 0 혹은 1로만 이뤄진 padding을 씌워주는 것 입니다. 그럼 filter 가 움직이게 되더라도 원본 이미지의 가장자리 부분을 2번 이상 훑게 되는 결과를 얻을 수 있게됩니다.

 

 

Stride

 

 Stride는 filter가 어느정도 간격으로 이미지를 훑을 것인지를 나타내는 지표입니다.

stride

다음 이미지 처럼, stride = 1인 경우, 픽셀 1개의 간격으로 filter 가 이동하게 됩니다. 그럼 총 7*7의 raw 이미지를 훑었을 때, 5*5의 feature map을 얻을 수 있게 되는 것이죠, stride =2 인 경우, 픽셀 2개의 간격으로 filter가 이동하며 최종적으로 3*3의 feature map을 얻게 됩니다.

 

 

Pooling layer

 

CNN 을 보면 pooling layer라는 것이 존재합니다. Activation map 을 뽑아낸 것처럼 패치와 이미지를 합치고 필터 사이즈 내에서 존재하는 이미지의 최댓값을 골라내는 과정을 수행하는 Layer를 Pooling Layer라고 합니다.

 

 그 중의 가장 대표적인 Max pooling 에 대해서 설명하겠습니다. 

 

max pooling

 

다음과 같은 이미지처럼, 원본 이미지와 filter를 겹쳤을 때, filter size 내에서 가장 큰 값을 갖는 결과물만 골라 feature 뽑아내는 것 입니다.

 

 이렇게 Max pooling을 뽑아내게 되면 일종의 요약괒어을 거쳐 원래 값에서 최대 값만을 뽑아내기 때문에 이미지의 주된 특징을 추출해내면서 가로, 세로 사이즈를 반으로 줄여주는 효과를 지니게 되는 것이죠.

 

  • 전체적으로는 이미지 사이즈가 반으로 줄되, Activation map 에서의 특징 추출은 그대로 가져올 수 있게 됨 (대략적인 위치로)
  • Max pooling 은 이미지의 채널별로 따로따로 진행해주게 됨

 

따라서 전체적인 CNN 구조를 살펴보면, CN → Max pooling → CN → Max pooling 과정이 연달아 일어나기 때문에 최종적으로는 이미지의 특징을 간직한 채로 작은 이미지 size로 줄어들게 됩니다.

 

FC Layer

 

 이렇게 과정들을 거치면 앞서 말했듯 Activation map 의 경우 Matrix의 형태로 나타나지기 때문에 FC Layer(Fully connected Layer)를 거치기 위하여 한 줄 짜리 Vector의 형태로 펴주는 과정을 마지막으로 거치게 됩니다.

Fully connected layer + softmax

 

Fully connected layer를 거침으로써 output node를 위의 그림과 같이 생성하고 'X'라는 output 이미지에 대한 Score, 'O'라는 output 이미지에 대한 score를 따로 만들어 FC layer를 거친 가중치를 계산하여 이미지를 분류하거나 구분할 수 있는 CNN 모델을 구축하는 것 입니다! (즉, Fully connected layer = multi-layer perceptron의 역할을 하게 됩니다.)

 

최종적으로, 결과로 추출된 값에 대하여 정답값에는 최대한 1이 나오도록, 오답에는 최대한 0이 나오도록 하는 Binary Cross-Entropy loss나 MSE loss 등을 이용하여 Backpropagation을 진행해서 가중치를 업데이트를 하는 과정을 거쳐 모델을 학습하고 filter의 coefficient를 최종적으로 도출할 수 있습니다!

Convolution Neural Network sequence

 

전체적으로 보면 위와 같은 과정을 거치게 되는 것이죠.

 

 

CNN에서의 Hyper Parameter

따라서 CNN architecture에서의 중요한 Hyper Parameter는 다음과 같은 것들을 꼽을 수 있습니다.

 

  • Convolution
    • Number of filters
    • Size of filters
  • Pooling
    • Window size
    • Window stride
  • Fully Connected
    • Number of layers
    • Number of Neurons

 

위와 같은 Hyper parameter들을 사전에 잘 정의해 둔 Architecture들이 존재합니다. 

아래와 같은 모델들을 하나씩 살펴보며 CNN 에 대해 더 구체적으로 공부해본다면 CV task를 더 잘 이해하는데 도움이 되지 않을까 싶습니다🤗

 


CNN Architecture Models

  • AlexNet → Image Classification 대회, ImageNet 대회 (2012)
  • VGGNet
    • 각각의 Convolution layer에서 사용하는 Convolution filter의 가로, 세로 size를 무조건 3*3으로 설정하였음
    • 대각선 패턴이나 x자 패턴을 정의할 수 있음.
    • 단순한 패턴이지만, Layer를 깊이 쌓음으로서 단순한 패턴만으로 나타날 수 있는 단점을 커버할 수 있음
  • GoogleNet
  • ResNet
    • Layer 수를 많이 늘림에도 불구하고 학습을 용이하게 할 수 있음.
    • Residual Network를 이용한 것임
    • 뭔가 필요할 땐 건너뛸 수 있도록, 혹은 Skip 할 수 있도록 Skip Connection을 진행함
    • Output 에 Layer의 입력으로 주었던 Input을 다시 더해주는 방식으로 최종 Output을 구함
    • Skip 하고 싶으면 다음 함수의 Parameter를 0으로 놓고, 이전 Output 값을 더해주므로, 결국 이전의 Output 결과만 남게 됨
    • 따라서 Layer를 많이 늘리고 깊게 늘려서 학습을 진행해도 효과적으로 쓸 수 있음.