역전파 알고리즘은 예측값과 실제값의 오차를 계산하고, 출력층에서 입력층으로 오차 그래디언트(gradient)를 전달하면서 신경망의 모든 파라미터에 대한 손실함수의 기울기를 계산합니다. 그리고 나서 경사하강법 단계에서 이를 사용하여 weight를 업데이트 해줍니다.

기울기 소실(Gradient vanishing)이란? 

역전파 과정에서 입력층으로 갈수록 전달되는 기울기 값(gradient)이 점차적으로 작아지는 현상으로,  weight 업데이트가 제대로 되지않게 됩니다. 입력층에 가까운 층들에서 가중치들이 업데이트가 제대로 되지 않으면 결국 최적의 모델을 찾을 수 없게 됩니다.

기울기 폭주(Gradient exploding)이란? 

기울기 소실과 반대로 입력층으로 갈수록 기울기 값(gradient)이 점차 커져 weight들이 비정상적으로 큰 값으로 업데이트되면서 결국 발산되는 현상입니다. 주로 순환신경망에서 나타납니다,

[ 기울기가 불안정해지는 원인 ] 

 

  • 기울기가 불안정해지는 원인은 로지스틱 활성화 함수와 평균이 0이고 표준편차가 1인 정규분포의 가중치 초기화방법의 조합에 있다고 밝혀졌습니다.
    • 신경망의 위쪽으로 갈수록 층마다 분산이 계속 커져서 최상위 층은 활성화함수가 0이나 1로 수렴합니다.
    • 신경망의 위쪽으로 갈수록 기울기 또한 0에 매우 가까워져서 역전파 진행시, 신경망으로 전파할 기울기가 없거나 최상위층부터 내려오면서 역전파 과정에서 점점 기울기가 작아져서 아래쪽 층에는 더이상 아무것도 남아있지 않게 됩니다.

 

기울기 문제를 완화하는 방법

이러한 기울기 문제를 완화하기 위한 몇가지 방법들이 있습니다

1. 가중치 초기화

가중치 초기화만 적절히 해줘도 기울기 문제를 완화시킬 수 있는데,가중치(weight) 초기값을 어떻게 초기화하느냐에 따라 모델 훈련 결과가 달라질 수 있기 때문입니다.

[ 글로럿 초기화 ] 

글로럿 초기화(Glorot Initialization)는 세이비어 글로럿과 요슈아 벤지오가 제안한 기울기 문제를 완화하는 초기화 방법입니다. 각 층의 출력에 대한 분산이 입력에 대한 분산과 같아야 하며, 역전파에서 층을 통과하기 전과 후의 기울기 분산이 동일해야한다고 주장했습니다. 글로럿 초기값은 활성화 함수가 선형(linear)이라고 가정하는데, sigmoid 계열(sigmoid, tanh)의 활성화 함수는 좌우 대칭이며 가운데 부분이 선형인 함수입니다. 글로럿 초기화를 하면 훈련 속도가 증가한다는 장점이 있습니다. 글로럿 초기화는 다음과 같이 무작위로 초기화를 진행합니다. 

[ 르쿤 초기화 ] 

[ He 초기화 ] 

글로럿 초기값은 ReLU 활성화 함수에서는 신경망이 깊어질 수록 출력값이 0으로 치우치는 문제가 발생하는데, kaiming he가 ReLU에 적합한 초기값을 제안했으며, 다음과 같이 초기화를 진행합니다. (He 초기화는 글로럿 초기화와 다르게 층의 출력 개수를 반영하지 않습니다)

아래 표는 앞서 설명한 초기화 전략들이 사용한 활성화함수를 정리한 표입니다.

초기화 전략 활성화 함수 분산 σ^2 (정규분포)
글로럿 활성화 함수 없음, tanh, sigmoid, softmax
르쿤 SELU
He ReLU, Leaky ReLU

 

keras에서 초기화를 진행하기위해 kernel_initializer 파라미터를 사용합니다. kernel_initializer 파라미터는 균등분포의 글로럿 초기화가 디폴트로 설정되어 있습니다.

keras.layers.Dense(10, activation='relu', kernel_initializer='he_normal')
'''
# kernel_initializer
glorot_normal / glorot_uniform(default) / he_normal / he_uniform / lecun_normal / lecun_uniform
'''

 

2. 수렴하지 않은 활성화 함수 사용

[ ReLU ]

  •  ReLU함수는  0혹은 최댓값을 가지는 양수를 표현하는 함수입니다.
  • 특정 양수 값에 수렴하지 않고 계산도 빠르지만, Dying ReLU로 알려진 문제점이 있습니다.
    • Dying ReLU 문제란? 훈련하는 동안 일부 뉴런이 0 이외의 값을 출력하지 않는다는 것입니다. 즉, 뉴런의 가중치가 바뀌어 훈련 세트에 있는 모든 샘플들에 대해 입력의 가중치 합이 음수가 되면 ReLU 함수의 기울기가 0이 되어 경사하강법이 작동하지 않는다는 것입니다.

[ Leaky ReLU ]

  • 하이퍼파라미터가 α가 z<0일때의 기울기를 결정하여 이 값을 작게하는 것이 성능이 더 좋게 나타납니다.

[ RReLU ]

  • 훈련시에는 주어진 범위에서 a의 값을 랜덤으로 선택해서 테스트시에는 그 평균을 사용합니다.

[ PReLU ]

  • a가 훈련되는 동안 같이 학습합니다
  • 대규모 데이터셋에서는 좋은 성능을 보이지만 소규모 데이터셋에서는 a까지 학습되는 경우 때문에 훈련 세트가 과대적합될 위험이 있습니다.

[ ELU ]

  • 다른 ReLU함수들의 성능을 앞지르지만, 계산이 느립니다.
  • 하이퍼파라미터 a믄 z<0일 때, ELU가 수렴할 값을 정의함으로써 그래프가 만들어집니다.
  • z<0일때, 지수함수에 기반한 그래프가 만들어집니다.
  • z<0일 때, 활성화함수의 평균 출력이 0에 더 가까워져서 기울기 소실 문제를 완화할 수 있습니다.
  • a=1이면 z=0에서 급격한 변화가 일어나지 않기 때문에 경사하강법의 속도가 빨라집니다. 

[ SELU ]

  • 스케일이 조정된 ELU 활성화 함수의 변종입니다.
  • 완전 연결층만 쌓아 신경망을 만들고 모든 은닉층이 SELU 활성화 함수를 사용하여 네트워크가 자기 정규화되게 할 수 있습니다.
  • 훈련하는 동안 각 층의 출력이 평균 0과 표준편차 1을 유지하는 경향이 있어 (분산이 유지됨) 기울기 소실과 폭주 문제를 막아줍니다.

 

3. 배치 정규화

ReLU 계열 함수와 함께 He초기화를 사용하면, 훈련 초기 기울기 소실과 폭주 문제를 감소시킬 수 있지만, 훈련중에 다시 발생할 가능성이 있습니다. 그래서 또 다른 보완점으로 배치 정규화가 필요합니다 .배치 정규화는 인공 신경망의 각 층에 들어가는 입력을 평균과 분산으로 정규화하여 학습을 효율적으로 만듭니다.

[ 배치 정규화란? ] 

배치 정규화(Batch Normalization)는 한 번에 들어오는 배치 단위로 정규화하는 것을 말합니다. 

(장점)

  • 배치 정규화를 사용하면 sigmoid나 tanh를 사용시에 기울기 소실 문제가 크게 개선됩니다.
  • 가중치 초기화에 덜 민감해집니다.
  • 훨씬 큰 학습률을 사용할 수 있어 학습 속도를 계선 시킵니다
  • 미니 배치마다 평균과 표준편차를 계산하여 사용하기 때문에 훈련 데이터에 일종의 잡음 주입의 부수 효과로 과적합을 방지하는 효과가 있습니다. (드롭아웃과 비슷한 효과) 

(단점)

  • 너무 작은 배치 크기에서는 잘 동작하지 않을 수 있습니다.
  • RNN에 적용하기 어렵습니다.

[ 배치 정규화하는 방법 ]

  1. 각 층에서 활성화 함수를 통과하기 전이나 후에 모델에 연산을 하나 추가합니다.
  2. 연산은 입력에 대해 평균을 0으로 맞추고 정규화 합니다.
  3. 정규화된 데이터(평균과 분산)에 대해 스케일을 조정하고 이동시킵니다.
  4. 배치 정규화를 위해서 알고리즘은 미니배치에서 입력의 평균과 표준편차를 추정합니다

배치정규화 식

[ 테스트 시 배치 정규화 ]

배치 정규화는 학습 시 배치 단위의 평균과 분산들을 차례대로 받아 이동 평균과 이동 분산을 저장해놓았다가 테스트의 경우 훈련할 때와 달리 입력의 평균과 표준편차를 계산할 방법이 없기 때문에 테스트 할 때는 훈련시에 구해놓았던 평균과 분산으로 정규화를 합니다. 따라서, 훈련이 끝난 후 전체 훈련 세트를 신경망에 통과시켜서 배치 정규화 층의 각 입력에 대한 평균과 표준편차를 계산하는 방법을 사용합니다.

 

4. 그래디언트 클리핑

기울기 폭주를 완화하는 방법으로, 역전파가 진행될 때 일정 임계값을 넘어서지 못하게 기울기 값을 잘라냅니다.(임계치 만큼 크기를 감소시킴). 그래디언트 클리핑은 RNN에서 유용한데, RNN은 역전파 과정에서 층을 거슬러 올라가면서 기울기를 구하게 되는데, 이때 기울기가 너무 커질 수 있기떄문입니다.

from tensorflow.keras import optimizers
Adam = optimizers.Adam(lr=0.0001, clipnorm=1.)

 

'AI > Deep Learning' 카테고리의 다른 글

optimizer (옵티마이저)  (0) 2022.10.20
activation function (활성화함수)  (0) 2022.10.20
weight (가중치)  (0) 2022.07.14
ANN (Artificial Neural Network, 인공신경망)  (0) 2022.07.14
딥러닝을 위한 Data  (0) 2022.07.08

+ Recent posts