1. 활성화 함수
1. 인공 신경망의 간략도
2. 활성화 함수란?
네트워크로 분류할 때, 분류기가 비선형 분류기로써 역할을 하기 위한 비선형 함수이다. 위 그림에서 활성화 함수 부분이 빠진다면 각 노드는 *와 + 등 선형 연산만 하게 되므로 이런 네트워크는 비선형 데이터를 분류하지 못하게 될 것이다.
3. 활성화 함수의 종류
1. Sigmoid
가장 초기의 활성화 함수로 뉴런에 대한 직관적인 해석으로 탄생한 활성화 함수이다. 하지만 현재에는 잘 사용하지 않는데 다음과 같은 3가지의 이유가 있기 때문이다.
첫째로는 레이어를 거듭할 수록 기울기가 0에 가까워 지기 때문이다.
그 이유는 Sigmoid의 정의 때문인데, 0에서 - 혹은 +로 발산할 수록 gradient는 0에 가까워지고, 이것이 레이어가 깊어질 수록 backprop 중 낮은 레이어의 모든 뉴런은 0에 가까운 gradient를 갖게 되기 때문이다.
두번째로는 Sigmoid의 output이 zero-centered하지 않기 때문이다. 즉 범위가 [0,1]이기 때문이다.
이것이 어떤 문제를 야기한다는 것일까? 다시 뉴런의 간략도를 다시 확인해보자.
Activation function이 sigmoid라고 가정할 때 이전 layer의 output인 x0, x1, x2...의 값은 [0,1]의 범위의 양수값일 것이다.
이전에 backpropagation을 다시 리마인드 해보자면, 최종 output의 현재 레이어의 input인 x0, x1, x2...에 대한 미분 값은 upstream gradient * local gradient였다.
이때 upstream gradient를 dL/df라고 표현하고, local gradient는 d (sum(x_i*w_i + b)) / d w_i이므로, x_i일 것이다. 따라서 Activation function이 sigmoid 일때 gradient는 x_i * dL/df이다.
여기서 앞서 말한대로 x_i가 sigmoid의 결과값일테니 양수이므로 gradient는 dL/df에 의해서만 결정된다. 즉, w_0, w_1, w_2...의 gradient는 즉 W의 gradient는 모두 양수이거나 모두 음수일 것이다 (왜냐하면 부호가 upstream gradient에 의해서 결정되므로)
그렇기 때문에 다음과 같은 상황이 생길 수 있다.
파란색이 w의 최적의 벡터라고 할 때, w는 모두 양수이거나 모두 음수인 경우밖에 없으므로, (+,-)로 가지 못한다. 그래서 (+,+), (-,-)벡터의 지그제그의 형태로만 변형될 수 있다는 것이다. 이는 학습의 속도에 영향을 미치는 문제이다.
또한 이것이 data가 zero-centered가 되도록 전처리하는 이유이다.
세번째 문제로는 sigmoid의 지수 연산이 컴퓨팅적으로 비싼 연산이라는 문제가 있다.
2. tanh
Sigmoid에서 위 문제들을 풀기 위해 변형하여 나온것이 이 tanh라는 활성화 함수이다.
[-1,1]이라는 범위를 갖으므로, zero-centered문제는 해결되었지만, 여전히 local gradient의 범위로 인해 layer를 거듭할 수록 gradient를 죽인다는 문제는 해결하지 못한다.
3. ReLU (Rectified Linear Unit)
계산이 매우 단순하므로 계산 비용적으로도 효과적이고, 범위또한 (0, inf)이므로 gradient가 0에 가까워지지 않는다. 이와 같은 이유로 앞선 방식보다 6배 정도 빠르게 수렴한다고 한다. 하지만 ReLU에도 문제점이 있는데, output이 zero-centered하지 않는다는 점이다. 또한 gradient가 0 혹은 1이기 때문에 dead ReLU문제가 발생할 수 있다.
dead ReLU란?
우선 하나의 뉴런에 대하여 본다면 입력은 이전 레이어에서의 ReLU의 결과값이므로 양수일 것이다. 만약에 w가 모두 음수를 띈다면 output도 0이 될 것이고 backpropagation도 일어나지 않을것이다 (ReLU의 미분값은 0보다 작다면 반드시 0이므로)
이때 이 뉴런은 더 이상 0외의 값을 출력하지도, 0외의 값으로 gradient를 업데이트 하지도 못하게 되므로 이 뉴런은 dead ReLU상태에 빠지게 된다.
그럼 어떨 때 Dead ReLU상태로 빠지게 될까? 우선 이 상황이 가중치 W에 인해 발생하는데, 두가지 경우로 세분화 할 수 있다. 첫째로는 잘못된 가중치 초기화로 인해서 Data Cloud를 벗어날 때이다.
두번째로는 learning rate를 너무 크게 준 경우이다. learning rate가 너무 크면 data의 manifold를 벗어나므로 dead ReLU가 된다.
이를 극복하기 위해서 ReLU를 초기화 할 때 작은 상수값(bias)을 더하여 조금이라도 이 상황을 벗어나게 하는 경우도 있다고 한다.
4. Leaky ReLU, 5. PReLU(Parametric Recifier)
Dead ReLU 문제를 해결하기 위해서 변형된 ReLU이다. 0인 구간이 없으므로 업데이트가 되지 않는 Dead ReLU상황이 발생하지 않는다.
PReLU는 Leaky ReLU에서 0.01으로 설정된 음수의 그래프를 파라미터로 조정할 수 있게 한 방식이다.
6. ELU(Exponential Linear Units)
ReLU의 모든 장점을 가지면서, ReLU들 보다 output의 평균이 0에 가깝고(Closer to zero mean output) Leaky ReLU에 비해 노이즈에 대해 강하다는 추가 장점이 있따.
하지만 지수 연산이 비싸고, sigmoid와 같이 gradient가 0에 가까워질 수 있다는 단점이 있다.
7. Maxout
nonlinear하면서 ReLU와 Leaky ReLU를 일반화 한 것이다. 뉴런이 죽지도 않으며 gradient가 0에 가까워지지도 않는다. 하지만 두배의 파라미터가 필요하다는 단점이 있다.
2. 데이터 처리
이전에 Sigmoid에서 입력이 언제나 양수라면 gradient가 모두 양수이거나 음수인 경우만 발생한다고 했었다. 이전에는 sigmoid의 결과값이 언제나 양수이기 때문에 그런 경우가 발생했지만, 데이터가 모두 양수이거나 음수일때도 그런 경우가 발생할 수 있다. 그렇기 때문에 data를 normalize해줄 필요성이 있다.
이는 단순하게 입력 데이터에 대한 normalize이므로 첫번째 레이어에서만 해당된다는 것을 인지하자.
이렇게 normalize해주는 이유에는 이외에도 모든 차원이 결과 및 update에 동등한 영향을 끼치게 하기 위해서이다. 어떤 값은 0~10^100의 범위를, 어떤 값은 0~1의 범위를 갖는다면 input의 차원별로 결과에 미치는 영향이 매우 달라지기 때문이다.
이외에도 PCA와 Whitening등을 이용하기도 한다더라~
하지만 실제로는 이미지에 대해서는 이렇게 복잡한 것 대신에 zero-center만 한다더라. 모델별로 채널 전체의 평균을 이용할 수도, 채널별로 독립적인 평균을 사용할 수도 있다. 채널 전체의 평균을 이용하는 모델로는 AlexNet이 있고, 채널의 평균을 이용하는 모델의 예로는 VGG Net이 있다.
이렇게 데이터를 전처리 해주는 이유는 optimize를 더 쉽게 할 수 있기 때문이다. 아래 그림을 살펴보자.
데이터가 normalize되지 않으면 분류기가 가중치 변화에 매우 민감하지만 normalize하면 덜 민감함을 확인할 수 있다.
3. 가중치 초기화
네트워크의 가중치를 어떻게 초기화 시킬까? 가장 쉬운 방식은 0으로 초기화 시키는 것일것이다. 하지만 이 방식은 몇가지 문제점을 갖고 있다. 0이라는 점 때문에 가중치는 업데이트가 되지 않을 뿐더러, 모든 뉴런의 가중치가 동일하므로 학습하더라도 대칭성(Symmetry)을 깰 수 없을 것이다.
그렇다면 가중치를 서로 다른 수의 값으로 초기화시켜야 할 텐데, 어떤 범위의 값을, 어떤 분포로 초기화 해야할 지에 대해 몇가지 예시를 보고 특징을 살펴봄으로써 직관을 가져가보도록 하자.
1. 작은 값으로 초기화
첫번째 아이디어는 평균이 0이고, 표준분포가 1e-2인 가우시안 분포를 만족하는 작은 랜덤 값들을 이용하여 가중치를 초기화한다고 생각해보자.
가중치의 크기가 작기 때문에 작은 네트워크 모델에서는 잘 작동하겠지만, 깊은 네트워크라면 gradient가 점점 작아지는 문제를 가질 것이다. 이를 통계를 이용하여 살펴보자.
layer가 깊어질 수록 뉴런의 출력값이 빠르게 0에 수렴하는 것을 확인할 수 있었다. 이는 아까 서술한 대로 가중치가 너무 작기 때문에 결과값도 0에 가까워 지는 것이다. 이는 "초기화"된 가중치에 대한 결과이므로 학습이 반복되면 이런 경향이 깨지지 않을까? 라고 할 순 있지만, 가중치가 너무 작기 때문에 upstream gradient도 작게되고 그렇게 되면 gradient의 변화량이 작아지므로, 이런 경향을 쉽게 깨기는 어렵다.
2. 큰 수로 초기화
그렇다면 큰 수로 초기화 한다면 어떨까? 이번에는 평균이 0이고, 표준분포가 1인 가우시안 분포를 만족하도록 랜덤하게 초기화 해보자. 이런 경우에는 가중치의 표준분포가 너무 크기 때문에 모든 뉴런의 출력이 이분화될 것이고, 학습이 불안정할것이다. 이를 분포를 보며 확인해보자.
값들이 Saturate된 것을 확인할 수 있다.
3. 입출력의 분산을 이용한 초기화 (Xavier Initialization)
입출력의 분산을 만족하는 가우시안 분포에서 랜덤하게 가중치를 초기화 시키는 방식이다. 입출력이 작다면 그만큼 작은 가중치를 곱하고, 입출력이 크다면 그만큼 큰 가중치를 근다는 아이디어를 이용한 방식이다. 분포를 보면서 어떤 경향성을 갖는지 한번 살펴보자.
가우시안 분포를 갖는 꽤 합리적인 방식이지만, Activation이 Linear해야 한다는 가정이 존재한다.(이 예시에서는 tanh를 사용하고 있고, 0 근처의 active region안에 있다고 가정하에 있다) 만약에 그럼 이 가정을 어긴다면 어떤 분포를 보일까? 이번엔 ReLU를 이용해서 이를 어긴 통계를 보자.
ReLU의 특성으로 Gradient 영역의 절반이 0을 갖기 때문에 레이어를 거칠 때 마다 약 절반의 유닛을 kill함을 확인할 수 있다. 레이어가 깊어질 수록 대부분의 결과값이 0이 되었다.
이러한 문제점을 해결한 노력은 존재했는데, 그 중 한 논문에서는 초기 가중치를 조정할 때 2를 나눠줌으로써 이것을 해결하고자 하였다. 이 의도는 가중치의 크기를 키움으로써 죽는 뉴런의 수를 줄이고자 하는 것이다. 즉, 어차피 절반이 사라지니, 이를 고려하여 그만큼 나눠주자는 것이다. 이에 대한 결과는 다음과 같다.
이전 결과에 비해 준수한 분포를 이루고 있음을 확인할 수 있다. /2라는 단순한 연산이 트레이닝에 엄청난 영향을 미쳤다.
이와 같이 가중치를 어떻게 초기화 하는지가 학습에 매우 큰 영향을 줌을 여러가지 초기화 방법을 비교하면서 살펴보았다. 그렇기 때문에 실제 이에 대한 연구도 활발하게 이루어 지고 있는 실상이다. 일반적인 상황에서는 Xavier initialization을 추천한다고 한다. 또한 layer가 깊을 수록 weight의 초기화의 중요도가 올라감을 확인할 수 있었다.
3. Batch Normalization (BN)
1. Batch Normalization?
이전에 입력 데이터를 Normalize하고 그 결과를 보았다. 하지만 이는 단순히 입력 데이터에 대한 것이고, 레이어를 지나면서 이는 깨지게 된다. 만약 어떤 레이어에서 각 차원에 대해 unit gaussian형태를 띄게 하고자 사용되는 것이 이 Batch Normalization이다. 학습이 윤활하기 위해서는 activate한 뉴런이 많아야 할텐데 이를 가우시안 범위로 activation을 유지시키는 것이다.
입력으로 들어온 데이터의 각 차원에 대한 평균과 분산을 구하고, 이를 이용하여 Normalize한다.
이렇게 Batch normalization을 해주는 이유는 잘못 초기화 된W가 쌓이면서 야기된 bad scaling effect를 상쇄해준다.
// bad scaling effect는 값이 0에 가까워지거나 너무 커지는 그것을 의미하는가? 그렇다면 이것이 학습에 어떤 악영향을 주는가?
BN는 일반적으로 Fully Connected layer(FC) 나 Convolutional layer의 이후에 삽입되거나, nonlinearity전에 삽입된다.
2. Batch Normalization의 복구
그런데 activation이 gaussian분포를 띈다는게 무조건 좋다는 것인가? normalize하지 않고 saturate하게 두는 것이 더 효과가 좋지 않을까? 라는 의문이 들 수 있다. 그렇기 때문에 이 정도를 조절할 수 있도록 할 수 있다. 그 방법은 normalize를 우선 하고, saturate할 정도에 따라 원본 데이터로 복구할 정도를 결정하는 것이다. 이를 통해 우리는 얼마나 saturate할지에 대한 유연성을 얻을 수 있다더라~
r와 b는 하나의 파라미터로 학습되면서 Normalize되기 전인 입력 데이터와 완전 동일하게 되지는 않지만 이 과정을 거침으로써 유의미하게 변경된다.
3. Batch Normalization의 장점
이렇게 BN을 거치면, 다양 한 장점이 있는데, gradient의 흐름을 윤활하게 해주며 더 큰 learning rate를 사용할 수 있고, 초기화에 대한 의존도를 낮춤으로써 학습을 더욱더 강직(robust)하게 해주기 때문이다. 이는 regulazation의 형태이기 때문에 dropout의 필요성을 줄인다. 왜냐하면 하나의 deterministic한 샘플이 정규화 되어 그 영향도가 줄어들게 되기 때문이다.
4. Train time에서의 Batch Normalzation
train time에서는 실제 입출력 된 값을 사용하는 것이 아닌 train time때 계산된 평균과 분산을 이용한다. 왜냐하면 네트워크의 학습 데이터로 부터 전체 데이터에 대한 평군과 분산을 어느정도 예측할 수 있다고 여겨지기 때문이다.
4. Learning rate 설정
learning rate는 학습에 중요한 하이퍼 파라미터 중 하나이다. 적절한 learning rate를 발견하기 위해서는 값을 바꿔가면서 네트워크에 알맞은 값을 찾아야 한다.
그렇다면 어떻게 값을 변경해야 할까? 우선 learning rate를 극한으로 설정할 때 어떤 경향성들을 나타내는지 확인해보자.
첫번째로는 learning rate를 작게 한 경우이다.
학습이 진행되지만 loss가 거의 변하지 않음을 확인할 수 있다.
반대로 learning rate를 크게 하면 어떨까?
학습이 진행되면서 너무 커지기 때문에 NaN (Not a Number)오류를 띄우게 되었다.
learning rate를 극한으로 뒀을 때 나타나는 경향성을 바탕으로 올바른 learning rate를 발견하자. (일반적으로 1e-3 ~ 1e-5]라더라~
5. 하이퍼 파라미터 설정
먼저 적은 에포치로 하이퍼 파라미터의 러프한 범위를 설정하고 오랫동안 미세하게 조정해가며 적절한 하이퍼 파라미터를 찾는것이 좋다.
'ML' 카테고리의 다른 글
인공지능 Learning rate, Regularization, Weight update, Transfer Learning (0) | 2021.07.05 |
---|---|
다양한 Gradient descent optimization (0) | 2021.07.05 |
합성곱 신경망 (0) | 2021.07.01 |
역전파와 신경 네트워크 (0) | 2021.07.01 |
ML-Agent 학습 환경 디자인 (0) | 2021.05.28 |