Reference
https://iai.postech.ac.kr/teaching/machine-learning
https://iai.postech.ac.kr/teaching/deep-learning
위 링크의 강의 내용에 기반하여 중요하거나 이해가 어려웠던 부분들을 정리하여 작성하였고,
모든 강의 슬라이드의 인용은 저작권자의 허가를 받았습니다.
또한, 모든 내용은 아래 Notion에서 더 편하게 확인하실 수 있습니다.
>>노션 링크<<
Keywords
- CNN - Motivation
- CNN - Structure
- Filter, Kernel, Channel
- Padding, Stride, ReLU, Pooling
Motivation of CNN
우선 어떤 Motivation으로 CNN이 고안되게 되었는지 부터 확인하자.
위의 사진들에서 새가 존재하는 지, 존재하지 않는 지를 Classification하는 NN을 구성하려고 하는 것이다.
(그러한 NN을 학습시키면, 새로운 이미지를 대입하여 그 이미지에 새가 존재하는 지를 확인할 수 있는 classifier가 된다는 것.)
이것을 물론 기본적인 ANN 구조를 통해, 이미지를 1D로 flatten시킨 후 학습시켜, weight를 update시키면서 학습시킬 수 있을 것이다.
그러나 이러한 방법은, Input이 “이미지”인 특성을 최대로 활용하지 못하는, 최선의 방법이 아니다.
input을 flatten하여 학습시키는 순간, 이 ‘이미지’의 각각의 픽셀의 특성이 사라지게 된다.
이게 무슨 말이냐 하면, ‘이미지’라는 data는 기본적으로 가로, 세로로 연결되어 있다는 정보를 포함하고 있고(2D), flatten하는 순간 세로로 인접한 픽셀이라는 정보 자체가 사라진다는 것을 쉽게 생각할 수 있다.
여기서 말한 가로, 세로의 픽셀 인접 정보 이외에도 (물론 대각선도), flatten하여 ANN을 통해 학습함으로써 잃게 되는 정보가 많을 것이다.
그래서 이러한 FCN(일반적인 ANN)은, input data의 flatten을 거치기 때문에, “공간적인 정보”를 활용하지 못한다는 단점이 있다.
(또한, Fully-Connected이기 때문에, Parameter의 개수가 매우 많아 학습이 느리거나 하는 단점 또한 존재한다.)
→ 그래서 이러한 공간적인 구조 정보를 NN에서 활용하는 방법이, Flatten을 하는 것이 아닌, Convolution을 활용하는 방법 - CNN인 것이다!
위에서의 예시로 돌아가 보자.
위에서의 예시였던 새에 대한 object detection 문제에서, 새와 같은 object는 이미지 전체에 걸쳐 있기 보다는, 이미지의 일부 부분에 위치에 있는 경향이 대부분일 것이다.
그렇기 때문에, Fully-connected된 구조를 사용하는 것(전체 위치에 mask를 씌우는 것) 보다는, 각각의 local에 local한 mask를 사용할 수 있을 것이다.. (Locally-connected)
그리고 여기서, detect하는 object는 항상 같은 object이기 때문에, 모든 local에서 동일한 mask를 사용해도 된다. (weight sharing)
weight sharing을 통해 모든 곳에서 같은 mask(kernel)을 사용하므로, parameter의 개수가 현저히 적어진다.
이렇게 최종적으로 convolution 과정과 동일하게, 같은 local한 mask(kernel)을 가지고 shifting을 하여 object를 detect해낼 수 있다는 것을 학습하였다.
이제 남은 것은, 주어진 data를 가지고 이러한 kernel의 weight들을 학습하는 일 뿐이다.
결국 CNN은, FCN에서 weight sharing, local connectivity와 같은 특성을 통해 parameter를 줄이고 node간의 연결을 줄여, 학습이 훨씬 쉬워진다. (물론, 위의 모든 설명은 input data가 2D의 image라는 특성을 가정하고 설명된다.)
Structure of CNN - Multi-Filter(Kernel), Channel, Shape
우선 위와 같이, CNN 구조에서 하나의 input에 대해 여러 개의 kernel을 적용하여 output을 낼 수 있다는 것을 짚고 넘어가자.
하나의 kernel을 통해 하나의 feature에 대한 정보를 뽑아낼 수 있으므로, 한 이미지에서 여러 개의 feature에 대한 정보를 얻기 위해서는 당연히 여러 개의 kernel을 적용해야 하는 것이다.
예를 들어, 위의 F1 kernel에서는 smoothing을 하는 역할을 수행하고, F2 kernel에서는 edge detection을 하는 역할을 수행한다고 하자. 두 kernel을 하나의 input image에 적용하게 되면, 각각의 kernel이 적용되어, 그 각각의 feature에 대한 정보가 담긴 2-dimension의 output이 나오게 된다.
이러한 output의 dimension을 channel이라 한다.
Multi-channel 2D convolution
위의 이미지처럼, 만약 Input의 channel이 다수라면, Input의 channel의 수에 맞춰 kernel이 3차원으로 확장된다. (kernel과 input의 channel은 동일해야 한다.)
물론 2D convolution과 동일한 방식으로, kernel이라는 3차원 블록을 그대로 shifting하며 elementwise multiply하면 되는 것이다. (만약 커널이 3x3x3의 크기라면, 그 27개의 원소 각각 input과 곱하여 모두 더해서, 하나의 output이 되는 것이다 - 그림 참고)
kernel size는 receptive field라고도 부르며, 보통은 1, 3, 5, 7, 11의 크기를 가진다.
(1x1, 3x3, 5x5, 7x7, 11x11. channel의 수는 별개.)
물론 위의 그림과 같이 Input이 Multi-Channel이면서, 동시에 여러 개의 kernel을 사용할 수도 있다.
이 때 각 input, output의 channel과 width, height 크기와, kernel에 의한 parameter의 개수는 위와 같다.
parameter의 수를 계산할 때, 각 kernel마다 bias에 의해 kernel 수만큼 parameter가 추가된다는 것도 잘 확인하자.
(추후 Padding과 Stride에 대한 개념이 등장하므로, 여기에서 자세히 다루지 않겠다. 물론 위의 내용 자체도 직관적으로 이해하기에 어렵지 않다.)
(위의 내용의 요약이다)
Convolution을 수행할 때, channel 사이에서 shifting(swipe)하는 것이 아니다. 가로세로(row/col)로만 훑으며 convolution을 수행한다. 이를 통해, Convolution을 수행해도 signal의 구조가 보존된다는 것을 는 것을 명심하자.
1D는 1D signal로, 2D는 2D로 변환되며, input에서 이웃한 부분이 output에서도 여전히 이웃한 부분으로 남아 있다는 것. (앞에서 이야기한 ‘공간적 정보’ 가 유지된다.)
하나의 kernel(filter)로 convolution을 통해 나온 output(단일 channel)을 activation map이라 한다.
또한, output component에 영향을 미치는 input(input map)의 그 일부분을 receptive field라 한다. (filter가 거쳐갈 때 1회 계산 시 해당되는 그 공간. input에서 filter의 크기와 같은 그 공간.)
Structure of CNN - Padding, Stride, Pooling
Stride: convolution을 진행할 때, shifting 시 한 번에 이동하는 step size.
위에서까지는 stride=1인 convolution을 진행한 것.
stride가 클수록 output map의 크기가 줄어든다.
Padding: convolution 진행 시, Input의 테두리에 칸을 추가하여 진행하는 것.
위 그림처럼 5x5 input, 3x3 kernel일 때, 1칸의 padding을 추가하면 output 또한 5x5가 되어 크기를 그대로 유지할 수 있게 된다.
→ input-output의 크기를 일정하게 유지하고 싶을 때.
보통 Padding은 0으로 채워지게 된다. (Zero Padding)
Input shape, Kernel size와 Stride, Padding까지 고려하여, output shape가 결정된다.
하나의 Layer에서, Convolution을 거치고 난 후의 결과는 결국 Linear combination(선형결합)으로 이루어진 결과이다.
그렇기 때문에 Convolution 이후 비선형적인 activation function을 사용해야 하며, (CNN에서는) 하나의 Layer에서 convolution을 수행한 후 ReLU와 같은 비선형적 함수를 적용하게 된다.
(convolution 이후의 2D data에, 각각의 element에 대해 element-wise하게 각각 ReLU를 적용하는 것. 2D의 shape는 변하지 않음. 그 안의 각각의 숫자(원소)에 대해 ReLU를 적용한 결과가 도출되는 것이다.)
Pooling: sliding window를 통해, 각 특정 크기(filter)의 범위에서 가장 큰(max pooling) value를 뽑아내는 것. filter shifting 시 겹치는 부분이 없게 이동하며 pooling을 수행한다는 것에 주의하자.
물론, 최소값을 뽑아내는 min pooling이나, 평균값을 채택하는 average pooling도 가능하다. 상황에 맞게 사용하게 되는 것.
위의 그림과 같이 Pooling을 수행하게 되면 dimension이 감소하고 공간적 resolution(해상도)가 줄어들어, 더욱 빠른 계산을 수행할 수 있다. 이 과정에서, 공간적인 정보는 어느 정도 보존된다.
위의 두 그림처럼, Input이 어느 정도 달라져도, 큰 기조만 같다면 Max pooling을 수행하였을 때 Output이 동일한 것을 확인할 수 있다.
이렇게 pooling을 통해 input의 민감한 변화에 대해 어느 정도 generalize를 수행할 수 있다.
Multi-channel에서의 pooling에 대해.
width/height에 대해서만, 그리고 각 channel에 대해 위 그림과 같이 pooling을 수행한다는 것을 확인하자.
Pooling을 수행해도 Input-Output의 channel은 보존된다.
그래서 결과적으로, 위에서 배운 것들을 종합하여,
Convolution을 수행하고 → non-linear activation function을 적용하고 → Pooling을 수행하는 것까지.
CNN에서는 이를 하나의 Convolutional Layer Block으로 간주한다.
클래식한 Convolutional Neural Network의 구조는,
Input에 대해 위와 같은 Convolutional Layer Block을 여러 개 거친 후,
마지막에 Fully Connnected layer를 거치고, Softmax를 적용하여 Output을 도출한다.
이 구조에서, Convolutional Layer Block을 거치는 부분에서 Feature extraction을 수행하는 것이고,
마지막에 Flatten-Fully Connnected-Softmax를 거치는 부분이 최종적으로 Classification을 수행한다.
최종적으로 Cross-Entropy loss를 이용해 Backpropagation으로 학습을 진행하게 된다.