머신러닝/Vision

Convolutional Neural Networks ?

망나 2018. 9. 5. 12:09

해당 글은 Adit Deshpande의 블로그에 게제되어 있는 "A Beginner's Guide To Understanding Convolutional Neural Networks"를 개인 공부 목적으로 한글로 재작성한 것 입니다. 원문을 읽으시는게 문맥상이나 모든면에서 훨씬 이해가 쉬울 수 있습니다.



Introduction

Convolutional neural networks, CNNAI, 특히 Deep Learning이 다시 관심을 받고 이렇게 발전할 수 있게 만들어준, 그 만큼 기본적이고 중요한 모델이다. 2012년에 ImageNet competition(computer vision 분야의 올림픽이라 할 수 있는 큰 대회)에서 Alex Krizhevsky에 의해 사용되었고, 이미지 분류 오류율을 26%에서 15%로 낮추는 엄청난 성능을 보여주었다. 이후 많은 기업들과 연구자들의 관심을 받았고(아직까지 Deep Learning에서 중심이 되는 것 같다.), 지속적으로 연구가 활발하게 이루어지고 있다. 최근 거의 모든 기업(구글, 페이스북, 아마존 등..)에서 Deep Learning 기술을 서비스에 적용하고 있고 앞으로도 한 동안은 가장 핫한 연구 분야이지 않을까 한다.

 

본 글에서는 이미지 처리 분야, 특히 CNNs으로 어떻게 이미지를 분류할 수 있는지에 대해서 다루겠다. (14년도 군생활하면서 처음으로 AI가 사진에서 고양이를 찾아낸다는 얘기를 들었던 기억이 나는데... 이걸 이제야 정리하고 있다.. 시간..... 빠르네..)



The Problem Space

이미지 분류는 컴퓨터(모델)에 이미지를 입력으로 주면, 해당 이미지의 클래스(고양이, , ..) 또는 해당 이미지가 각 클래스에 속할 확률을 출력으로 받는 과정을 말한다. 우리 사람은 태어나서부터 주변 환경을 눈으로 보면서 자연스럽게 이러한 이미지 분류 과정을 학습하고, 쉽게 해결할 수 있게 된다. 그렇다면 어떻게 컴퓨터(모델)을 학습시켜서 우리보다 더 정확한 이미지 분류 문제를 해결할 수 있을까?


 


 


 우리 눈에 보이는 모습

컴퓨터가 보는? 인식하는 모습 




Inputs and Outputs

컴퓨터(모델)이 이미지를 볼 때(이미지를 입력으로 줄 때), 위 그림과 같이 픽셀 값의 배열을 인식할 것이다. 만약 우리가 480x480 크기의 컬러 JPG 형식 이미지를 입력으로 주면, 480x 480x3(3RGB 값을 나타낸다)의 배열 값으로 나타낼 수 있다. 각 값은 0 ~ 255사이의 픽셀 값으로 나타난다. 우리가 볼 때는 무의미 할 수 있는 이 숫자 값들은 컴퓨터가 이미지 분류를 수행할 때 유일하게 이미지로부터 얻을 수 있는 정보이다. 이 정보를 활용하여 컴퓨터는 이미지 분류를 하고 결과 값으로 해당 이미지가 각 클래스에 속할 확률을 사용자에게 돌려준다.(고양이 0.15, 0.80, 0.05, ...)



Structure

CNNs의 전체적인 구조는 다음과 같다, 먼저 이미지를 입력으로 받고, convolutional, nonlinear, pooling(downsampling), and fully connected layers를 거쳐 출력 값(클래스 또는 각 클래스의 확률 값)을 얻어낸다. 이제 각 단계별로 어떤 과정이 이루어지는지 자세히 알아보자.



First Layer - Math Part

CNN의 첫 번째 단계는 항상 Convolutional Layer이다. 이전에 언급한 것처럼 입력으로 32x32x3 형태의 픽셀 값 배열을 받게 된다. 먼저 이 배열의 가장 왼쪽 위의 5x5 영역만 고려해보자. machine learning terms로 이 5x5 영역을 receptive field라 하고, 5x5 filter를 사용한다고 한다. 이때 filter도 특정 값들로 이루어진 배열이며 이 값들을 weights or parameters라 부르고, filter 또한 이미지와 같은 깊이를 갖기 때문에 filter5x5x3의 형태가 된다. filter가 입력 이미지에 convolving 한다는 것은 현재 filter의 위치, 입력 이미지의 가장 왼쪽 위의 영역의 값들과 filter의 값들을 곱하는 과정을 의미한다(element wise multiplications 계산). 모두 곱한 값들은 다 더해지고, 우리는 하나의 값을 얻게 된다. 이 값은 filter가 위치했던 입력 이미지의 가장 왼쪽 위의 5x5 부분을 나타내는 값이다. 이제, 이 과정을 filter를 오른쪽으로 1칸씩 입력 이미지의 모든 값을 고려할 수 있을 때까지 옮기며 반복하게 된다. 이렇게 반복 계산이 종료되면 우리는 28x28x1의 숫자 배열을 얻게 되고 이것을 activation map 또는 feature map이라 부른다.





First Layer - High Level Perspective

그렇다면, convolution이 정확히 어떤 역할을 하는지에 대해서 알아보자. filter들은 feature identifiers라 할 수 있다. 여기서 말하는 feature들은, 직선, 곡선, 색상, 모서리 등의 특징을 말한다. 만약에 우리가 7x7x3curve detector filter를 가지고 있다고 가정해보자(이 부분에서 filter와 이미지의 깊이를 무시하고 가장 위의 slice만을 고려하겠다, 간단한 설명을 위해...). curve detector filter은 다음 그림에서 보이는 것과 같이 곡선 모양의 영역에만 높은 픽셀 값을 가진 형태가 될 것이다.



다시 수학적으로, 우리가 이 filter를 입력 이미지의 가장 왼쪽 위에 위치시키면, 입력 이미지의 픽셀 값들과 filter의 픽셀 값들의 곱셈 계산이 진행될 것이다. 아래 그림을 보면 이해가 쉬울 것이다



위 그림에서처럼 우리가 적용시킨 filtercurve detector였고, 이미지의 가장 왼쪽 위에는 filter와 거의 유사한 curve 형태의 이미지가 존재한다. 결과적으로 입력 이미지 픽셀 값과 filter 픽셀 값의 곱들의 합의 결과로 6600이라는 큰 숫자를 얻을 수 있다. 그렇다면, 이제 filter를 이동시켰을 때, 어떤 일이 벌어지는지 보자.


filter를 이동시켜서 같은 연산을 수행 했지만, 입력 이미지는 curve 형태가 아니기 때문에 연산의 결과 값으로 아까와 다르게 0이라는 작은 숫자를 얻게 된다. curve detector filter에 반응하지 않았다는 뜻이고, 해당 부분의 이미지는 curve 형태가 아니라는 뜻으로 해석할 수 있다. 따라서 우리는 이렇게 간단한 예를 보고 activation map이 입력 이미지에서 어느 영역이 해당 filter(우리 예에서는 curve)와 같은 모습을 보이는지를 찾아낼 수 있다는 것을 알았다. 그렇다면 우리가 다양한 filter를 사용한다면 원본 이미지의 전체 모습이 어떠한지를 컴퓨터가 이해(식별)하게 만들 수 있을 것이다.

쉬운 이해를 위해 간단한 filter를 활용했는데, 실제 filter는 훨씬 복잡하고 다양한 정보를 포함하고 있다. 아래 그림은 first conv laterfilter를 실제 시각화해본 결과이다.

(The above image came from Stanford's CS 231N course taught by Andrej Karpathy and Justin Johnson)



Going Deeper Through the Network

전통적인 CNN의 구조는 아래와 같다.

Input Conv ReLU Conv ReLU Pool ReLU Conv ReLU Pool Fully Connected

이전까지의 설명은 첫 번째 Conv layer를 거치게 되면서 이루어지는 과정이다. 첫 번째 conv layer에서 우리는 이미지에서 곡선을 식별하는 filter에 대해서 다루었다. 이렇게 곡선, 직선, 모서리 또는 간단한 색상 같은 특징을 이미지에서 식별하는데 성공했는데 실제로 이미지를 분류하기 위해선 좀 더 높은 차원의 특징, 예를 들면 얼굴이나 손, 발과 같은 특징을 식별해야 한다. 그러기 위해서 우리는 또 다른 conv layer가 필요하게 되고, 이때 두 번째 conv layer의 입력 값은 첫 번째 conv layer의 출력 값 28x28x3의 형태를 갖게 된다. 두 번째 convolution을 수행하게 되면, 우리는 첫 번째 convolution에서 얻을 수 있었던 activation map보다 더 넓은 영역의 이미지 정보가 함축된 activation map을 얻을 수 있고, 따라서 얼굴이나 손, 발 같은 높은 차원의 특징을 식별할 수 있게 된다


[ 추가 참고자료 ]

Jason Yosinski의 비디오 설명 자료

Matt Zeiler and Rob Fergus의 연구 논문



Fully Connected Layer

이제 앞의 convolution 과정을 통해서 얻은 high level features들은 네트워크의 마지막 층인 fully connected layer에 전달된다. 기본적으로 FC(fully connected)층에서는 conv 또는 ReLu 또는 pool 층의 결과 값을 입력으로 받고, N 차원의 배열을 출력으로 준다. 여기서 N은 사용자가 프로그램 한 클래스의 개수이다(고양이와 강아지 2가지를 분류하고 싶다면 N2가 된다). 예를 들어서 출력으로 [0.80 0.20]이 나왔다면, 이는 이미지가 고양이일 확률이 80%이고 강아지일 확률이 20%라는 것을 뜻한다. 그렇다면 fully connected layer는 어떤 방식으로 동작할까? FC층에서는 이전 층의 출력(high level features를 나타내는 activation maps)을 보고 어떤 feature들이 특정 클래스에 속할지를 결정하는 작업을 수행한다. 예를 들어, 만약 이미지가 강아지인지를 판별하는 프로그램(모델)이라면, 강아지의 특징들(얼굴, 꼬리, 다리)등을 나타내는 high level feature들의 activation maps가 높은 값을 가지고 있을 것이다.

 



Training (What Makes this Stuff Work)

이제 neural networks의 한 과정으로 가장 중요한 과정에 대해서 다루겠다. 이 전까지의 과정을 읽다보면 많은 궁금증이 생길 것이다. conv layerfilter들이 어떻게 모서리나 곡선을 구분할까? 어떻게 fully connected layeractivation maps의 모습이 어떠한지 알까? 각 층의 filter들이 어떤 값(정보)를 가지고 있는지 어떻게 알까? 컴퓨터는 역전파(backpropagation)이라 불리는 학습 과정을 거치면서 filter (weights )을 조정하면서 앞의 모든 과정들을 가능하게 한다.

 

역전파(backpropagation) 과정으로 바로 들어가기 전에, 먼저 neural network가 동작하려면 무엇이 필요한지에 대해서 생각해보자. 우리가 처음 태어났을 때, our minds were fresh(아무것도 모르는 상태? 순수한 상태?). 우리는 고양이나 강아지가 무엇인지 모른다. 이와 같이 CNN도 학습이 이루어지기 전에는 weights 또는 filter 값은 무작위(random) 값이다. filter들은 모서리나 곡선을 구분할 줄 모른다. 하지만 우리가 자라는 과정에서 우리는 많은 것들을 사진(image)으로 보고 부모님들은 해당 사진이 무엇(label)인지 알려준다. 이러한 학습을 반복하며 고양이와 강아지가 무엇인지 알고 구분할 수 있게 된다. 여기서 아이디어를 얻어 우리는 CNNs의 학습을 위해서 imagelabel을 모델에게 입력한다. 따라서 학습을 위해서 우리는 수천 장의 이미지와 해당 이미지에 해당하는 label값이 필요하다. 그렇다면 이제 다시 역전파(backpropagation)을 살펴보자.

역전파(backpropagation)forword pass, loss function, backward pass, weight update4 과정으로 구분할 수 있다. 먼저 forword pass 동안에는, 학습할 이미지가 전체 네트워크를 통과하게 된다. 모든 weight 또는 filter 값이 무작위로 초기화 되어 있고, 출력 값은 [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]와 같은 모습일 것이다(클래스가 10이라고 가정). 기본적으로 출력 값을 어떤 특정 값(클래스)에 우선을 두지 않는다. 현재 상태의 네트워크로는 어떠한 의미 있는 분류 결과를 얻을 수 없다. 이제 역전파의 loss function 과정으로 들어간다. 우리는 현재 학습 데이터(training data)를 사용하고 있고, 학습 데이터는 imagelabel값을 모두 갖고 있다. 그렇다면 예를 들어, 첫 번째 학습 데이터의 image는 클래스 3에 속한다고 하자. 그럼 label의 모습은 [0 0 1 0 0 0 0 0 0 0]와 같을 것이다. loss function은 다양하게 정의될 수 있지만, 가장 기본적으로 MSE(mean squared error)를 사용한다.


(쉽게 직관적으로 이해하면 target이 실제 값이고 output이 예측 값이므로, 실제 값과 우리가 모델을 통해 얻은 예측 값의 차이를 구하는 것이다.)


우리는 우리의 예측 label(ConvNet의 출력 값)이 학습 데이터 label과 같아지기를 원한다(두 값이 같다는 것은 우리의 모델이 제대로 예측을 했다는 뜻이다). 이를 위해선 우리는 위에서 얻은 loss값을 최소화해야 한다. 따라서 우리는 네트워크에서 어떤 입력 값(weights in our case)이 직접적으로 loss(or error)값에 영향을 미치는지를 찾아야한다.



이는 수학적으로 dL/dW로 나타낼 수 있는데, 여기서 W는 특정 layerweights를 의미한다. 이제 우리는 네크워크에서 어떤 weight값이 가장 loss에 영향을 미치는지를 찾고 그 weight값을 조정함으로써 loss값을 줄이는 backward pass 과정을 수행한다. 마지막으로 우리는 weight update 과정을 수행하는데, 이 과정에서는 모든 filter들의 weight들 값을 기울기의 반대 방향으로 가도록 update한다.



위 식에서 learning rate란 사용자에 의해서 결정되는 변수이다. learning rate가 크다면, weight update 과정에서 각 단계마다 weight값의 변화가 커지게 되고, 이는 모델의 weight값들을 최적화 시키는데 걸리는 시간을 단축시킬 수 있다. 하지만 너무 큰 learning rate 값을 사용하면 global optimal point에 도달하지 못할 수도 있다.



여기까지 설명한 forward pass, loss function, backward pass, parameter update가 전체적으로 한번 학습이 진행되는 과정이다. 모델은 전체 네트워크 각 층의 weight들이 정확하게 튜닝될 때까지 이 학습 과정을 반복한다.


* 본 글에서 많은 내용을 다룬 듯 하지만 아직 CNN에 대해 완전히 이해하기 위해선 턱없이 부족하다. 나머지 부족한 개념들을 하나하나 차근히 정리해 나가겠다.


'머신러닝 > Vision' 카테고리의 다른 글

ResNet 이해하기  (0) 2019.06.04
Generative Adversarial Networks (GANs)  (0) 2019.02.27
Batch Normalization?  (0) 2018.10.23
Recurrent Neural Networks ?  (0) 2018.09.30
Convolutional Neural Networks ? [2]  (0) 2018.09.06