Computer/Machine Learning

머신러닝과 딥러닝

Novelism 2021. 9. 7. 20:01

 

이미 딥러닝이 알려진지도 7년이 넘게 지났으니 생소한 것도 아니고, 처음 입문하는 사람이 아니라면 딥러닝이 무엇인지 모르는 사람도 많지 않을 것 같습니다. 5년 전쯤만 해도 직접 딥러닝을 사용하는 사람이 아닌 경우, 학회에서 발표하는 경우에도 머신러닝과 딥러닝의 개념을 잘못 생각하시는 분들이 많았습니다.

딥러닝 (deep learning)은 머신러닝 (machine learning, 기계학습)의 한 분야입니다. artificial neural network (ANN, 인공 신경망)에서 hidden layer 가 늘어난 deep neural network (DNN), 혹은 비슷한 네트워크 구조인 Restricted Boltzmann Machine (RBM)과 Deep Belief Network (DBN)에서 이름을 따온 것 같습니다. DNN이라고 해서 뭐 엄청 깊은 것이 아니고 hidden laryer가 3 정도만 넘어도 DNN이라 부릅니다. 저는 첫 논문에서 제가 쓴 모델이 별로 깊지 않아서 ANN이라 적었더니, 리뷰어가 DNN이라 적으라고 하더군요.

 

 이렇게 설명하면 딥러닝은 그저 ANN의 일종일 뿐일 텐데 왜 이렇게 별개의 이름까지 붙인 것일까요?

2010년 이전까지 DNN을 학습시키는 것이 기술적으로 어려워서 성능이 제한적이었는데, 그 후 여러 학습 기술이 개발되고, 컴퓨터 성능이 향상되고 학습에 활용할 수 있는 데이터가 늘어나면서 이전보다 더 깊은 신경망을 학습시킬 수 있게 되었습니다. 하지만 이 정도라면 그냥 ANN이라고 불렀겠지만, convolutional neural network (CNN), recurrent neural netrowk (RNN) 등 좀 더 향상된 아키텍처가 도입되면서 이전의 ANN과는 구조적으로 분명한 차이를 보여주기에 새로운 용어가 정착된 것이 아닐까 생각합니다.

 딥러닝의 초창기에는 딥러닝을 가능하게 하는 과도적인 기술들이 있었고, 지금도 사용하는 사람이 있지만 굳이 꼭 사용하지 않아도 되는 것들도 여럿 있습니다. 예전에는 딥러닝을 공부할 때 그런 과도기적인 것들도 약간 다루긴 했는데, 지금은 굳이 꼭 공부해야 할 필요는 못 느끼겠네요. 주로 RBM과 DBN 계열에서 나온 기술들이고, 층별 예비학습 방법 같은 것들이 있습니다.

 사실 지금은 표준화된 방법들을 사용하면 별다른 번거로운 작업을 하지 않고도 웬만한 것들은 잘 되니까요.

 

 딥러닝을 학습시키기 어려운 이유가 있었는데, 그런 표준화된 방법만으로도 상당수는 개선됩니다. 여기서 학습이 안된다는 이야기는 오버 피팅 여부는 신경 쓰지 않더라도, training set에 대해 loss 가 안 내려간다는 의미입니다.

Rectified Linear Unit (ReLU) activation function, 다양한 initializer (He, 혹은 Xavier), mini batch를 사용한 gradient decent (경사 하강법) 등은 지금은 너무나 당연하게 사용하고 있는데, 이 방법들을 사용하는 것만으로도 간단한 문제는 학습이 잘 되는 편입니다. 이 방법들도 꾸준히 개선되고 있습니다. 여기에 더 깊은 신경망 (수십~수백)을 학습시키기 위해선 residual block와 batch normalize를 사용합니다.

 

 

ANN에서 한 레이어에서 다음 레이어로 연결되는 연산은 다음과 같은 수식으로 주어집니다. 
$$ X_{j}^{l+1}=\sigma^{l}(\sum_{j} W_{ij}^{l} X_{i}^{l}+B_{j}^{l}) $$

여기서 \( l \) 은 layer의 인덱스이고, \( X_{i}^{l} \)은 \( l \)의 data의 \( i \) 번째 성분을 의미합니다.

\( X_{i} \)는 벡터 혹은 텐서입니다.
벡터는 \( X_{i} \)처럼 index가 \( i \) 하나뿐이고 rank는 1입니다. 행렬은 \( X_{ij} \)처럼 index가 \( i, j \)로 2개가 있고, rank는 2입니다. 차원 (dimension) 이란 \( i \)가 가질 수 있는 값의 수입니다. i=1,2,3 이면 3차원입니다.

W는 weight parameter, B는 bias입니다. 이들을 하이퍼 파라미터라고도 부릅니다.

인공 신경망은 생물의 신경망에서 따온 모델인데, 신경망 한 가닥을 모사한 것을 퍼셉트론이라 부릅니다.

여러 입력 값을 받아서, 각각에 대해서 가중치 (weight)를 반영하고 더해준 후, 적절한 역치 (bias) 값을 더해줍니다.

인공신경망은 퍼셉트론을 여러 개 모아 두고, 그것들을 레이어로 쌓은 것입니다.

위 그림은 hidden layer가 1개인 단순한 ANN의 구조입니다. 위의 수식과 그림을 비교하면 \( l \) =1 (input layer), 2 (hidden layer), 3 (output layer)입니다. \( i )\는 각 layer에서의 데이터의 element index입니다.

 검은 선이 weight \( W_{ij} \)에 대응됩니다.

\( \sigma \)는 activaton function입니다. 비선형 함수를 사용합니다. 선형 함수를 사용해버리면 layer를 많이 쌓아도 소용이 없습니다. Wij Wjk Wkl.. 등을 아무리 곱해도 Wil 하나를 사용한 것과 차이가 없어집니다. 수식적으로는 그렇고, 의미적으로 생각하면 데이터를 분류할 비선형 공간 변환이나, 논리 연산이 필요한데, 선형 연산만 쌓아서는 그런 표현이 되지 않겠죠. 

예전에는 신경망과 유사할 것 같은 sigmoid를 사용했지만, 최근에는 대부분 ReLU 및 변종을 사용합니다.

그리고 제일 마지막 output의 경우, 실수 값이 나오게 하고 싶다면 activation function을 적용하지 않고, 0과 1 사이의 값으로 나오게 하고 싶다면, sigmoid를 사용하고, output dimension이 1보다 크면서, 각 값의 합이 1인 class에 속할 확률 값 예측 문제(classification)에 적용하고 싶다면 softmax를 많이 사용합니다.

 

hidden layer가 많아지면 어떤 어려움이 생길지 생각해봅시다.

weight parameter에 별다른 initializer를 사용하지 않고, 단순히 가우시안이나 uniform 형태의 랜덤 함수를 사용하고, hidden layer에 activation function으로 sigmoid를 사용했다면...

 

입력값의 변화가 커도, 출력 값의 변화가 작습니다. sigmoid는 x값이 매우 크거나 매우 작은 경우, gradient 값이 0에 수렴합니다. sigmoid를 사용해서 layer를 깊게 쌓을 경우 vanishing gradient라는 문제가 발생합니다.
그레디언트 디센트 방법은 미분 값을 이용해서 loss 이 낮아지도록 weight 값들을 조절해야 하는데, 이때 역전파(back propagation)를 사용합니다. 그런데 아웃풋에서 인풋으로 갈수록 그래디언트 값이 매우 작아져서 초기 레이어들에 대한 학습이 진행되지 못합니다.

 

sigmoid는 0 이하일 때는 0이고 0 이상에서는 선형인 함수입니다. 0 이상일 때는 미분 값이 일정합니다. ReLU를 사용하면 층을 깊이 쌓아도 sigmoid에 비해 미분 값이 작아져서 역전파가 어려워지는 문제가 적습니다.

 초기에는 층별 예비학습 같은 방법도 있었지만, 지금은 굳이 사용할 필요는 없을 것 같습니다.
vanishing gradient의 원인을 생각해보면, 결국 sigmoid의 미분이 작아지는 데이터 값들이 많아져서인데, normalization을 이용해서 이 문제를 해결할 수도 있습니다. 결국 데이터들이 특정 구간 안에만 들어오게 한다면, 미분 값이 과도하게 줄어들지 않을 테니까요. residual network와 batch normalize를 사용하면 ReLU를 사용하지 않고 sigmoid activation를 사용하고도 학습이 가능하다는 연구 결과가 있습니다.

 

ReLU의 도입은 vanishing gradient 문제를 해결하여 딥러닝이 가능하게 된 계기중 하나이지만, (일단 loss는 내려가게 된) 그 이외에도 다양한 문제들이 있습니다. training set에 대한 loss는 내려가지만 test set에 대한 loss는 올라가는 과적합 문제가 있는데, 이를 해결하려고 다양한 규제 기법과 drupout 같은 방법들이 개발되기도 하였습니다.
이외에도 데이터의 구조에 적합하도록 뉴럴 네트워크의 구조를 변경하여 파라미터의 수를 줄이고, 시계열 데이터에 적합한 방법도 개발되었습니다.

 알고리즘의 발전뿐만 아니라 CUDA 같은 컴퓨터 성능 향상도 딥러닝의 발전에 중요한 요소입니다.

 그리고 인터넷의 보급으로 막대한 데이터가 수집되었고, 이용해서 pretraining 된 모델들이 공개되어 이들을 사용할 수도 있게 되었습니다. tensor flow, pytorch 같은 편리한 툴들이 등장도 무시할 수 없겠군요.
반면에 여전히 데이터가 부족해서 학습이 어려운 분야들도 있고, 데이터의 구조에 적합한 모델이 없는 경우도 있습니다.

 딥러닝은 주로 이미지 처리, 자연어 처리 (NLP) 음성인식 같은 분야에서 큰 발전을 이뤄왔고, 이런 문제를 풀기 위해 CNN, RNN, attention 기반의 transformer 가 개발되었습니다. 하지만 이런 아키텍처를 사용하기에 적합하지 않은 데이터에서는 기존 방법에 비해서 딥러닝이 큰 성과를 보여주지 못하기도 합니다.