본문 바로가기
인공신경망(DL)/Neural Networks

기울기 소실 Vanishing, 발산 Exploding

by kiimy 2021. 8. 15.
728x90
728x90

기울기 소실(Gradient Vanishing)과 발산(Exploding)

 

깊은 인공 신경망을 학습하다보면 역전파 과정에서 입력층으로 갈수록

기울기(Gradient)가 점차적으로 작아지는 현상이 발생 == 가중치 업데이트가 제대로 안된다.

결국은 최적의 모델을 찾을 수 없게 된다.

 

이를 기울기 소실(Gradient Vanishing)이라고 한다.

반대의 경우가 기울기 발산(Gradient Exploding)

1. ReLU와 ReLU의 변형들

Sigmoid 함수를 사용하면 입력의 절대값이 클 경우에 Sigmoid 함수의 출력값이

0 또는 1에 수렴하면서 기울기가 0에 가까워진다.

그래서 역전파 과정에서 전파 시킬 기울기가 점차 사라져서 입력층 방향으로 갈수록

제대로 역전파가 되지 않는 기울기 소실 문제가 발생

 

해결

은닉층의 활성화 함수로 Sigmoid나 tanh함수 대신에

ReLU나 ReLU의 변형 함수와 같은 Leaky ReLU를 사용하는 것

2. 그래디언트 클리핑(Gradient Clipping)

기울기 값을 자르는 것

- 기울기 폭주를 막기 위해 임계값을 넘지 않도록 값을 자른다.

  즉, 임계치만큼 크기를 감소

### code ###

from tensorflow.keras import optimizers

Adam = optimizers.Adam(lr=0.0001, clipnorm=1.)

3. 가중치 초기화(Weight initialization)

같은 모델을 훈련시키더라도 가중치가 초기에 어떤 값을 가졌느냐에 '

따라서 모델의 훈련 결과가 달라진다.

# 가중치 초기값을 무작위로 해주는 이유

- 만약 가중치 초기값이 모두 0이라면?

순전파시 입력층의 가중치가 0이니, 이것과 입력값을 곱하면, '모든값'이 0이 된다.

이렇게되면 입력층의 값이 무의미해지고, 역전파시에도 '모든 매개변수'가 똑같이 갱신된다는 말

1) 세이비어 초기화(Xavier Initialization) or 글로럿 초기화(Glorot)

여러 층의 기울기 분산 사이에 균형을 맞춰서 특정 층이 너무 주목을 받거나 다른 층이 뒤쳐지는 것을 막는다.

= 초기값의 표준편차가 1 / np.sqrt(n) ( n = 앞 층의 node 수 )

Sigmoid나 tanh함수와 같은 S자 형태인 활성화 함수화 사용할때 좋음( tanh 쓰면 더 좋음 )

tanh = 원점 (0,0) / 활성화 함수용으로는 원점에서 대칭인 함수가 바람직하다고 알려져있음sigmoid= (x,y) = (0, 0.5)

2) He 초기화(He initialization)

He 초기화는 세이비어 초기화와 다르게 다음 층의 뉴런의 수를 반영하지 않는다.

 

ReLU 계열 함수를 사용할 경우에는 He 초기화 방법이 효율적( 보편적이다 )

4. 배치 정규화(Batch Normalization)

- CNN에 많이 사용하는 기법

- 인공 신경망의 각 층에 들어가는 입력을 평균과 분산으로 정규화하여 학습을 효율적으로 만든다.

특성 단위로 평균과 표준편차를 계산해서 정규화
즉, 특성의 개수가 3개이기 대문에 각각 3개의 평균, 3개의 표준편차를 계산하고, 이 값을 사용해서 정규화

 

장점

*배치 정규화를 사용하면 Sigmoid함수나 tanh 함수를 사용하더라도

 기울기 소실 문제가 크게 개선됩니다.

 

*가중치 초기화에 훨씬 덜 민감해집니다.

 

*훨씬 큰 학습률을 사용할 수 있어 학습 속도를 개선시킵니다.

 

*미니 배치마다 평균과 표준편차를 계산하여 사용하므로 훈련 데이터에 일종의 잡음 주입의

 부수 효과로 과적합을 방지하는 효과도 냅니다.

 다시 말해, 마치 드롭아웃과 비슷한 효과를 냅니다. 물론, 드롭 아웃과 함께 사용하는 것이 좋습니다.

 

*배치 정규화는 모델을 복잡하게 하며, 추가 계산을 하는 것이므로 테스트 데이터에 대한 예측 시에

 실행 시간이 느려집니다.

 그래서 서비스 속도를 고려하는 관점에서는 배치 정규화가 꼭 필요한지 고민이 필요합니다.

 

단점

1. 미니 배치 크기에 의존적이다.

- 그럴일은 없겠지만 batch_size=1로하면 분산이 0이된다. 

   즉 너무(?)작은 mini_batch에서는 Batch Normaliztion이 훈련에 악영향

 

2. RNN에 적용하기 어렵다.

RNN 적용이 어렵다고한다.(= 각 시점(time step)마다 다른 통계치를 가진다. 즉, Instance 별 길이가 달라 사용할 수 없다.)

 

BN은 "각 feature의 평균과 분산"을 구해 batch에 있는 "각 feature을 정규화"
LN은 "각 input의 feature들에 대한 평균과 분산"을 구해 "각 층의 input을 정규화"

https://velog.io/@howon_98/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0Layer-Normalization

5. 층 정규화(Layer Normalization)

- RNN에 많이 사용하는 기법

- 훈련 속도를 개선하기 위함

데이터 샘플 단위로 평균과 표준편차를 계산해서 정규화
즉, 특성의 개수와는 상관 없이 Batch 안의 데이터 샘플의 수가 4개이기 때문에 4개의 평균, 4개의 표준편차를
계산하고, 이 값을 사용해서 정규화
728x90

댓글