[Pytorch]Gradient Clipping

Date:     Updated:

카테고리:

Common Problems with Backpropagation

1. Vaninshing Gradient (기울기 소실)

딥러닝을 공부하면서 발생하는 오류 중에 가장 흔한 오류는 층이 깊어질수록 학습이 잘 될 것이라는 생각이다. 실제로는 Layer의 수가 증가한다고 무조건 적으로 학습의 효과가 좋아지진 않는다. 특정 임계치를 넘어가면 학습에 오히려 방해가 된다. 그 이유는 바로 Vanishing Gradient (기울기 소실) 현상 때문이다. Vanishing Gradient란 역전파(Backpropagation) 과정에서 출력층으로부터 멀어질수록 Gradient값이 점점 작아져 결국에는 0에 수렴하는 현상이다.

1

1

Vanishing Gradient가 생기는 원인은 주로 활성화 함수(Activation function)과 관련이 있다. 여러 층을 걸쳐 출력된 값이 활성화 함수를 거치고 거치고 거치다보면 층의 입출력간의 차이가 점점 작아지고 결국은 이게 미분값이 0으로 만드는 것이다. Sigmoid함수나 tanh함수를 활성화 함수로 사용할 때 발생할 수 있다. Rectified Linear Unit (ReLU)함수를 activation function으로 사용하면 예방할 수 있다.(또는 Leaky ReLU 함수를 사용)

참고: Artificial Neural Network

2. Exploding Gradient (기울기 폭발)

Vanishing Gradient와는 다르게, 기울기가 입력층으로 갈수록 점차 커지다가 Weight들이 비정상적으로 큰 값이 되면서 발산하는 현상이다.

The exploding gradients problem refers to a large increase in the norm of the gradient during training.

Such events are casued by an explosion of long-term components, which can grow exponentially more than short-term ones.

1

arXiv:1211.5063 cs.LG: The objective function for highly nonlinear deep neural networks or for recurrent neural networks often contains sharp nonlinearities in parameter space resulting from the multiplication of several parameters. These nonlinearities give rise to very high derivatives in some places. When the parameters get close to such a cliff region, a gradient descent update can catapult the parameters very far, possibly losing most of the optimization work that had been done.

Clipping

Exploading Gradient를 해결하는 방법에는 여러 가지가 있다. 그 중 가장 흔한 방법은 네트워크의 cost function을 계산할 때 weight decay로 적용되는 L2 regularization이다. Regularization 파라미터가 커지고, 가중치가 작아지면서 모형의 유용성이 떨어지고, 그 결과 모형이 더 선형적이 된다.

1. Gradient Clipping이란?

Gradient Clipping은 네트워크를 통해 역전파하는 동안 오차 도함수(Error derivative, Cost function)가 변경되거나 임계값으로 클리핑되고, 클리핑된 Gradient를 사용하여 가중치를 업데이트하는 방법이다. 오차 도함수를 rescailing함으로써 가중치에 대한 업데이트도 rescailing되어 overflow 또는 underflow의 가능성이 크게 줄어든다.

1

Effect of gradient clipping in a recurrent network with two parameters w and b. Gradient clipping can make gradient descent perform more reasonably in the vicinity of extremely steep cliffs. (Left)Gradient descent without gradient clipping overshoots the bottom of this small ravine, then receives a very large gradient from the cliff face. (Right) Gradient descent with gradient clipping has a more moderate reaction to the cliff. While it does ascend the cliff face, the step size is restricted so that it cannot be propelled away from the steep region near the solution. Figure adapted from Pascanu et al. (2013).

Gradient Clipping에는 두 가지 방법으로 구현할 수 있다.

  • Clipping-by-value
  • Clipping-by-norm

1) Gradient Clipping-by-value

value값에 따라 clipping하는 방법의 핵심은 최소 클리핑 값(minimum cliping value)과 최대 클리핑 값(MAXIMUM clipping value)를 정하는 것이다. 만약에, gradient값이 threshold값(문턱값, 임계값)을 넘어가면 그 exploading gradient 값을 threshold로 클리핑 하는 것이다. 만약 gradient값이 minimum threshold보다 작으면 이 역시 클리핑해서 최소 임계값까지 올려놓는다.

Algorithm

1

2) Gradient Clipping-by-norm

value값에 따른 방식과의 가장 큰 차이점은 Gradient의 unit vector에 임계값을 곱해 Gradient를 자른다(Clipping).

Algorithm

1

Threshold (임계값)은 hyperparameter이다. Gradient clipping은 g가 최대 임계값과 동일한 놈을 갖도록 보장한다. 이를 통해 기울기 하강이 모델의 손실 지형(loss landscape)이 불규칙적(대부분 절벽(cliff)일 가능성이 높음)인 경우에도 합리적인 동작을 취할 수 있다.

Algorithm을 보면, 기울기 norm이 정해진 최대값(역치)threshold보다 클 경우 기울기 벡터를 최댓값보다 큰 만큼의 비율로 나누어준다. 따라서 기울기는 항상 역치보다 작다. 이는 학습의 발산을 방지함과 동시에 기울기의 방향 자체가 바뀌지 않고 유지되므로, 모델 파라미터 W가 학습 해야 하는 방향을 잃지 않게 한다. 즉, 손실 함수를 최소화하기 위한 기울기의 방향은 유지한 채로 크기만 조절한다. 덕분에 신경망 기계번역과 같은 문제를 풀 때 학습률을 1과 같은 큰 값으로 학습에 사용할 수 있다.

1

다만, 기존의 확률적 경사하강법(SGD)가 아닌, 아담Adam과 같은 동적인 학습률을 갖는 옵티마이저optimizer를 사용할 경우라면 굳이 그래디언트 클리핑을 적용하지 않아도 괜찮다. 물론 안전장치로 적용하는 것이 안전하다. PyTorch에서도 그래디언트 클리핑 기능을 torch.nn.utils.clipgrad_norm 이라는 함수를 통해 제공하므로 매우 쉽게 사용할 수 있다.

import torch.optim as optim
import torch.nn.utils as torch_utils

learning_rate = 1.
max_grad_norm = 5.

optimizer = optim.SGD(model.parameters(), lr=learning_rate)

# In orther to avoid gradient exploding, we apply gradient clipping.
torch_utils.clip_grad_norm_(model.parameters(), max_grad_norm)

# Take a step of gradient descent.
optimizer.step()

Pytorch 카테고리 내 다른 글 보러가기

댓글 남기기