Pytorch gradient가 흐르지 않는 경우 원인과 해결법
파이토치 모듈을 이용하여 모델을 학습하는 과정에서 train 과정이 진행되는 것처럼 보여도
실제로는 파라미터가 업데이트되지 않고 학습이 안되는 경우가 있습니다.
이번 글에서는 제가 겪었던 원인을 바탕으로 모델 학습이 되지 않을 때
의심할만한 원인 3가지 정도를 간략하게 정리해보도록 하겠습니다.
1. 모델의 layer freeze 여부 체크
모델의 각 layer의 requires_grad 속성을 확인하여 해당 값이 True로 설정되어있는지를
확인해야 합니다. 이를 확인할 수 있는 방법의 코드는 아래와 같습니다.
# 각 layer의 requires_grad가 True인지 확인
for param in model.parameters():
print(param.requires_grad)
만일, requires_grad 인자가 False로 출력되는 부분이 있다면 해당 layer는 freeze된 상태로
학습이 이루어지지 않습니다.
각 layer의 파라미터 freeze 상태는 아래의 코드로 해제할 수 있습니다.
# 각 layer의 freeze 상태 해제
for param in model.parameters():
param.requires_grad = True
2. optimizer나 scheduler에서 learning rate가 0이 되는지 확인
만일, optimizer에서 learning rate를 0으로 설정했거나
scheduler에서 감소된 learning rate가 0이나 학습에 불충분한 매우 작은 값에 도달했다면
더 이상 학습이 진행되지 않는 상황으로 파라미터 업데이트가 안될 수 있습니다.
이 경우, 의도된대로 learning rate가 각 epoch에서 적용되고 있는지를 체크해봐야 합니다.
각 epoch가 시작되는 시점에서 아래 코드로 현재 learning rate를 출력할 수 있습니다.
# 현재 learning rate 출력
print(optimizer.param_groups[0]['lr'])
3. 모델 구조가 backpropagation이 가능한 구조인지 확인
간혹, 직접 모델을 구현한 경우 gradient를 흘려보내는 것이 불가능한 구조인 경우가 있습니다.
예를 들어 sequence 생성 기반 모델에서 차례로 generate된 원소들을 모두 모은 뒤,
이 sequence 자체를 다른 모델에 투영시키면 각 위치의 원소에 대한 생성 모델에서의
gradient는 구할 수 없어 생성 모델로의 backpropagation이 불가능합니다.
이 경우, 어느 layer부터 파라미터가 업데이트되지 않고 있는지 확인해야하며
layer 이름과 파라미터의 출력은 아래 코드로 진행할 수 있습니다.
# 각 layer의 이름과 파라미터 출력
for name, child in model.named_children():
for param in child.parameters():
print(name, param)