이 글은 Christopher Olah가 2014년 7월에 쓴 글을 우리 말로 번역한 것이다. Convolutional layer가 기존 neural network를 어떻게 발전시켰는지에 대해 좋은 그림들과 함께 이론적으로 잘 설명했고, 그 당시 핫한 연구 결과를 토대로 그 의미를 느낄 수 있도록 한 굉장히 좋은 글이라고 생각한다. 저자의 홈페이지에 neural network에 대한 주옥같은 글들이 많으므로 관심이 있다면 둘러보시길 추천한다.
기본적으로 neural network에 대해서 이해하고 있어야 이 글의 내용을 원활하게 이해할 수 있으리라 생각한다. (염치없는 홍보 문구) 혹시 neural network를 먼저 알고 싶다면 역자의 다른 글도 나쁘지 않다.
우리 말로 옮기기 애매한 용어는 영어 단어 그대로 표기했고, 원문에 있는 그림을 그대로 가져다 썼다. 물론 저자의 허락을 받고 번역했다. 오역에 대한 지적이나 내용에 대한 피드백은 항상 감사합니다.
Convolutional Neural Networks: 모듈 별로 쪼개서 보기
2014년 7월 8일
시작하는 말
지난 몇 년 동안, deep neural network는 컴퓨터 비전, 음성 인식 등의 여러 패턴 인식 문제를 앞장 서서 격파해왔다. 여기서 핵심적인 network 모델 중 하나는 convolutional neural network (이하 CNN)이다.
쉽게 풀어 얘기하자면, CNN은 하나의 neuron을 여러 번 복사해서 사용하는 neural network라고 말 할 수 있겠다. 그렇게 함으로써 CNN은 neuron의 행태를 보여주는 (실제 학습이 필요한) parameter의 개수를 꽤나 작게 유지하면서도, 굉장히 많은 neuron을 가지고 방대한 계산을 필요로 하는 모델을 표현할 수 있다.
2D CNN
한 neuron을 여러 번 복사해서 사용하는 술수는 수학이나 컴퓨터 과학에서 함수를 사용하는 것에 빗대서 이야기할 수 있다. 코딩을 할 때면, 한 번 만들어진 함수는 여러 번 쓰인다. 같은 코드를 다른 부분에 100번 반복해서 사용하지 않아도 되니 프로그램이 빨라지고 버그도 적어지게 된다. 마찬가지로 CNN도 한 번 배운 neuron을 여러 군데에서 사용하기 때문에, 모델이 학습하기 쉬워지고 또한 오차도 줄일 수 있다.
CNN의 구조
우리는 음성 자료를 바탕으로 이 음성이 사람이 말하는 것인지 아닌지 예측하고 싶다고 해보자. 그리고 사람이 말하고 있는 음성이라면 거기서 우리는 뭔가를 더 조사해볼 수도 있을 것이다.
우리의 음성 자료는 시간에 따라 다른 정보를 가지고 있을 것인데, 여기서는 일정한 시간 간격의 음성 자료라고 가정하겠다.
이제 neural network로 분류를 하고자 할 때 가장 단순하게 할 수 있는 방법은 그냥 fully-connected layer에 전부 다 연결해버리는 것이다. 그러면 network 모델은 서로 구별되는 neuron들을 갖고 있을 것이고, 모든 input이 모든 neuron에 각각 연결될 것이다.
조금 더 network를 발전시켜 보려면, 데이터를 들여다 보기에 도움이 되는 성질 간의 대칭성을 생각해봐야 한다. 우리는 데이터의 local 성질들에 신경을 많이 써야 한다: 어느 시간 범위에서 어떤 주파수의 소리가 날까? 주파수가 그 범위에서 올라갈까 내려갈까? 이런 식으로 말이다.
위에서 언급한 성질을 시간의 모든 지점에 대해서 알고 싶을 수도 있다. 시작 시점에서의 주파수를 아는 것도 중요하고, 중간 지점에서도, 마지막 지점에서 아는 것도 유용한 것이다. 그런데 음성 자료의 작은 범위만 체크한다는 점에서 이들은 모두 local 성질이다.
그래서 우리는 neuron의 그룹 A를 만들 것이다. 그 그룹 A는 음성 자료의 작은 시간 단위만을 다룰 것이다. 그리고는 어떤 feature를 계산할 것이다. 그렇게 convolutional layer의 결과물이 나오고 이 결과물이 다시 fully-connected layer F로 들어가게 된다.
위 그림에서 A는 자기와 가까운 2개의 범위만을 바라보는데 이것이 많이 단순화된 그림이다. 보통 convolutional layer의 window 범위는 훨씬 크다.
아래 그림에서 A는 3개의 범위를 바라보는데 이것도 역시 단순화된 것이다. 아쉽게도 많은 input에 연결된 A를 그림으로 보이기엔 너무 어렵다.
Convolutional layer의 매우 좋은 성질 중 하나는 layer들을 계속 합성할 수 있다는 점이다. 한 convolutional layer의 결과가 다른 convolutional layer로 들어갈 수 있는 것이다. Layer가 올라감에 따라 network는 더 어려운 레벨의 추상화된 것들을 알 수 있다.
아래 그림에는 새로운 neuron 그룹 B를 추가된 모델을 볼 수 있다. B는 기존 convolutional layer위에 한 층 더 쌓이는 convolutional layer이다.
Convolutional layer는 종종 pooling layer와 엮이곤 한다. 그 중에서도 max-pooling layer는 굉장히 유명하다.
또한 멀리서 보았을 때, 혹은 높은 수준의 관점에서, 아주 정확한 시점에서의 정보는 우리에겐 굉장한 정보가 아니기도 하다. 음성 주파수가 아주 약간 일찍 또는 약간 이따가 나타났다고 해서 그것이 중한가?
Max-pooling layer는 이전 layer의 작은 블럭만 쳐다보고 그 중 가장 큰 값만 취한다. Max-pooling layer의 output은 이전 layer의 어느 부분 즈음에 그 특성이 있는지 말해주지, 정확히 어디인지 알려주지는 않는 것이다.
그러니까 max-pooling layer는 일종의 "zoom-out" 같은 것이다. Max-pooling layer는 그 input으로 받는 작은 patch들을 모두 합친 영역의 정보를 다음 layer로 넘겨주기 때문이다. 게다가 max-pooling은 매우 작은 스케일의 데이터 변환에 대해서 크게 영향을 받지 않도록 (invariant) 해준다.
지금까지는 1D convolution layer만을 다뤘었지만, 다차원의 데이터에 대해서도 적용할 수 있다. 사실 CNN의 가장 유명한 성공 스토리는 이미지 인식을 위한 2D CNN이다.
위 그림에서 보다시피 2D convolutional layer가 쳐다보는 범위는 patch 단위가 된다.
각 patch마다 A는 feature를 계산할 것이다. 예를 들어 A는 그림의 경계(edge)를 배울 수도 있고, 어떤 질감(texture)을 배울 수도 있고, 아니면 색상 대비를 배울 수도 있다.
위 그림에서의 network 모델은 convolutional layer의 결과물을 fully-connected layer에 연결한 것이다. 하지만 아까 1D의 경우처럼 2개의 convolutional layer를 쌓을 수도 있다.
그리고 max-pooling을 2D에서도 적용할 수 있는데, 각 patch 마다의 가장 큰 값을 취하면 될 것이다.
우리가 지금까지 말했던 것 모두 적용했다고 생각해보자. 이미지 전체를 두고 생각해 보면, 우리는 그림의 경계의 위치를 픽셀 단위로 정교하게 신경쓰지는 않게 된다. 그저 몇 픽셀의 범위 내에서 edge가 있다는 정도로만 아는 것이다.
한 차원 더 높인 3D CNN은 영상 자료나 체적 측정 데이터 (3D 의학 영상 같은 것)에 대해 사용될 수 있지만, 그렇게 널리 쓰이지는 않으며, 시각적으로 보여주기는 더욱 어렵다.
A는 neuron의 그룹이라고 지금까지 이야기했었는데, 이제부터는 조금 더 깐깐하게 생각해 보려고 한다. 그래서 A는 정확히 무엇인가?
전통적으로 말하는 convolutional layer A의 의미는 neuron들의 병렬적인 묶음인데, 그 neuron들은 모두 같은 input을 받지만 서로 다른 feature를 계산한다.
2D convolutional layer의 예를 들어보자면, 한 neuron은 수평적인 edge를 감지하는 반면 다른 neuron은 수직 edge를 감지할 수도 있고, 또 다른 neuron은 초록-빨강 색상의 대비를 찾을 수도 있는 것이다. 아래 그림의 3개 neuron에 맞춰서 생각해 볼 수 있다.
"Network in Network" (Lin 외, 2013) 논문에서는 새로운 "Mlpconv" layer를 제안했는데, 아래 그림의 A처럼 여러 layer로 구성되어있고, 마지막 layer는 어느 범위의 고레벨의 feature를 뱉어낸다. 논문에 따르면 모델은 여러 benchmark 데이터에 대해서 최고 기록을 세울 만큼 꽤 인상적인 결과를 보여주었다.
지금까지 여러 복잡한 convolutional layer 구조에 대해 충분히 생각해봤으므로, 이제부터는 표준적인 convolutional layer에 집중해서 얘기하겠다.
CNN의 최근 결과물들
지금까지 최근 컴퓨터 비전 문제를 돌파한 CNN에 대해 설명해왔다. 더 나아가기 전에, 동기 부여를 위해 실제 연구 결과를 논의해보려 한다.
2012년에 Alex Krizehvsky, Ilya Sutskever, Geoff Hinton의 연구는 기존 이미지 분류 결과를 압도하는 결과를 보여주었다 (Krizhevsky 외, 2012).
압도적인 결과의 이유는 서로 다른 여러 방법들의 조합을 합쳐서 사용했기 때문이다. 그들은 거대한 deep neural network를 학습시키기 위해 많은 GPU를 사용했고, 새로운 방식의 neuron (ReLU)을 도입했으며, overfitting의 문제를 줄이기 위해서 새로운 방법 (DropOut)을 사용한 것이다. 또한 많은 이미지 카테고리를 가지고 있는 방대한 데이터셋 (ImageNet)을 사용했다. 마지막으로, 그들의 모델은 CNN이었다.
아래 그림에서 볼 수 있는 이 모델의 구조는 굉장히 깊다. 5개의 convolutional layer가 있고, 그 사이에 pooling layer가 엮여 있으며, 3개의 fully-connected layer가 더 있다. 초기 단계의 layer는 2개의 GPU가 계산할 수 있도록 나뉘어져 있다.
출처: Krizehvsky 외 (2012)
이 모델은 학습을 통해 천 여개의 다른 카테고리에 속한 이미지들을 분류하게 된다.
아무 근거 없이 찍는다면 이 분류가 성공할 확률은 0.1% 밖에 되지 않는데, 이 모델의 정답률은 63%로 나왔다. 심지어 가장 잘 맞추는 카테고리 5개에 대해서는 85%의 정답률을 보였다!
윗 줄의 4개는 정답을 맞춘 사례고, 아랫 줄의 4개는 오답인 경우이다. 각 사례마다 가장 높은 확률로 계산된 5개의 선택지를 볼 수 있다. 출처: Krizehvsky et al. (2012)
위 결과에서 볼 수 있는 오답들 마저 꽤 일리있어 보이기도 한다!
여기서 우리는 이 모델의 첫 번째 layer가 무엇을 배우는 지 확인해 볼 수 있다.
앞에서 convolutional layer들이 2개의 GPU가 계산할 수 있도록 나눠져 있다고 이야기했었다. 학습 과정에서 배우는 정보들은 layer들을 맘대로 왔다 갔다 할 수 없기 때문에, 이렇게 convolutional layer가 학습 과정에서 나눠지는 것은 학습 내용에도 영향을 미치게 된다. 그래서 모델이 학습할 때면 layer가 나눠진 두 부분은 각자 고유한 뭔가를 학습한다고 밝혀졌다.
첫 번째 convolutional layer가 학습을 끝냈을 때의 필터들의 모습이다. 윗 절반과 아랫 절반이 GPU의 계산을 위해 분리되어 있다. 출처: Krizehvsky et al. (2012)
그림을 보면 나눠진 convolutional layer의 첫 절반은 흑백 정보에 집중하고 있으며, 다양한 방향과 스케일에서의 edge를 배우려고 하고 있다. 나머지 절반은 색상과 질감에 특화되어 있어서 색상 대비와 패턴을 배우는 것을 볼 수 있다. 아무도 이 모델에게 edge를 배우라고 edge detector를 설정한 것도 아니고, layer의 쪼갠 두 부분이 각자 이렇게 다르게 배우라고 정하지도 않았다. 그저 network가 이미지를 구분하기 위해 알아서 학습하는 과정 중에 일어난 일이다.
이런 놀라운 결과는 (그리고 이 연구가 나올 당시의 다른 멋진 연구들까지) 시작에 불과했다. 곧 많은 연구자들이 이들을 따라서 모델을 조금씩 발전시켜갔고, 또한 다른 분야에 적용시켜 보기도 했다. 그리고 neural network 분야 사람들 뿐만 아니라 컴퓨터 비전 분야에서도 이 deep CNN를 도입하기 시작했다.
CNN은 이제 컴퓨터 비전과 현대 패턴 인식에서 필수적인 도구가 된 것이다.
수식으로 생각해보는 CNN
1D convolutional layer의 input이 \( \{x_n\} \) 이고 output이 \( \{y_n\} \) 이라고 표기하자.
이 output을 수식으로 표현하는 것은 비교적 쉬운 일이다.
\[ y_n = A(x_n, x_{n+1}, \cdots ) \]
예를 들어 위 그림과 같은 convolutional layer를 표현해보면 아래처럼 쓸 수 있겠다.
\[ y_0 = A(x_0, x_1) \\ y_1 = A(x_1, x_2), \\ \vdots \]
비슷한 방법으로 2D convolutional layer를 생각해보면, input을 \( \{x_{n,m}\} \)으로, output을 \( \{y_{n,m}\} \)으로 표시할 수 있다.
아까와 같은 방식으로 output을 input에 대한 관계식으로 표현해보자.
\[ y_{n,m} = A \begin{pmatrix} x_{n,m} & x_{n+1,m} & \cdots \\ x_{n,m+1} & x_{n+1,m+1} & \cdots \\ \vdots & \vdots & \ddots \end{pmatrix} \]
위 그림의 경우에는 이렇게 단순해 질 수 있다.
\[ y_{0,0} = A \begin{pmatrix} x_{0,0} & x_{1,0} \\ x_{0,1} & x_{1,1} \end{pmatrix} \\ y_{1,0} = A \begin{pmatrix} x_{1,0} & x_{2,0} \\ x_{1,1} & x_{2,1} \end{pmatrix}, \\ \vdots \]
이제 \( A(x) \)의 실체를 이렇게 아래와 같다고 생각해보자.
\[ A(x) = \sigma(Wx + b) \]
그러면 이론적으로는 CNN을 구성할 수 있는 모든 것을 갖추게 된 셈이다.
하지만 실제로 CNN을 이해하기 위한 방법으로 더욱 좋은 것들이 있다. Convolution이라는 것이 수학적으로 어떤 의미를 가지는 지를 생각해보면 CNN에 접근하는 더 좋은 방법을 알 수 있다.
Convolution은 편미분 방정식에서부터 확률론에 이르기 까지 다양한 수학 분야에서 사용되는 도구이다. 편미분 방정식에서 사용되는 것에서 볼 수 있듯이, convolution은 물리 과학에서도 굉장히 중요한 개념으로 쓰인다. 또한 컴퓨터 그래픽이나 신호 처리 분야와 같은 응용 수학 분야에서도 중요한 역할을 맡고 있다.
Convolution을 통해 우리도 많은 이득을 얻을 수 있다. 첫 번째로, convolutional layer는 network의 계산량을 현저하게 줄여준다. 두 번째로, 모델을 공식화하는데 지저분한 계산들을 치워준다. Input x의 인덱스를 계속 추적해가야 하는 일을 줄여주는 것이다. 위에서 본 공식들은 그닥 지저분해 보이지 않을 수도 있는데, 일부러 단순한 경우만 보여준 것이다. 마지막으로 convolution은 convolutional layer를 상당히 다른 관점에서 이해할 수 있게 해준다.
I admire the elegance of your method of computation; it must be nice to ride through these fields upon the horse of true mathematics while the like of us have to make our way laboriously on foot. — Albert Einstein
'Machine Learning' 카테고리의 다른 글
Deep Learning, NLP, 그리고 Representation (2) | 2018.04.17 |
---|---|
Long Short-Term Memory (LSTM) 이해하기 (27) | 2018.04.10 |
PyTorch를 이용한 NLP 튜토리얼, Part 3: Recurrent Neural Network와 LSTM 모델 (0) | 2018.04.05 |
PyTorch를 이용한 NLP 튜토리얼, Part 2: Word Embedding (0) | 2018.03.25 |
PyTorch를 이용한 NLP 튜토리얼, Part 1: 기초 개념 (0) | 2018.03.22 |