본문 바로가기
코딩/데이터 분석 이론 & 응용

[11] Deep Learning - Initialization & Activation function

반응형

[11] Deep Learning - Initialization & Activation function

 

 

 

 

 

 

복잡한 문제를 해결해야 할수록 , Network는 점점 더 복잡하고 깊어져야 할 것이다. Network가 점점 더 깊어지고 복잡해 짐에 따라 다양한 문제들이 발생하였다.

 

 

    • 기울기 소실(Gradient Vanishing), 기울기 폭주(Gradient Exploding)
    • 거대한 DNN을 만드는 데 사용되는 Data 부족 ( Train data 부족 혹은 label이 없는 데이터를 사용할 경우 )
    • 깊어지고 복잡한 Network 때문에 극단적으로 길어지는 훈련시간
    • 다수의 parameter들로 인해 Overfitting의 위험성 ( 특히 Train data set이 적을 때 )

 

 

Gradient Vanishing & Gradient Exploding

 

Error backpropagation을 사용하는 경우 , 신경망의 모든 오차 함수의 경사를 계산해 경사 하강법을 통해서 parameter 들을 수정한다. 이러한 backpropagation의 경우 경사가 소실되거나 , 폭주하는 경우가 생긴다. 이를 경사 소실 , 경사 폭주라고 한다. 경사 폭주의 경우 경사가 점점 커져 여러층이 비정상적으로 큰 weight를 가지게 되고 , 결국 발산한다. 이는 특히 순환 신경망 구조에서 자주 나타나는 문제다.

 

 

이러한 경사와 관련한 문제는 sigmoid activation function과 weight initialization을 개선하면서 해결되었다. 이 두 가지 function과 일반적인 initialization 방법을 사용했을 때 , 각층에서의 출력 분산이 입력 분산보다 크다는 사실이 알려졌다. 즉 층을 지날수록 분산이 계속 커지게 되며 activation function이 0이나 1로 수렴한다는 것이다.

 

 

 

 

 

 

 

 

 

위의 sigmoid 함수의 그림을 보면 커지거나 작아지면서 기울기가 0에 매우 가까워지는 것을 볼 수 있다. 따라서 이 때문에 backpropagation 단계에서 층을 지나면서 경사가 점점 소실되었고 , 약해진 경사는 아래층에 도달했을 떄 남아있지 않게 되는 것이다.

 

 

이러한 문제를 해결하기 위해서는 각 층의 출력 분산과 입력 분산이 같아야 한다. 또 역방향에서 층을 통과하기 전 후의 경사에 대한 분산이 같아야 한다. 하지만 층의 입력과 출력의 개수가 다르다면 위의 경우를 만들어 낼 수 없다. 따라서 다른 방법으로 새로운 weigth Initialization 방법이 제시되었다. 

 

 

Initialization

 

새롭게 제시된 weigth Initialization은 Xavier initialization method (세이비어 초기화 , 글로럿 초기화)다. Xavier initialization method는 앞쪽의 layer와 뒤쪽의 layer 사이의 비율로 weight를 initialization 한다. 좀 더 자세히 말하자면 이전층과 다음 층의 뉴런의 개수를 통해 범위를 만들고 가중치들을 범위 내의 무작위 수로 초기화한다고 말할 수 있다. Xavier initialization method는 2가지 경우로 나뉜다.

 

 

1. Xavier initialization method 정규분포

 

 

 

 

 

 

정규분포로 초기화 할 때는 위의 식처럼 초기화해야 한다. 무작위로 초기화한 weight들은 평균이 0 , 분산은 다음 식과 같아야 하며 정규분포의 형태를 띠고 있어야 한다. 위의 식에서 루트 안을 살펴보면 이는 위에서 이야기한 뉴런 개수의 평균이다.

 

 

2. Xavier initialization method 균등 분포

 

 

 

 

 

균등 분포의 경우 r의 식은 다음과 같이 나온다. 초기화되는 weight 들은 모두 -r과 r 사이에 균등하게 분포된다. 

 

 

위의 식들에서 (in + out) / 2를 in으로 바꾸면 이는 Lucun initialization ( 르쿤 초기화 ) 이 된다. 만약 in = out이라면 르쿤 초기화는 세이비어 초기화와 같아질 것이다.

 

 

Xavier initialization method는 분포를 고루 퍼지게 하여 특정 층이 크게 영향받거나 , 영향 주거나 하는 경우를 줄인다. 하지만 initialization method는 언제나 조합되는 activation function을 고려해야 한다. Xavier initialization method의 경우 S자 형태를 띠는 함수와 좋은 성능을 보인다. 대표적으로 위에서 살펴본 S자 형태의 Sigmoid activation function이 있을 것이다. ReLU에 대해서도 미리 살펴보자면 ReLU와 알맞은 initialization method는 He initialization method 다.

 

 

다음은 순서대로 같이 사용했을 때 성능이 좋은 initialization method - activation function - 분산(정규분포) 조합이다.

 

 

  • Xavier / Sigmoid , Softmax , 하이퍼볼릭 탄젠트 , 사용 X / 분산 = 1 / avg ( avg = (in + out) / 2 )
  • He / ReLU 혹은 ReLU 시리즈들 / 분산 = 2 / avg
  • 르쿤 / SELU / 분산 = 1 / in

 

 

keras는 기본적으로 균등 분포 Xavier initialization method를 사용한다.

 

 

keras.layers.Dense(10 , activation="relu", kernel_initializer="he_normal")

 

 

위와 같이 kernel_initializer="he_normal" 혹은 kernel_initializer="he_uniform" 을 통해 정규분포 , 균등 분포 He 초기화를 사용할 수도 있다. 또한 in이 아닌 avg 기반의 He 초기화를 위해서는 아래처럼 mode를 지정할 수 있다.

 

 

he_avg = keras.initializers.VarianceScaling(scale=2., mode='fan_avg',
	distribution='uniform')
keras.layers.Dense(10, activation="sigmoid" , kernel_initializer=he_avg)

#VarianceScaling의 경우 기본값은 scale=1.0, mode='fan_in',
#distribution='truncated_normal' 이다.

 

 

 

 

Activation function

 

아래의 이전 글에서 DNN의 문제를 ReLU를 통해 해결하였다고 하였다.

 

 

[7] Deep Learning - CNN (tistory.com)

 

[7] Deep Learning - CNN

[7] Deep Learning - CNN Neural Network Neural Network는 지도 학습으로 괜찮았지만, 90년대 이후 한계에 도달했다. 실제로 복잡한 문제를 해결하고자 할 때, 잘 해결하지 못했기 때문이다. Neural Network..

ddggblog.tistory.com

 

 

 

이는 일부만 맞는 이야기이다. ReLU 역시 완벽하지 않기 때문이다. ReLU의 문제로는 Dying ReLU가 있다. 즉 일부 뉴런이 죽어버리는 문제가 존재하는 것이다. 위의 ReLU 함수에서 볼 수 있듯이 , weight 합이 음수가 되면 값이 0으로 죽어버리게 되고 , 이는 경사를 0으로 만들어 경사 하강법이 불가능하게 만든다.

 

 

이러한 문제를 해결하기 위해 ReLU의 변종인 LeakyReLU가 제시되었다. 이 LeakyReLU는 다음과 같다.

 

 

 

 

 

위의 식에서 하이퍼 파라미터 α가 함수의 새는 정도를 정한다. 새는 정도라는 뜻은 z < 0 일 때 , 이 함수의 기울기를 이야기한다. 아래의 그림을 통해서 LeakyReLU를 살펴보면 위의 뜻을 정확히 이해할 수 있다.

 

 

 

 

 

 

 

붉은색 그래프가 LeakyReLU , 파란색 그래프가 ReLU 다. 위의 그림에서 볼 수 있듯이 LeakyReLU는 음수 부분에 기울기가 존재한다. 이 기울기는 위의 식에서 본 것처럼 α 값으로 정해진다. 위에서 볼 수 있는 작은 기울기가 ReLU와 다르게 LeakyReLU를 절대 죽지 않도록 만든다. 또한 이러한 LeakyReLU의 사용으로 통해 얻은 결론은 언제나 LeakyReLU가 ReLU 보다 성능이 좋다는 점이다. LeakyReLU 이외에도 다양한 ReLU 함수들이 존재하고 각 함수 별로 장단점이 존재한다.

 

 

 

model = keras.models.Sequential([
	#....
	#....
	keras.layers.Dense(10 , kernel_initializer="he_noraml"),
   	keras.layers.LeakyReLU(alpha=0.2),
   	#...
  	#...

 

 

 

만약 LeakyReLU를 keras에서 사용하고 싶다면 다음과 같이 사용 가능하다. 층 자체를 만들고 적용하고 싶은 층 뒤에 추가하면 된다. 

 

 

ReLU 이외에도 ELU라는 activation function도 존재한다. ELU 함수는 sigmoid와 LeakyReLU가 합쳐진 것처럼 생겼다. 식은 다음과 같다.

 

 

 

 

 

식이 아닌 그림을 보면 더욱 쉽게 이해 가능하다.

 

 

 

 

 

 

 

ELU 함수는 다음과 같은 특징을 가진다.

 

 

  • z < 0 일 때 , 음수이므로 함숫값의 평균 출력이 0에 가까워진다. 이를 통해 경사 소실 문제를 해결할 수 있다.
  • α는  z가 매우 작은 음수 값일 때 , 수렴할 값을 이야기한다. 보통 1로 두지만 변경 가능하다.
  • α = 1 일 경우 , z = 0에서 값이 급격하게 변하지 않는다. 즉 모든 구간에서 매끄러워 경사 하강법의 속도를 높일 수 있다.
  • 지수함수를 사용하므로 , 단순한 형태의 ReLU 시리즈 함수에 비해 계산이 느리다는 단점이 있다.

 

 

ELU 함수 이외에 ELU 함수의 스케일을 조정한 SELU 함수도 있다. Full connected layer을 통해 hidden layers를 구성하고 모든 activation function을 SELU로 둔다면 Network는 자기 정규화된다. 이는 훈련하는 동안 각층의 출력이 평균 0 , 표준 편차 1을 유지하는 경향을 보인다는 것을 의미한다. 이러한 점은 경사 소실과 폭주 문제를 막아준다. 따라서 SELU는 Deep 한 Network 구조에서 다른 activation function들 보다 좋은 성능을 보여준다. 하지만 이러한 자기 정규화가 일어나게 하려면 아래의 조건이 충족되어야 한다.

 

 

 

  • 입력 Feature가 표준화 (평균 0 , 표준편차 1) 되어야 한다.
  • 모든 hidden layer의 weight는 르쿤 정규분포로 초기화해야 한다.
  • Network 구조가 순차적이어야 한다. (ex wide and deep이나 순환 신경망 같은 경우 보장 X )

 

 

관련 논문에서는 Fully connected layer 일 때만 자기 정규화를 보장한다고 하지만 , 합성곱 신경망에서도 성능을 향상할 수 있다고 알려져 있다.

 

 

 

layer = keras.layers.Dense(10 , activation="selu",
	kernel_initializer="lecun_normal")

 

 

만약 keras에서 SELU를 사용하고 싶다면 다음과 같이 사용 가능하다. 층을 만들 때 activation을 "selu"로 ,
kernel_initializer을 "lecun_normal" 로 두어 만들 수 있다.

 

 

 

정리

 

  • 일반적으로 SELU > ELU > LeakyReLU (ReLU 시리즈) > ReLU > tanh > sigmoid
  • 위의 순위는 일반적인 경우일 뿐 , 각기 다른 상황에서는 다를 수 있다.
  • 예를 들어 , 자기 정규화를 시도하지 못하는 구조의 경우 ELU > SELU 가능 ( SELU가 z에서 연속적이지 않아서 )
  • 실행 속도가 중요한 model의 경우 LeakyReLU 선택 가능
  • Network가 Overfittng 되었다면 RReLU , Training Set이 큰 경우 PReLU 추가 가능
  • ReLU가 가장 보편적인 activation function 이기에 ReLU 기준으로 최적화되어있는 경우가 많다. 따라서 속도를 위한다면 ReLU를 사용할 수도 있다.
  • 제한된 컴퓨팅 파워 , 시간 속에서 최적의 activation function을 찾기 위해서 cross validation을 시도해 볼 수도 있다.

 

 

 

 

ref. "Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, 2nd Edition"

 

 

반응형