본문 바로가기

딥러닝

11. 컨볼루션 신경망, CNN (Convolution neural network)

이 포스트는 Do it 딥러닝 교과서 (윤성진 저)를 참고하여 만들어졌음!

 

 

 

 

CNN의 역사

 

앞서 배운 MLP(Multi layer perceptron)로 이미지 데이터도 학습할 수 있을까?

$\rightarrow$ 가능하다. 비록 성능은 떨어지겠지만 input data의 크기가 작고 특징이 적은 경우(MNIST 숫자 손글씨 이미지 등) 에 학습이 잘 된다. 

 

pytorch-image-classification/1_mlp.ipynb at master · bentrevett/pytorch-image-classification · GitHub

 

 

 

하지만 Image data를 MLP에 입력하면, 예를들어 위 그림에서 2라는 숫자가 1차원 벡터로 flatten된 후 입력되기 때문에 숫자 2라는 형태를 유지할 수 없다. MLP를 이용해서는 Image data의 특징을 추출할 수가 없는 것이다. 더불어 이미지 데이터의 각 픽셀은 입력벡터의 각 차원이 되기 때문에 28x28 image에서 30x30 image로 크기를 늘리면 116차원 (900-784)이나 증가한다. 

 

Image data의 size가 30x30으로 굉장히 작을 때도 MLP를 사용하면 차원이 900개이므로 이를 학습하기 위해서 굉장히 많은 신경망 파라미터가 필요하다. Image size가 조금만 증가해도 신경망이 매우 커져야 한다는 것이다. 따라서 Image를 MLP로 처리하는 것은 영 좋은 방법이 아닌 것 같다.

 

 

 

 

 

 

이미지 처리를 위해선 MLP가 아닌 다른 효율적인 방법이 필요하다. 1959년 신경 생리학자 데이비드 허블과 토르스텐 닐스 비셀이 동물 시각 피질 기능에 대한 연구를 발표하였다. 이들이 발표한 시각시스템의 계층 구조를 모델링하여 1979년 쿠니히코 후쿠시마는 네오코니트론을 제안하였다.

 

 

 

 

네오코그니트론은 1959년 발표된 동물의 신경 시각피질 모형을 본따 계층을 갖는 형태로 구성된다. 인간 뇌의 시각피질은 V1, V2, V4 계층을 거치며 수용영역을 점점 확장해가는 구조이다. 네오코그니트론도 이와 마찬가지로 하위 계층에서는 좁은 수용영역을 통해 이미지의 디테일한 특징을 파악하고, 상위 계층에서는 넓은 수용영역으로 이미지의 전반적인 특징을 학습한다. 또한 네오코그니트론은 개발당시 비지도 학습이 결합한 알고리즘이었다.

 

 

 

1998년 프랑스의 컴퓨터 과학자 얀 르쿤은 네오코그니트론에 역전파 알고리즘을 학습 알고리즘으로 채택한 CNN을 제안하였다. (역전파 알고리즘 또한 얀 르쿤이 1985년에 제안한 알고리즘이다.) 얀 르쿤은 최초의 CNN 모델로 LeNet-5를 제안하였고, 이는 convolution layer, pooling layer로 구성되었다.

 

 

 

 

 

 

CNN의 구조

{"originWidth":1400,"originHeight":626,"style":"alignCenter","width":579,"height":259,"caption":"What is Convolutional Neural Network — CNN (Deep Learning)

 

일반적으로 CNN 모델은 LeNet-5와 같이 convolution layer와 sub-sampling layer가 반복되는 구조로 구성된다. 여기서 sub-sampling은 pooling 등의 연산을 통해 입력된 이미지 크기를 줄이는 역할을 수행한다.

CNN에서 수용영역이란 어떤 뉴런에서 전달받은 입력 이미지의 영역을 의미한다. 계층이 깊어질수록 입력 이미지의 더 많은 부분을 수용하게 되므로, CNN 모델은 convolution layer와 sub-sampling layer가 반복될수록 수용영역이 점점 넓어지는 구조이다. 따라서 초반 layer들은 작은 영역의 특징을, 후반 layer들은 넓은 영역의 특징을 인식한다.

 

 

 

 

 

컨볼루션 연산

두 연속함수 $f$와 $g$가 있을 때, 일반적으로 컨볼루션 연산 다음을 나타낸다.$$(f*g)(t) \stackrel{\Delta}{=} \int_{-\infty}^{\infty}f(\tau) g(t-\tau) d\tau $$

 

$g(\tau)$라는 함수가 있을 때 이를 $\tau$에 대해 반전시킨 $g(-\tau)$를 $f(\tau)$위로 슬라이딩하며 적분하는 것이라고 생각할 수 있다.

 

 

교차상관 연산

컨볼루션 연산과 매우 비슷한 교차상관 연관이 존재하는데, 이는 수식으로 다음과 같이 표현된다.

$$(f*g)(t) \stackrel{\Delta}{=} \int_{-\infty}^{\infty}f(\tau) g(t+\tau) d\tau $$

교차상관에서는 $g(\tau)$를 $\tau$에 대해 반전시키지 않았다는 것이 컨볼루션 연산과의 유일한 차이점이다. CNN 신경망에서 컨볼루션 필터는 컨볼루션 연산과 교차상관 연산 중 어느 것을 수행해도 학습이 가능하기 때문에 연산과 해석이 쉬운 교차상관 연산을 사용한다.

 

 

 

 

 

컨볼루션 신경망에서의 컨볼루션 연산 (실제로는 교차상관 연산)

컨볼루션 신경망은 입력된 이미지의 특징을 추출하기 위해 컨볼루션 필터를 사용한다. 위에서 초반 layer의 뉴런들 (여기서는 필터)은 좁은 수용영역의 특징을, 후반 layer의 뉴런들은 넓은 수용영역의 특징을 학습한다고 했다. 즉 입력 이미지의 특징을 학습하는 주체가 바로 컨볼루션 필터의 뉴런이므로, 이미지가 가진 특징의 복잡도에 따라 컨볼루션 필터의 개수를 조정해야 한다.

입력 이미지가 복잡한 특징을 많이 갖고있다면, 이를 학습하기 위해 많은 수의 컨볼루션 필터가 필요하다. 반면 입력 이미지가 단순한 경우 적은 컨볼루션 필터만으로도 충분히 학습이 가능하다.

 

따라서 입력 이미지의 특징 분포를 파악하고 그에 맞춘 적절한 깊이의 네트워크를 설계할 것이 요구된다.

 

 

 

 

#006 CNN Convolution On RGB Images - Master Data Science (datahacker.rs)

 

컨볼루션 필터는 일반적으로 정사각형으로 정의한다. 큰 필터를 사용하면 적은 계층으로도 넓은 수용영역을 학습할 수 있다. 작은 필터를 많은 계층에 걸쳐 사용하면 적은 수용영역을 점점 넓혀가며 특징을 학습할 수 있다. 일반적으로 3, 5, 7 size의 컨볼루션 필터를 사용한다.

 

 

 

컨볼루션 연산은 입력의 모든 채널에 대해 한꺼번에 가중 합산을 수행한다. 위 그림에서 입력의 채널이 3이므로 이와 컨볼루션 연산을 수행하는 filter의 채널 또한 3이다. 입력되는 이미지의 채널과 filter의 채널이 같아야만 연산이 수행된다.

 

 

 

 

 

컨볼루션 필터의 뉴런

위 그림에서 $3\times 3\times 3$ size의 컨볼루션 필터의 뉴런은 바로 각 필터의 가중치이다. 따라서 해당 필터는 $3 \times 3 \times 3 = 27$개의 뉴런을 갖는다. 이 filter를 이용하여 입력 이미지의 모든 영역을 슬라이딩하며 가중 합산을 수행하므로 입력 이미지는 해당 filter(뉴런, 가중치)를 공유한다고 생각할 수 있다.

 

 

 

또한 컨볼루션 필터는 입력 이미지와 필터가 겹쳐지는 영역에서만 연산이 수행되므로 이를 지역연결(local connectivity) 특성이라고 한다.

 

 

 

 

 

액티베이션 맵 (Activation map)

한 계층에 입력된 이미지에 컨볼루션 연산을 수행한 후 출력된 결과를 activation map이라고 한다. 컨볼루션 연산을 수행한 결과는 MLP와는 다르게 사각형 이미지(map) 형태로 표현되므로 이를 특별히 액티베이션 맵이라고 칭한다.

 

또한 이미지에 컨볼루션 연산을 수행한 결과는 곧 해당 이미지의 특징을 추출한 결과이기 때문에 feature map이라고도 한다.

 

 

https://datahacker.rs/convolution-rgb-image/

 

액티베이션 맵의 채널 수는 컨볼루션 필터의 개수와 같다. 위 그림에서 입력 이미지에 대해 2개의 컨볼루션 필터를 적용하여 $4\times 4$ size의 activation map을 두 개 출력했다. 이때 최종 출력은 이 두 개의 activation map을 쌓아올려 완성된다. 만일 100개의 컨볼루션 필터를 적용했다면 activation map의 채널은 100이 되어 $4 \times 4 \times 100$ size의 출력을 얻게 된다.

 

 

 

이때 여러개의 activation map을 쌓아올리기 위해서 해당 activation map들의 크기가 전부 동일해야 한다. 따라서 한 계층에서 사용되는 컨볼루션 필터의 size는 전부 동일해야 한다. (그래야만 서로 같은 크기의 activation map을 산출할 수 있다.)

 

 

 

 

 

Sub-sampling

sub-sampling이란 데이터를 낮은 빈도로 샘플링(추출)하는 것으로, 이미지 데이터에 대해 이를 수행하면 이는 곧 이미지 크기를 줄이는 연산이 되므로 down-sampling이라고도 부른다. sub-sampling은 CNN의 가장 초창기 모델인 LeNet-5에서부터 pooling 연산의 형태로 사용되어왔다. pooling 외에 stride=2를 설정하여 이미지 크기를 절반으로 줄이는 방법도 있다.

 

 

 

 

 

Pooling

CNN에서 사용하는 풀링은 일반적으로 max, average pooling이지만 min, 가중합산, $L_2$ norm 풀링도 사용할 수 있다.

가장 많이 사용되는 두 풀링의 예시이다. 2x2 pooling을 수행하면 이미지의 가로, 세로크기가 각각 절반으로 줄어든다. max pooling은 2x2 영역에 대하여 가장 큰 값을 추출하고, average pooling은 해당 영역의 평균값을 추출한다. 따라서 max pooling은 이미지의 크기를 줄임과 동시에 두드러지는 특성을 추출한다고 볼 수 있고, average pooling은 이미지 크기를 줄이면서 이미지의 전반적인 특징을 반영한다고 볼 수 있다.

 

또한 pooling은 정해진 요약 통계량 (max, min, average 등)만을 구하는 역할이므로 weights를 가지지 않으며 따라서 학습되지 않는다.

 

 

풀링필터는 위치불변성이라는 중요한 성질을 갖는다.

입력이 이동해도 출력이 바뀌지 않는 성질을 위치불변성이라고 한다. 예를들어 2x2 max pooling을 적용할 때 a라는 최대값이 2x2 영역 안에서 움직여도 여전히 max pooling을 적용한 결과는 a이다. 즉 pooling의 수용영역 안에서 이미지의 특징이 이동해도 여전히 pooling은 이것을 캐치할 수 있다.

 

pooling이 2x2를 바라보고 있다고 해서 수용영역이 2x2인 것은 아니다. 컨볼루션 필터를 여러번 거치면 수용영역이 계속 증가한다. 따라서 컨볼루션 필터를 여러번 거친 후 적용되는 pooling 역시 해당 수용영역 전체를 바라보고 있다. 따라서 모델 후반쯤에서 사용되는 pooling은 경우에 따라 50x50 이상의 영역을 바라보고 있을수도 있다.

 

일반적으로 CNN 신경망을 구성할 때 2~3번의 컨볼루션 연산을 거치고 pooling 연산을 수행하는 것을 여러 번 반복한다. 따라서 계층이 깊어질수록 뉴런의 수용 영역은 계속 넓어지며, sub-sampling을 하면 수용영역이 더 빠르게 넓어진다. (2x2 max pooling을 수행하면 2x2 영역의 픽셀이 담당하던 수용영역을 한 픽셀에 담아버리므로 수용영역이 매우 커진다.)

 

 

 

 

 

스트라이드 (stride)

Make Your Own Neural Network: Calculating the Output Size of Convolutions and Transpose Convolutions

컨볼루션 연산과 풀링연산을 수행할 때 필터의 슬라이딩 간격을 스트라이드(stride)라고 한다. 일반적으로 컨볼루션 연산에서는 stride=1, 2x2 pooling에서는 stride=2로 설정한다. 하지만 간혹 stride=2를 갖는 컨볼루션 연산을 수행하여 sub-sampling 효과를 얻거나, stride가 2보다 큰 pooling을 수행하며 이미지 사이즈를 대폭 감소시킬 수도 있다.

 

위 그림의 경우 stride=1로 컨볼루션 연산을 수행하면 activation map은 $4 \times 4$ size를 갖는다. 하지만 stride=2로 연산을 수행하면 오른쪽과 같이 $2 \times 2$ size가 출력된다.

 

 

 

Stride=$S$를 가지고 컨볼루션 연산을 수행했을 때 activation map의 size는 다음과 식으로 계산할 수 있다.

$$O=\frac{N-F}{S} +1 $$

$$N: \text{입력 데이터 크기}, F: \text{컨볼루션 필터 크기}, S: \text{스트라이드}, O:\text{출력 데이터 크기} $$

 

위 그림예시를 식에 적용하면 다음과 같다. 

$$ O=\frac{5-2}{2}+1 = 2.5 $$

이때 소숫점 단위의 size를 갖는것은 불가능하므로 위 연산은 항상 소숫점을 버린다. 따라서 $O=2$

 

만약 stride=3인 경우 출력 size는 다음과 같이 얻어진다.

$$ O=\frac{5-2}{3}=1 $$

 

 

 

 

패딩 (padding)

컨볼루션 연산은 입력되는 이미지 안에서 슬라이딩하며 이루어지므로 activation map은 입력 이미지보다 크기가 줄어든다. 여러번의 컨볼루션 연산과 pooling을 반복하다 보면 입력 이미지의 크기는 어느새 매우 작아져 더 이상 컨볼루션 연산을 할 수 없을 정도가 될 것이다. 

 

따라서 컨볼루션 연산을 더 많이 수행하기 위해서는 이미지 크기를 어느정도 유지해야 할 필요가 있으며, 우리는 이를 위해 Padding 기법을 사용한다. Padding은 이미지 데두리에 지정된 만큼의 픽셀을 추가하여 컨볼루션 연산 후에도 이미지 크기가 유지되도록 한다.

 

 

How Padding helps in CNN ? (numpyninja.com)

일반적으로 입력된 이미지의 테두리에 0을 추가하는 zero-padding을 수행한다. Padding을 사용하는 경우 출력이미지의 사이즈는 다음 식으로 구해진다.

 

$$O=\frac{(N+2 \times P) -F}{S}+1 $$

$$N: \text{입력 데이터 크기}, P: \text{패딩}, F:\text{컨볼루션 필터 크기}, S:\text{스트라이드}, O:\text{출력 데이터 크기} $$

 

예를 들어 6x6 image에 3x3 convolution filter를 적용한다고 하자. 이때 padding=1, stride=1이라면 다음 출력 size를 얻는다.

$$ O=\frac{(6+2)-3}{1}+1 = 6 $$

입력 size와 출력 size가 동일함을 확인할 수 있다. 따라서 padding을 활용하면 이미지 크기를 줄이지 않으면서 컨볼루션 연산을 수행할 수 있다.

 

 

 

 

수용영역 (Receptive field)

{"originWidth":1200,"originHeight":613,"style":"alignCenter","width":462,"height":236,"caption":"A guide to receptive field arithmetic for Convolutional Neural Networks

 

사실 CNN 처음 배울 때 수용영역에 대해 간략하게만 알고 넘어갔었는데, 다시 공부해보니 수용영역이 갖는 의미가 CNN 해석에 있어 굉장히 중요하다는 것을 체감한다.

위 그림에서 layer2의 한 픽셀은 layer1(입력 이미지)의 3x3 픽셀을 바라보고있다. 따라서 layer2의 수용영역은 3x3 (3)이다.

layer3의 한 픽셀은 layer2의 3x3 픽셀을 바라보고있다. 하지만 layer2의 각 픽셀은 layer1의 픽셀을 슬라이딩하며 얻어진 결과이므로 layer2의 인근 픽셀끼리는 중복되는 영역을 수용한다. 이를 잘 고려해서 계산하면 layer3의 수용영역은 5x5 (5)이다.

$\rightarrow$ 3x3 convolution을 수행하면 계층을 지날때마다 수용영역이 2씩 증가한다.

 

 

 

수용영역을 계산하기 위해 먼저 계층 $L$의 크기를 알 때 입력 데이터 크기를 계산해본다. padding이 없을 때 출력데이터 크기는 다음과 같이 얻어짐을 확인했다.

 

$$O=\frac{N-F}{S}+1 $$

 

위 식을 입력 이미지 크기 $N$에 대해 정리하면 다음과 같이 입력 size $N$과 출력 size $O$ 사이의 관계식을 얻는다.

 

$$N=(O-1) \times S + F $$

 

이때 $l$계층의 입력 $N$은 $l-1$계층의 출력으로 볼 수 있으므로 다음과 같은 표현이 가능하다.

 

$$\begin{align}  O_{L-1}&=(O_L -1) \times S + F \\ O_{L-2} &= (O_{L-1} -1) \times S + F \\ O_{L-3} &= (O_{L-2} -1) \times S + F\\  \cdots \\ N&=(O_1-1)  \times S +F \end{align} $$

 

점화식을 전개하면 다음을 얻는다.

 

$$\begin{align} O_{L-1}&=(O_L-1) \times S + F \\ O_{L-2} &= (O_{L-1} -1)\times S +F \\ &=((O_L-1)\times S +F -1) \times S + F \\ &=(O_L-1)\times S^2 +(F-1)\times S +F \\ O_{L-3} &=(O_{L-2}-1)\times S +F \\ &=((O_L-1)\times S^2 + (F-1)\times S +F-1) \times S +F \\ &=(O_L-1) \times S^3 + (F-1) \times S^2 + (F-1)\times S +F \\ \cdots \\ N&=(O_L-1)\times S^L + (F-1) \times S^{L-1} + \cdots+(F-1) \times S^1+F  \end{align} $$

 

따라서 ($F$ size의 convolution만 수행했다고 했을 때) $L$번째 layer 출력 크기가 $O_L$인 경우 입력 size $N$은 다음과 같이 얻어진다.

 

$$N=(O_L-1)\times S^L + (F-1) \times S^{L-1} + \times + (F-1)\times S^1 + F $$

 

 이때 $O_L=1$으로 설정하면 $L$번째 layer의 수용영역을 계산할 수 있다. (수용영역은 계산하고자 하는 계층의 한 뉴런이 수용하는 입력데이터 크기를 의미하므로 $O_L=1$으로 설정)

 

$$L\text{번째 계층 뉴런의 수용 영역} = (F-1)\times S^{L-1} + \cdots + (F-1) \times S^1 + F $$

 

 

이제 위 그림에 대해 수용영역을 구해보자. 위 예시는 $F=3, S=1$이므로 $L=2$에서의 수용영역은 다음과 같이 얻어진다.

$$\begin{align} \text{2nd layer's receptive field} &=(F-1) \times S^1 +F \\ &=(3-1) \times 1 + 3 \\ &=5 \end{align} $$

 

세 번째 계층 $L=3$에서의 수용영역도 구해보자.

$$\begin{align} \text{3rd layer's receptive field} &=(F-1)\times S^2+ (F-1) \times S^1 +F \\ &=(3-1) \times 1 + (3-1)\times 1 +3 \\ &=7 \end{align}$$

 

즉 Stride=1인 경우 한 계층을 지날때마다 수용영역은 $(F-1)$만큼 커진다. (동일한 size의 컨볼루션 필터를 적용한다는 가정) 따라서 3x3 size의 convolution filter를 적용하면 매 계층마다 2씩 수용영역이 넓어진다. stride를 크게 잡으면 수용영역은 매우 빠르게 넓어진다. (그만큼 이미지 크기가 빠르게 줄어들기 때문에 사용에 주의가 필요하다.)

 

 

 

 

희소연결

MLP와 비교했을 때 컨볼루션 신경망 CNN은 이미지의 패턴과 특징을 잘 추출할 수 있다는 장점이 있다. 이 외에도 파라미터 개수상에서 장점이 존재한다.

컨볼루션 필터는 입력데이터와 필터가 겹치는 영역에서만 연산이 이루어지고 나머지 부분에서는 연산을 수행하지 않는데, 이것을 희소연결이라고 부른다. 더하여 동일한 필터로 입력 데이터 전체에 대해 연산이 수행되므로 한 계층의 뉴런은 파라미터를 공유한다. 쉽게 말하면 사진 내에 사람 얼굴이 어느 위치에 존재하던 간에 컨볼루션 필터는 사람 얼굴을 추출해낼 수 있다.

 

 

 

뉴런이 $n$개이고 입력이 $m$개일 때 fully connected 파라미터 수 $rightarrow$ $O(m \times n)$

 

 

뉴런이 $n$개이고 한 뉴런당 입력되는 연결이 $k$개일 때 (그림에서는 3개) 파라미터 수 $rightarrow$ $O(k \times n)$

 

 

희소연결 특성을 가지는 뉴런을 각 입력마다 공유하여 사용할 때 파라미터 수 $rightarrow$ $O(k)$

컨볼루션 연산에서 한 커널을 이용하여 전체 이미지를 커버하는 것을 떠올리면 이해가 쉽다.

 

 

 

즉 기존의 fully connected에 비해 CNN 신경망을 사용하면 연산량이 크게 감소한다.

'딥러닝' 카테고리의 다른 글

12. RNN (Recurrent Neural Network) 이론  (0) 2023.10.06
VGG net 논문리뷰 + 실습  (0) 2023.10.04
9. 초기화 Initialization  (0) 2023.09.21
8. 최적화 Optimization  (0) 2023.09.20
7. 손실함수 Loss function  (0) 2023.09.15