-
Transformer 계열의 훈련 Tricks카테고리 없음 2021. 11. 8. 13:20
훈련 Tricks
어떤 모델을 훈련시킬 때 무조건적으로 훈련 데이터에 초점을 두고 맞춰서는 안되고, 특이한 값들의 경우는 어느 정도의 조정을 해서 실제 데이터에 적용했을 때 큰 영향을 미치지 않도록 해야 하는 경우가 있다. 그럴 때 쓰는 방법들을 훈련 Trick이라 하기도 한다. 이번 포스팅에서는 그러한 방법들 중 자주 쓰이는 Gradient Clipping, Learning Rate Scheduling, Weight Decay 에 대해 설명하고자 한다.
Gradient Clipping
모델은 종종 학습 도중에 gradient explosion을 일으킨다. gradient explosion이란 기울기가 점차 커지다보니 여러 층이 비정상적으로 큰 가중치를 갱신하게 되어 발산하게 되는 현상이다.
출처: deep learning - Does Gradient Clipping reduce effectiveness of a RNN - Stack Overflow Gradient Clipping은 이를 방지하기 위한 방법인데 말 그대로 기울기의 값을 자르는 과정을 말한다. 기울기가 특정한 임계값을 넘을 경우 기울기를 바꾸어주는데, 이 때 기울기 벡터의 방향은 그대로 유지하되 크기만을 바꾸어준다. 즉, 학습하는 방향을 틀어버리지는 않아 손실 함수를 최소화하며 발산하지 않도록 조절해주는 정도의 역할을 한다. 아래는 pyTorch에서 Gradient Clipping을 사용하는 코드를 작성한 것이다.
import torch.nn.utils as torch_utils max_grad_norm = 5. torch_utils.clip_grad_norm_(model.parameters(), max_grad_norm )
Learning Rate Scheduling
Learning Rate는 gradient의 보폭을 의미한다. 어떤 알고리즘의 특정 목적 함수를 최적화할 경우, 경사하강법을 사용한다면 학습률을 미리 결정해두고는 하는데 이는 결과에 큰 영향을 미친다. 만약 너무 작은 Learning Rate를 적용하면 수렴 속도가 느려 전체 함수에서의 최적값이 아닌 부분적(지역적)인 범위 내에서의 최적값을 찾아버릴 수도 있다. 반대로 너무 큰 Learning Rate는 최적점 주변에서 진동이 심해 최적점을 찾지 못하거나 최악의 경우에는 발산할 수도 있다.
출처: Learning Rate Scheduling - Deep Learning Wizard 이를 해결하기 위해 Learning Rate Scheduling을 사용하는데 Learning Rate Scheduling 방법에는 많은 종류가 있다. Learning Rate를 선형적으로 증가시켰다 감소시켰다 하는 방법도 있고, cosine 함수를 사용하여 증가시켰다 감소시켰다 하는 방법도 있으며(비선형적), 증가시켰다 감소시켰다 하는 주기를 규칙적으로 하지 않는 방법도 있다. 아래는 여러 Learning Rate Scheduler를 사용해보는 코드이다.
optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 지정한 스텝 단위로 Learning Rate에 감마를 곱해 학습률을 감소시키는 방식 scheduler = lr_scheduler.StepLR(optimizer, step_size=1, gamma= 0.99) # 지정한 스텝 지점마다 Learning Rate에 감마를 곱해줘서 감소시키는 방식 scheduler = lr_scheduler.MultiStepLR(optimizer, milestones=[10,20,40], gamma= 0.1) # 매 epoch마다 Learning Rate에 감마를 곱해줌으로써 감소시키는 방식 scheduler = lr_scheduler.ExponentialLR(optimizer, gamma= 0.99) # 원하는 epoch마다, 이전 학습률 대비 변경폭에 따라 Learning Rate를 감소시켜주는 방식 scheduler = lr_scheduler.ReduceLROnPlateau(optimizer,threshold=1,patience=1,mode='min')
Weight Decay and L1, L2 Regularization
복잡한 모델의 경우 과적합(Overfitting)이 발생할 가능성이 있다. 과적합이란 학습 데이터를 지나치게 학습하여 일어나는 현상으로 학습 데이터가 실제 데이터의 일부이기 때문에 발생하는데, 학습 데이터에 대해서는 오차가 작지만 실제 데이터에 대해서 오차가 증가하게 되는 현상이다. 즉, 단순히 손실 함수를 최소화하는 학습만을 진행하다보면 특정 가중치 값들이 커지면서 더 안 좋은 결과를 내는 경우가 생긴다.
과적합은 특히 특정 가중치 값이 커질 경우 발생 가능성이 더 높아지는데 이를 해결하기 위해 손실 함수에 어떤 값을 더해주는 것을 Weight Decay라 하고, 그 어떤 값을 결정하는 방법을 L1, L2 Regularization이라 한다. L1 Regularization과 L2 Regularization의 차이는 L1은 가중치의 절댓값들의 합을, L2는 가중치들의 제곱합을 비용 함수에 추가한다는 점이다. Weight Decay 방법을 사용할 때 주의할 점은 Weight Decay할 값이 너무 커지면 과적합의 반대 현상인 과소적합(Underfitting)이 발생할 수 있다는 것이다. 아래는 Weight Decay를 사용하는 코드이다.
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, weight_decay=0.1)
https://kh-kim.gitbook.io/natural-language-processing-with-pytorch/00-cover-6/05-gradient-clipping
https://velog.io/@changdaeoh/learningrateschedule