본문 바로가기
  • Deep dive into Learning
  • Deep dive into Optimization
  • Deep dive into Deep Learning
Deep dive into Deep learning

Deep dive into Deep learning part 13. CNN - Updated

by Sapiens_Nam 2023. 4. 23.

"모바일 앱 환경에서는 latex 수식이 깨져 나타나므로, 가급적 웹 환경에서 봐주시길 바랍니다."

 

 

오늘부터는 CNN에 대해 이야기를 해보고자 한다.

 

먼저 CNN의 역사에 대해 간단하게 이야기해볼까 한다.

 

CNN history time graph

 

첫 시작은 1989년이지만 너무 오래되었고, 실질적으로 CNN의 시작은 LeNet으로 여겨진다.

LeNet Architecture

 

LeNet은 Yann Lecun (현재 메타 AI 연구원)의 팀이 개발한 모델이며, 그의 이름을 따서 LeNet으로 이름을 지었다.

그는 현재도 딥러닝의 4대 천왕중 한 명이라 불리우는 인물이며, 컴퓨터 과학계의 노벨상으로 불리우는 튜링상을 수상한 인물이다.

딥러닝 4대 천왕에 대한 이야기는 나중에 시간이 되면 해보도록 하자.

(4대 천왕이라는 표현은 필자가 만든 표현이 아니라 실제로 쓰이는 표현이다..)

 

LeNet이 나온 이후 한동안 CNN에 대해서 큼지막한 사건이 없다가 (사실 AI의 겨울이라 불리우는 시기였다.) 2012년 ImageNet 분류 대회에서 기존의 머신러닝 모델의 오차율을 대폭 낮춘 CNN 기반의 모델이 1등을 차지하였는데 이 모델이 AlexNet이다. 사실상 딥러닝의 부흥을 불러온 사건이라 할 수 있다. 이는 Deep learning의 대부이자 역시나 4대 천왕 중 한명인 제프리 힌튼 교수의 팀에서 만든 모델이다.

 

이후 CNN이 각광을 받기 시작하면서 GoogleNet, Inception, VGG등이 많이 나왔다.

이 모델들은 모두 CNN을 '깊게' (deep) 쌓으면서 모델의 성능을 향상시켰다. 물론, 여러 테크니컬한 요소들을 많이 사용했지만, 가장 기본이 되는 발전 방향은 결국 모델의 사이즈를 키우는 방향이었다.

하지만 이렇게 모델의 사이즈를 계속해서 키워나가는, 즉 layer를 계속 깊게 쌓아나가는 것에서 여러 문제가 발생했는데 그것을 보완한 모델이 ResNet이고 이 모델은 현재도 많이 쓰이는 기본 골격이 되는 모델이다. (backbone)

이 모델에서 제안한 가장 핵심적인 아이디어는 'Skip connection'이란 것으로 layer를 깊게 쌓아나가면서 생기는 gradient vanishing 등의 문제점을 해결하였다.

또한 이 모델은 동양인이 개발한 모델로서 당시까지는 계속 서양에서의 딥러닝 모델이 ImageNet 대회에서 1위를 차지하다가 처음으로 동양인이 개발한 모델이 1위를 차지한 의미도 있다. (He라는 중국인인데 현재 Microsoft에서 일하고 있다.)

 

이후 이 모델에서 제안한 Skip connection 아이디어를 살짝 변형하여 적용한 DenseNet, 모델의 폭 (width) 을 넓힌 ResNeXT, 모바일 디바이스 환경에서 사용하기 위한 EfficientNet 등이 나왔다.

그리고 결정적으로 위 history timegraph에는 나와있지 않지만 RNN 계열의 모델에서 기계 번역을 위해 나온 모델인 Transformer가 Vision task에 적용될 수 있도록 한 Vision Transformer (ViT)가 나왔다. 현재는 VIT가 backbone model로 활약하고 있다.

 

여기까지가 CNN의 간단한 역사이다.

 

자, 그러면 LeNet이란 모델에 대해서 살펴보도록 하자.

이 모델은 MNIST라는 숫자 손글씨 데이터를 처리하기 위해 나온 모델로서, MNIST는 0부터 9까지 숫자들이 손글씨로 써져 있는 흑백 데이터셋이다. 

MNIST

앞선 포스팅에서 2차원 이미지를 1차원 벡터로 변환하면서 ('flatten') 정보 손실이 발생하고, fully connected layer를 사용하면서 계산량이 상당히 크기 때문에 생기는 여러 문제들을 CNN이 해결해준다고 하였다.

즉, CNN은 이미지 텐서를 그대로 입력으로 받을 수 있는데 Convolution 연산을 수행하는 층을 겹겹이 쌓아서, 점점 복잡한 특징을 학습해나간다는 점은 Fully connected neural network와 다르지 않다.

처음에는 기본적인 feature들, 모서리, 직선 등응 학습하고 다음에는 좀 더 복잡한 패턴, 원, 직사각형 등을 학습하고 이어지는 층에서는 더 복잡한 패턴, 얼굴의 일부, 자동차 바퀴 등을 학습하는 방식등을 거쳐서 최종적으로 사진의 핵심이 되는 물체가 고양이인지 강아지인지, 자동차인지 등을 분류해내는 것이다. (이렇게 처음에는 단순한 특징을 학습하고, 점점 복잡한 특징/패턴을 학습하는 방식을 Hierarchy learning이라고도 부른다.)

즉, 결국 CNN에서는 특징을 추출하는 Convolution layer와 여기서 추출해낸 특징들을 분류하는 Fully connected layer로 구성되어져 있다. 이때 이지미자 Convolution layer를 지나면서 추출된 패턴/특징을 우리는 'Feature map'이라 하고, 이것이 1차원 벡터로 flatten 되면서 Fully connected layer를 지나 분류가 이뤄진다.

 

 

자, 그러면 합성곱 (Convolution)이란 무엇일까?

 

수학에서 말하는 합성곱은 두 함수를 인수로 하여, 새로운 함수를 만들어내는 과정이다. 엄밀하게 CNN에서의 합성곱 연산과 수학에서의 합성곱 연산은 조금 다르긴 한데, 편의상 이는 무시하도록 하자.

https://www.projectpro.io/article/introduction-to-convolutional-neural-networks-algorithm-architecture/560

 

 

앞선 글에서 이미지는 Height, Width, (Color)Channel를 축으로 갖는다고 하였다. 만약 흑백이미지면 Channel 의 개수는 1이고, 컬러이미지이면 Channel의 개수는 R/G/B로 3일 것이다.

위 예시를 보면 이미지는 Height의 값이 6, Width의 값이 6으로 총 36개의 픽셀값이 존재한다.

이것이 가운데 위치한 Filter (= Kernel)과 합성곱 연산이 이뤄지고, 그 결과 나오는 것이 Feature map이다.

 

이때 Filter에 있는 값들이 결국 가중치 (=weights, parameters)이고 이 값이 backpropagation 과정을 통해서 학습이 이뤄진다. 

CNN에서의 합성곱 연산은 상당히 간단하다. Filter가 Input image 위를 움직이면서 연산을 수행하고 그 결과값이 Feature map이 되는것인데, 연산 방법은 다음과 같다.

$9 * 1 + 2 * 0 + 5 * -1 + 6 * 1 + \cdots + 5 * 0 + 4 * -1$.

 

결국 Input의 픽셀값들과 Filter의 픽셀값들을 서로 곱해서 다 더한 값이다.

위에 예시에서는 Filter의 사이즈가 $3 * 3$행렬인데, $5 * 5, 2*2$등도 쓰이기도 하고, 특수한 목적으로 $1*1$ 필터도 많이 쓰인다. 또한 위의 예시에서는 Filter가 1개만 존재하는데 사실 Filter의 개수는 여러 개가 쓰일 수 있다.

그리고 이 Filter의 개수가 결국 출력의 깊이를 결정해낸다.

무슨 말인가 하면, Filter가 1개이면 이미지 1개와 연산이 수행되면 Feature map이 1개가 나올것이다.

하지만, Filter가 3개이면? 이미지 1개가 각각의 Filter들과 Convolution 연산을 수행하고 Feature map이 3개가 나올 것이다.

즉, Filter의 개수가 Feature map의 개수를 결정하는 것이고, Filter가 많을수록 Feature map의 개수가 많아지므로, 출력의 깊이가 더 깊어진다. Filter의 수를 늘리면 계산량은 증가하지만 그만큼 더 복잡한 패턴을 추출해낼 수 있게 된다.

 

그 다음, Stride란 '보폭'을 의미한다. 즉, Filter가 Input의 픽셀단위로 움직이면서 연산이 수행되는데, 이때 '얼마만큼 움직일지' 결정해주는 것이 Stride값이다. 만약 Stride가 1이면, 1칸씩 옆으로 움직이는 것이고 Stride가 2이면 2칸씩 옆으로 움직일 것이다.

 

마지막으로 Padding은 이미지의 테두리 부분에 픽셀값들을 추가해주는 것이다.

Zero Padding

 

위 예시를 보면 원래 $4*4$의 Height, Width를 가지는 image에 각 테두리에 0의 픽셀값들을 추가하여 $6 * 6$의 Height, Width를 만들어주었는데 이를 (Zero) padding이라고 한다.

이 작업을 수행해주는 이유는 Convolution layer 연산을 수행하면 image의 Height/width가 줄어들 수밖에 없는데 이 값을 보존해주기 위해서 Padding을 추가해주는 경우가 있다.

 

앞선 이미지 예시를 보면 $6*6$의 Image가 $3*3$의 Filter를 거쳐서 $4*4$의 Feature map이 나오게 되었다.

이처럼 Height/Width가 줄어드는 것을 막기 위해 Padding을 추가해주기도 한다.

 

그다음 CNN의 구조에서 등장하는 것 중 하나는 'Pooling layer'이다.

이 층이 존재하는 가장 큰 이유는 계산량을 줄이기 위함인데 이에 대해 살펴보도록 하자.

 

Pooling layer

 

$4 * 4$의 Height/Width를 가지는 image에서 $2 * 2$단위의 Pooling을 적용한 결과이다.

Max pooling은 결국 $2*2$ 단위의 픽셀값들 중에서 가장 큰 값들을 뽑아 그것만 남기는 방법이고, Average는 $2 * 2$ 단위의 픽셀값들의 평균을 계산하여 그 값으로 대체하는 방법이다.

 

즉, Pooling layer는 parameter가 존재하여 별도의 연산을 수행하는 것이 아닌, 단순히 'Downsampling', 즉, 이미지 또는 feature map의 크기를 줄이기 위함이다. 이는 계산량이 줄어드는 효과를 가져오게 된다.

 

이제 CNN의 기본적인 구조들을 살펴보았으므로 이를 바탕으로 AlexNet의 구조를 살펴보도록 하자.

AlexNet

 

위 예시를 보면 Input으로 $227 * 227 * 3$의 image가 들어옴을 알 수 있다. channel의 값이 3이므로 이는 컬러 이미지를 의미하며, 실제로 ImageNet dataset은 color image이다.

전체적인 구조를 보면 위의 그림과 (위의 그림이 짤린 것은 실제로 논문에서 이미지의 figure가 짤려 있기 때문이다.)

아래의 그림이 있는데 이는 GPU를 2개를 사용하여 병렬 연산을 수행하였기 때문이다.

$11 * 11 * 3$의 Filter 48개로 convolution연산을 수행하고 그 결과 나온 $55 * 55 * 48$의 Feature map에 대하여 Max pooling 연산을 수행한다. 이처럼 Convolution 연산과 Max pooling 연산을 반복적으로 수행하고, 마지막에는 Feature map을 flatten하여 Dense layer에 input으로 집어넣고 Fully connected 연산을 수행한다.

그리고 ImageNet 데이터셋은 클래스의 개수가 총 1,000개 이기 때문에 output layer는 1,000개의 노드로 이루어져 있고, 각각의 node에서 나오는 값이 각각의 클래스에 속할 확률 (softmax를 거치므로)이 된다.

그리고 첫 번째 그림에서 Stride = 4라고 적혀있는 것을 볼 수 있는데 이는 앞에서 언급하였듯 Filter가 Image의 픽셀값을 4칸 단위로 이동함을 의미한다.

 

그럼 다음 글에서는 GoogleNet, VGG, InceptionNet에 대해서 살펴보도록 하자.

 

 

728x90

댓글