딥 러닝: 기울기 소실과 폭주 (Gradient Vanishing / Exploding)
MLP를 학습시키는 방법에서 역전파(Backpropagation)가 있었다. 역전파는 출력층(output layer)에서 입력층(input layer)으로 거꾸로 오차 그래디언트(gradient)를 흘려보내며 각 뉴런의 입력값에 대한 손실함수의 그래디언트를 계산한다. 이렇게 계산된 그래디언트를 경사 하강법 단계에서 각 가중치 매개변수(W, b)를 업데이트 해준다.
하지만 위의 그림처럼 hidden layer가 많으면 많을수록 오차 그래디언트가 작아져 결국 가중치 매개변수가 업데이트되지 않는데, 이를 그래디언트 소실, 기울기 소실(gradient vanishing)이라고 한다. 이와 반대로 오차 그래디언트가 너무나 커져 오차가 무한대로 갈 경우, 학습이 되지 않아 이를 기울기 폭주(gradient exploding)이라고 한다.
이러한 기울기 소실이 일어나는 이유는 Sigmoid 함수때문이다. 각 레이어의 activation function으로 sigmoid 함수를 사용한다면, 다음 레이어로 넘겨주는 값이 0과 1 사이이다. 이러한 방식이 여러번 지속된다면 sigmoid 함수의 중첩으로 인해 오차 그래디언트가 점점 작아지며 마지막에는 0에 수렴하기 때문에 backpropagation이 정상적으로 작동하지 않는다.
따라서 이러한 sigmoid 함수를 대체할만한 함수는 tanh, ReLU, Leacky ReLU 등이 있으며, 대부분 ReLU 계통의 함수로 activation 한다.
ReLU 함수에 단점이 없는 것도 아니다. 만약 어떠한 가중치(W, b)가 0으로 초기화되어 있다면 backpropagation 과정에서 그 노드 이전의 노드들의 gradient는 모두 0이 되어 활성화가 되지 않을 것이다. 또한, 가중치가 음수로 초기화되어 있다면, 음수일 경우의 ReLU의 함수값은 0이므로 똑같이 0으로 되어 그 이전 노드들이 활성화되지 않을 것이다. 이럴 경우를 dead ReLU라고 하며, 이러한 문제를 해결하기 위해 ReLU 함수의 변형들이 나오게 되었다. 아래는 그 중에서 Leaky ReLU의 모습이다.
따라서 여기서 알 수 있는 것은, 가중치를 모두 0으로 초기화하면 안된다는 것이다.
그럼 어떻게 가중치를 초기화해야할까?
가중치는 작은 난수(small random numbers)로 초기화해야한다. 그 이유는 활성화 함수가 sigmoid일 경우 만약 가중치 초기값(절대값)을 큰 값으로 한다면 0과 1로 수렴하기 때문에 그래디언트 소실이 발생하게 된다. 또한 활성화 함수가 ReLU일 경우 절대값이 클 경우 음수일 때는 dead ReLU 문제가 발생하고, 양수일 때는 그래디언트 폭주가 일어나게 된다.
그리하여 나온 방법들이 Xavier initialization과 He initialization이 있다. Xavier initialization은 Sigmoid와 같이 activation function이 linear일 때 사용한다.
He initialization은 ReLU 계열의 activation 함수에서 사용한다.