2020. 7. 23. 22:05ㆍML in Python/Knowledge
1. 인공 신경망 모형의 배경
인공 신경망 모형은 인간의 뉴련의 자극전달 과정에 아이디어를 착안하여 발생한 머신러닝 알고리즘이다. 인간의 뉴런은 시냅스를 통하여 다른 뉴런으로부터 자극을 전달받고 시냅스를 통하여 다른 뉴런에게 자극을 전달하는 과정을 통해서 학습을 진행한다.
이 자극 전달의 과정을 알고리즘에서 layer와 perceptron으로 뉴런과 시냅스를 구성하여 연결지은 것이 바로 인공신경망 모형이다. 하나의 뉴런은 Neural Network 모형에서 하나의 perceptron과 대응되며, 시냅스의 역할은 여러 layer를 잇는 weight/bias(error)가 한다.
위의 그림에서 A는 인간의 뉴런을 형상화 한 것이다. 그리고 C는 이 뉴런들의 연결을 보여주는 것이다. B그림을 보면 X1~Xn의 데이터가 들어가서 Yi 하나를 출력하는 하나의 퍼셉트론의 형태이고 D는 여러 퍼셉트론을 여러층에 걸쳐서 연결시킨 Multi Layer Perceptron을 나타낸 것이다. 이제부터 이러한 Neural Network의 구조에 대해 자세하게 알아보자.
2. 퍼셉트론(Perceptron)
아래는 퍼셉트론의 구조를 도식화한 것이다. 퍼셉트론은 크게 보면 inputs / weights / transfer function / activation function으로 이루어진다고 말할 수 있다.
inputs은 입력 데이터이다. 이 입력데이터들은 n차원으로 이루어져있을 때, weights(가중치)의 개수 또한 n개이며 개별 변수마다 connected되어 표현된 것이 transfer function이다.
예를 들어 2개의 입력변수 X1,X2가 존재한다고 할 때, transfer function은 아래의 형태와 같다.
그리고 이 transfer function은 X1~X2를 X1 ~ Y의 관계로 표시한다면, 이는 선형식의 형태로 볼 수 있다. 즉 Neural Network는 최적의 분류/예측을 위해 선형식을 사용한다는 것을 알 수 있다. 하지만, 대부분의 출력결과물과 과정을 보듯이 단순한 선형식의 형태로 이루어지진 않는다. 이는 아래서 추가적으로 보겠다.
그리고 이 transfer function을 거친 값이 activation function으로 들어가 출력값을 구하는 과정을 거친다. 가장 기본적인 인 activation function으로는 Step function과 sigmoid function이 있고 이 function의 형태는 위와 같다. 최근에 가장 많이 쓰며 주목받는 activation function으로는 ReLU계열의 function이 존재한다. 더 자세한 내용은 아래의 activation function 순에서 다루겠다.
다시 돌아와서, activation을 거친 값은 분류 문제를 진행할 경우 임계값(threshold)를 기준으로 특정 집단으로 구분된다. 이것이 하나의 퍼셉트론에서 최종 결과물(Output)으로 도출되는 것이다.
물론, 이 퍼셉트론이 여러개 존재할 경우 한 퍼셉트론의 출력값이 다른 퍼셉트론의 입력값이 되며 가중치를 학습하는 과정을 반복한다. 그리고 퍼셉트론이 여러개가 존재하며 이 단계가 반복되는 퍼셉트론들이 모인것을 "다층 퍼셉트론(Multi Layer Perceptron)"이라고 말한다.
3. 활성함수(Activation function)
activation function은 은닉층(hidden layer)를 의미있게 쌓아주는 역할을 한다. 만약 위의 transfer function을 통해서 나온 값이 activation function을 거치지 않고 바로 출력된다면 이는 선형식에 불과하게 된다. 그리고 선형식은 예측 및 분류 작업에 있어서 한계를 분명하게 가진다. 이러한 한계점을 제거하기 위해서 activation function에 넣는데 activation에 넣는 이유를 알기 전에 activation function의 특징을 알 필요가 있다.
활성함수(activation function)의 특징은 1. 연속성 2. 비선형성 3. 단조증가 4. bounded 5. 점근성 이렇게 다섯가지가 대표적으로 있다. 이 특징을 보면 선형식이 activation의 function으로 들어가면 위의 특성을 갖는 형태로 변환이 되는 것이다. 그리고 변환되는 형태는 activation의 종류마다 다르다.
Step function
step function의 수식은 위와 같다 transfer function의 값에 따라서 0을 임계값으로 하여 0과 1로 결과를 이분법적으로 분류하는 것이다. step function의 형태는 아래와 같다.
Sigmoid function
sigmoid function은 가장 기본적인 activation function중 하나이다. sigmoid function은 딥러닝 이전에 많이 사용되었으며, 미분계수가 자기 자신으로 표현될수 있는 비선형 구조의 결과를 도출해준다는 장점이 있다. 하지만, gradient vanishing문제를 야기하기에 딥러닝( 많은 은닉층-hidden layer가 사용)에는 잘 사용하지 않는다.
sigmoid function의 형태는 위와 같다.
ReLU
ReLU함수는 위의 형태를 띈다. 이 함수는 0보다 큰 경우 기울기를 유지해주기 때문에 gradient vanishing 문제를 해결해준다. 그리고 함수가 매우 간단해서 계산이 간단하기에 학습속도가 매우 빠르다는 장점이 있어서 최근에 많이 쓰인다.
그래프의 형태는 위와 같다.
leaky ReLU
leaky ReLU 함수의 형태는 다음과 같다. 이는 transfer function 값이 음수일 때, 생기는 영향력이 없데이트가 안되는 문제점을 보완하고자기존 ReLU함수에서 음수 부분만 보정된 것이다.
그래프의 형태는 다음과 같다. 음수 부분을 보면 미세하게나마 기울기가 존재하는 것을 보인다.
ELU(Exponential Linear Unit)
ELU함수는 ReLU의 음수의 영향력을 무시하는 단점을 보완하고자 leaky ReLU함수처럼 보완한 것이다. 방식은 leaky ReLU함수와 다르다. ELU함수는 transfer function의 값을 activation시키는데 있어서 exponential 함수를 사용한다. 수식의 형태는 다음과 같다.
이 수식은 음수와 양수에 따라 다른 영향치를 보이는 듯하지만, 미분이 가능한 함수이며 아래와 같은 형태를 띈다.
4. 경사하강법(Gradient Descent)
Gradient descent는 Neural Network에서 weigths를 업데이트 시키는 기본적인 알고리즘의 방법이다. gradient descent를 통해서 loss function의 loss가 낮은 방향을 찾아가도록 학습하도록 한다.
위의 이미지는 위키피디아에서 가져온 사진으로, 위의 식을 가중치로 표현하면 아래와 같아진다.
위의 식에서 Wdot_i는 i번째 변수에 수정된 weight, w_i는 수정 전의 i번째 변수의 가중치이며, LR는 Learning Rate의 약자로 얼마나 조금씩 가중치의 최적해(loss를 가장 낮추는 지점)을 찾아갈 것인가를 뜻한다. 이는 weight를 변화시키는 정도로 값이 너무 커지면 해를 찾기가 힘들고 너무 작으면, 수렴하기까지 시간이 너무 오래걸리게 된다. E는 정의된 error값으로 Target - Outcome(Loss/Bias)를 뜻한다. 그리고 Xi는 데이터의 변수(입력값)인 것이다.
Gradient Descent의 과정의 순서는 다음과 같다.
1. 임의의 LR/Wi를 설정
2. 출력값을 계산
3. E(error)계산
4. wi` 업데이트
5. 최적해를 찾을 때까지 2~4 반복
이 순으로 최적해를 찾아나가는 것이 바로 Gradient descent 알고리즘이다. 하지만, 문제는 한 층만 가진 perceptron에서는 gradient descent로 학습을 시키겠는데, 만약 layer가 많아지면 어떻게 되나? 모든 퍼셉트론에 걸쳐서 계속적으로 Gradient Descent를 사용하나? 이럴 경우 문제가 발생할 수 있는데 중간의 Layer에서 최적해로 찾은 것이 마지막에 갔을때는 최적해가 아니며 마지막 layer에만 fitting이 된 값이 발생할 수 있게된다. 그렇기에 여러 layer에 걸쳐서 학습을 시키기위해 오차역전파(BackPropagation)이라는 알고리즘이 사용된다.
5. 오차역전파(BackPropagation)
오차역전파(backpropagation)는 단층 퍼셉트론에서 다층 퍼셉트론으로 진화시켜준 알고리즘이다. 이는 머신러닝의 10여년의 정체기를 해결시켜준 방법이기도 하다. backpropagation은 Multi layer perceptron을 학습시키기 위한 방법으로 Output layer에서 에러의 변화량을 앞선 layer로 전달한다는 개념이다.
아래 이미지를 한 번 봐보자.
첫 번째 Xi(1)은 입력 layer이다. hidden layer는 Xi(2) Output layer는 Xi(3)이다. 우리는 여기서 W1.1(1)을 알고싶다고 해보자. 이 가중치 W1.1(1)을 알기위해서 뒤에서 부터 e의 변화량을 미분을 통해 접근하여 알아가고자 한다. 이때 e의 변화량은 각 단계의 w에 영향을 받는다는 것에 착안한다.
예를 들어서 다시 말하면, 우리가 W1.1(1)을 알기 위해서 뒤에서 부터 e의 변화량을 앞으로 전파하는데 e1(3)의 변화량은 w1.1(2)의 영향을 받아서 전파가 된다는 것이다. 이를 꼭 기억해보자. 더 간단하게 보기위해 아래의 그림을 봐보자.
위의 그림을 설명하면
1. (i)는 i번째 레이어를 뜻한다.
2. v는 activation function으로 전달되기 전의 선형식의 상태이다. 즉 x와 w의 combination상태이다.
3. 변수들 아래에 위치하는 1or2는 i번째 레이어에서 첫 번째 노드 or 두 번째 노드라는 것이다.
4. w의 경우 아래 위치에 존재하는 i,j는 현 레이어의 i번째와 다음 레이어의 j번째 노드를 연결시키는 weight이다.
그렇다면 위의 backpropagation을 알아보기 위해서 error의 변화량부터 하나씩 알아가보자.
0. 먼저 모델의 정확도를 평가하는 척도로서 L을 사용하는데 이는 한 노드에서 weight들로부터 발생하는 error들의 error를 합한 식을 L이라고 표현한다.
여기서 Li는 Squared error를 가정하여 가중평균을 내린 것으로 아래와 같이 일반화시킬 수 있다. ( 에러가 2개가 합쳐져있기에 1/2를 사용 n개면 1/n)
1. 3번째 레이어(Output Layer)의 error e1,e2의 변화량은 아래와 같다.
위의 수식은 Loss function을 transfer function의 식, 즉, perceptron에서 activation function에 들어가기 전의 선형식에 대해서 미분을 진행한 것이다.
자세하게 말한다면, k번째 레이어의 노드의 수가 nk라고 할 때,
와 같은 linear한 관계를 갖는것이다. 그리고 v는 다시 activation을 통해서
2. 이는 다음과 동일하다.
위의 식은 chain rule을 활용하여 변수간의 변화량 관계를 표현한 것이다.
3. 그리고 2번째 레이어(Hidden Layer)의 error(e1의 경우만 예시)는 3번째 레이어의 e1과 e2를 활용하여 아래와 같이 표시할 수 있다.
4. 그리고 마찬가지로 2번째 레이어의 error를 활용하여 1번 레이어의 weight를 아래와 같은 식을 통해서 업데이트 할 수 있다.
이 식은 기본적으로 아래와 같은 Gradien descent에서 나타난 것이다. 이를 일반화된 식으로 표현하자면 아래와 같이 k번째 weight을 업데이트하는 것으로 표현할 수 있다.
다시 한 번 정리를 진행해보자.
이 그림에서 W1,1(1)의 가중치를 업데이트 하기 위해서 x1(3)에서 발생한 오차의 변화량으로 부터 역으로 계산을 진행하는데 이를 종합해서 계산을 진행한다면
0. 아래와 같은 계산을 진행해야하는데
1. 위의 식에서 빨간 부분은 아래와 같이 나타나진다.
e1(3)는 위에서 빨간 부분이며 여기서 각각의 곱셈을 할 원소들은 아래와 같이 표현된다.
2. 이는 squared error를 가정한 부분이고
3. 여기는 activation function의 미분계수이며 sigmoid function일 경우 다음과 같이 나타난다.
4. 이를 종합해보면 e1(3)는
위의 식과 같아지며, (x1(3) - y1) - 오차값과 x1(3)(1-x1(3)) - activation function의 미분계수를 곱해주었다는 뜻이다.
즉, 오차값이 커질수록 값을 크게 바꾼다는 것이다.
5. 여기에
위의 결과를 곱하면 최종적으로
6. error와 앞선 layer의 x값을 통해서 weight를 업데이트 할 수 있다는 것이다.
7. 이 과정을 누적해서 반복 진행한다면 맨 앞의 weight w1,1(1)은 최종적으로 아래와 같이 표기되며,
여기서 e1(2)는 아래의 형태와 같다.
이상 복잡한 개념을 글로 설명하려 하니, 전달이 잘 되었을지 모르겠다. 결론적으로 뒤에서 부터 chain rule을 통해 오차의 변화량을 분석하여 앞 노드들의 weight들을 반복해서 update시킨다는 개념이다.
결론은 이 과정들이 Neural Network의 학습이 이루어지는 원리라는 것이다. 사실 Neural Network는 비교적 단순한 모델도 아니며 한계점도 분명히 존재하기에 최근에는 다른 많은 알고리즘들이 사용된다. 하지만, deep learning의 시발점이니 학습할 이유는 충분하다.
파이썬의 sklearn을 통해 쉽게 구현하는 방법은 아래 링크를 통해 남겨놓겠다.