본문 바로가기
컴퓨터 사이언스/딥러닝

[cs231n] Lecture 4. Back propagation을 하는 이유와 Neural network의 직관적인 해석

by 제크와 죠세핀 2018. 10. 23.
반응형

어제 밤에 cs231n Lecture 4 Introduction to Neural Network를 듣다가 깨달음을 얻었다. 그 깨달음을 시간이 지나가기 전에 텍스트로 적어놓는다면 내용을 더 오랫동안 기억할 수 있을 것 같아서 글을 쓴다.

나는 cs231n 강의를 듣기 전에 Coursera에서 그 유명한 Andrew Ng의 Machine Learning을 들었고 그 다음에 같은 사이트에서 같은 분이 강의하는 딥러닝 강좌 중 Neural Network와 Convolutional Neural Network 강의를 들었다. 듣다가 중간에 하차했다.

그 이유는 

1. 한 달에 한국 돈으로 5만원 정도를 내면서 강의를 들어야 하는데 시간이 여유롭지 않아 몇 개 밖에 듣지 못했다.

2. Machine Learning에서 배웠던 내용이 상당수 겹쳤는데 들어야 할 내용은 많으니까 의욕이 떨어졌다.

가 있었다. 나름 그래도 재미있고 쉽게 강의를 들을 수 있어서 처음 듣기에 강의 자체는 좋았다.

그러면서 이렇게 어영부영 하다간 머신러닝 배웠던 것도 다 잊어버릴 거 같고 딥러닝 공부를 제대로 해볼 수 없겠단 생각이 들었던 와중에 지인이 cs231n 강의를 들어보는 것을 추천했다. 그러면서 이 강의는 강의도 명강이지만 과제가 진짜 제대로라는 이야기를 들었다. 그러면서 강의를 한 개씩(이전에 배웠던 내용과 겹치는 내용이 있었지만 강의 초중반이니 복습하는 셈치고 듣기로 했다.) 듣다가 Lecture 4에서 Back prop을 하는 이유와 Neural Network의 직관적인 해석에 대해서 설명하는 부분에서 많은 깨달음을 얻었다.


그전에 나는 Neural Network에서 Back propagation이 input 값을 흘려주었을 때 나오는 output들을 이용해서 거꾸로 output에 대한 input들의 partial derivative를 구하는 것이란 것만 이해를 했었다. 이 과정을 통해 어떤 값을 구하려고 하는 진 알겠고 이렇게 미분 값을 구함으로써 gradient descent를 할 수 있다는 것은 알겠는데 왜 굳이 Back propagation을 쓰는 지 의문을 가진 적이 없었다. 물론 이전에 들었던 강의 lecturer가 설명을 했었을 거란 생각은 한다. 다만 cs231n처럼 많은 시간을 할애해서 강조하며 설명하지는 않았던 것 같다. 일단 오늘의 포스트를 쓰는 목적을 생각하며 내용을 정리해보자.


1. Back propagation을 하는 이유

cs231n의 lecturer는 Back propagation을 쓰는 이유를 numerical / analytic gradient를 구하는 것으로 설명한다. 

1) Numerical gradient : 고등학교 때 열심히 배웠던 df/dx = lim (f(x+h)-f(x))/h 식으로 구한 미분 값이다.

2) Analytic gradient : 실질적으로 쓰는 것으로, 완벽히 어떤 미분 식을 구한다기보다는미분 값만 빠르게 구하는 것이다. 

실질적으로 딥러닝에서 쓰는 Neural Network처럼 복잡한 식은 그것에 대한 미분 식 자체를 구하는 데 시간이 오래걸린다. 그래서 시간을 절약하기 위해서 numerical gradient 대신 analytic gradient를 쓰는 데, 그걸 구하는 방법이 back propagation이다. back propagation은 computation graph를 이용해 전체의 복잡한 graph의 미분 값을 간단하게 구하는 방법이다. 전체 graph에서 input에 대한 output의 partial derivative를 구할 때, 그 graph를 구성하는 node들에 대한 함수들의 local gradient 곱(미분의 chain rule : df/dx = df/dz * dz/dx)을 이용함으로써 전체의 복잡한 문제는 작은 노드들의 local gradient를 구하는 쉬운 문제들로 변환할 수 있다는 것이 back prop을 하는 이유인 것이다! 그리고 이런 장점은 딥러닝을 코드로 구현할 때 back prop을 하나의 모듈처럼 구현할 수 있게 한다.


** 그리고 computational graph를 좀 더 직관적으로 해석해보면,

각 노드를 +로 연결할 때는 add gate라 해서 gradient를 (같은 값으로)분산하는 것이라 할 수 있다.

각 노드를 *로 연결할 때는 예를 들면 A*B = C의 형태라면, A에 대한 C의 partial derivative는 B, B에대한 partial derivative는 A가 되어서 각 노드 서로가 서로의 값을 가지는 것으로 multiplication gate는 gradient를 switch하는 것이라고 할 수 있다.(굉장히 전자회로스러웠다)


2.    Neural Network의 직관적인 해석

이 부분에 대해서 내용 정리를 하기에 앞서 나는 사실 그전에 어떤 classifier가 linear하다는 것과 non-linear하다는 것에 대해서 그렇게 엄청나게 잘 이해하지 못했다는 것을 밝힌다. 이 둘에 대해서 내가 기억하고 있는 것(뉘앙스)은 이 세상의 문제들은 대체로 복잡하기 때문에 linear하게 decision boundary를 쳐서 해결할 수 없는 문제도 많다. 그렇기 때문에 non-linear classifier를 쓰고 그래서 sigmoid같은 함수도 이용한다는 것이다. 음. 그냥 선형적으로 풀 수 없는 문제에 대해서 비선형적인 함수를 쓰는구나! 까지만 이해했던 것 같다. 그래서 Neural network가 복잡하다는 말을 들었을 땐 음 노드가 많으니까 막연히 그냥 복잡할 것 같다. 란 생각을 했었다. 

그러나 강의에서도 이야기하지만, 생각해보니 neural network의 노드들 자체가 연결되어 있는 건 선형적인 합이기 때문에 선형적인 층만 여러개 쌓는 것은 선형성에 의해서 하나의 층으로 합칠 수 있으므로 별 의미가 없다. 즉, 중간에 정보를 통합하는(sigmoid같은) 그런 것들이 있음으로써 neural network는 비선형함수가 될 수 있는 것이다. 층들이 겹겹이 쌓여있다는 것으로 neural network를 해석한다면 neural network는 간단한 함수들이 쌓인 하나의 클래스라고 볼 수 있다. 더 복잡한 비선형 함수를 만들기 위해서 linear layer들의 중간 중간에 non-layer function을 추가해서 계층적인 구조가 이루어진 형태라 생각했더니 이해가 쉬웠다. 


그리고 이 layer 사이의 W가 의미하는 것이 무엇인가?라는 것에 대해서도 수업 중에 다룬다. W의 각 행(row)은 우리가 input에서 어떤 부분을 찾고 있는 지를 알려주는 일종의 템플릿(template)이다. 예를 들어, 우리가 어떤 말(horse) 이미지에 대한 classfier를 만든다면 그 classifier의 input layer와 곱해지는 W1의 경우 horse로 분류될 수 있는 여러가지 템플릿을 가지고 있다. (수업에 W1의 값을 이미지로 나타내면 왼쪽/오른쪽을 바라보는 말의 측면 사진이 겹쳐진 것처럼 생겼다) 점점 상위 층으로 가게 되면 그런 여러가지 템플릿에 대한 정보에 weight을 줘서 템플릿들을 combining하는 효과가 나타나게 되고 결과적으로 맨 마지막 layer에서는 특정 클래스에 대한 final score를 계산할 수 있게 된다. 

** 수업에 나온 예시를 좀 더 설명해보자면, 2개의 layer로 구성된 neural network가 있다고 하자. W1의 row 중 왼쪽 말의 이미지에 대한 템플릿과 오른쪽 말의 이미지에 대한 템플릿이 있고, 내가 분류하려고 하는 이미지는 말의 정면사진이라면, hidden layer에서는 W1*x를 구함으로서 이미지에서 W1에 있는 템플릿이 얼마만큼 존재하는 지를 구할 수 있고, 이를 비선형 함수(activation function)를 통해 일종의 점수로 나타내게 된다. W2에서는 이제 여기에서 어떤 template에 더 점수를 많이 줄 것인지 weighting을 하는 거고 그것을 final class를 위한 점수로 second layer에서 나타내게 되는 것이다!


이제 이 neural network를 실제로 생물학에서 다루는 neuron에 빗대어 설명할 수 있다. 일단 neuronsynapse를 통해(W) dendrite들을 통해 정보를 받고(x) 이 정보들을 통합해서(sigmoid) 정보를 axon을 통해 다른 뉴런에 전달하는 식(e.g. firing rate)으로 구성되어 있는데 이는 neural network에서 각 노드에서 일어나는 일과 유사하다. 실제 뇌과학자에 따르면 neuron의 activation은 relu(rectified linear unit, sigmoid와 같은 activation function의 한 종류)와 닮았다고 한다. 하지만 우리가 아는 것보다 neuron이 훨씬 복잡하게 정보를 처리하고 있기 때문에 이 비유가 neuron의 다라고 해석해서는 안된다고 lecturer는 강조한다. 가령, dendrite가 non-linear한 computation을 통해 정보를 받는다던지, synapse가 단순한 single weight보단 더 복잡한 dynamic system이라던지, 그리고 세상엔 정말 다양한 뉴런이 있다는 것이다. 그럼에도 불구하고 뭔가 뭔가 실제 뇌에서 일어나는 일에서 영감을 따와서 모델을 구현함으로써 인간의 지능에 대해 한발짝 나아가 이해할 수 있다는 점에서 굉장히 신선하고 좋았다


요약하자면, neural network의 직관적인 의미는 다음과 같다. 

1) linear layer 사이에 non-linear layer를 끼워 넣어서 함수의 복잡성을 높일 수 있다. 여기서 말하는 비선형은 정보통합의 맥락에서 좋고, 선형적이지 않은 이 세상 문제들을 풀기에 편리하다.

2) 정보를 통합한다는 게 어떤 의미인지 예시를 통해(template를 저장하는 W와 각 template에 대한 input의 점수를 통합하고 가중치를 두는 H, W2) 좀 더 직관적으로 이해할 수 있다.

3) neural network는 실제 뉴런들이 신호전달하는 것을 매우 high한 레벨에서 흉내낸다는 것에서도 의의가 있다. 

4) 이건 summary하면서 나온 설명인데 neuron들을 fully connected layer로 구현함으로써 matrix 형태로 만들 수 있고, 이는 vectorize를 통해 연산속도 향상에 도움을 준다.(왜 neural network이 딥러닝에 쓰였는지 앞의 back prop처럼 연산하는 측면에서도 이해할 수 있다!)


뭔가 각잡고 강의 노트를 이쁘게 쓸 생각은 아니어서 그런지 글의 구성이 조잡하게 보인다. 뭐 어떤가! 나는 이런식으로 강의노트를 정리하는 것도 나쁘지 않아보인다. 무엇보다 이 날은 이런 식으로 이전보다 더 직관적으로 back prop과 neural network에 대해서 이해할 수 있어서 너무 너무 기쁘고 강의도 너무 재밌고 깨달음의 즐거움을 글로 녹여내고 싶었다. 왜 cs231n이 명강이라고 사람들이 극찬하는 지 이전보다 많이 이해할 수 있었던 좋은 시간이었다. :>

반응형

댓글