종종 모델링을 하다보면 customize해서 Loss를 설계할 일이 생긴다.
논문에서 써 놓은 loss가 아닌 customize를 해서 Loss를 만들었다가 최적화가 되지 않는 현상이 발생했다.
아래의 Loss 가 내가 따로 만들었던 Loss이다. 원래 논문에서는 L2 norm 으로 구현했는데, 값이 너무 커서 임의로 mean값을 취해주고 다른 형태로 바꿔주었다.
ATT_loss = torch.sqrt(torch.mean(torch.abs(word_label_lengths - attention.to(device))))
처음에는 Loss니까 requires_grad가 있어야하나? 하고 이 flag도 넣어줬었다.
근데 requires_grad는 업데이트 되어야 하는 weight, 즉 파라메터를 설정할 때 넣어주는 것이지 Loss 계산에 필요한 레이블에 넣어주면 안된다. 직접적으로 update 되는 대상이 아니기 때문.
여차 저차 requires_grad 플래그도 빼고, 내가 만든 식이 적절한 식인지를 살펴보았다.
내가 만든 Loss는 MAE(Mean Absolute Loss, L1 Loss=> Error의 절대값의 평균) 의 변형과 유사하다.
MAE는 loss가 크던, 작던 항상 gradient가 일정하다. 아래의 그래프를 보면 알 수 있다.
따라서 오차가 크던, 작던, 그라디언트의 크기는 일정하게 유지되고 gradient descent 에서 파라메터 업데이트 크기가 일관된다.
반대로 L2 Norm 은 오차가 클 때 더 그라디언트가 크기 때문에, 큰 오차를 줄이는데 효과적이다.
나의 경우 초기 학습 단계에서 큰 오차를 초래한다. attention 값이 굉장히 크게 계산되기 때문. 따라서 L2 norm 을 사용하는 것이 빠른속도로 손실을 줄일 수 있다.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
++ 추가
MAE, MSE Loss 차이의 문제가 아니었다.
torch.sqrt 를 사용해서 발생하는 문제였는데, 이게 gradient 를 nan으로 야기했다.
sqrt 를 미분할 경우 1/(2*sqrt(x))가 되는데, x가 0으로 근접할 수록 미분값은 발산하게 되고 실제 계산에서는 nan으로 뜨게 된다.
코드에서 torch.sqrt를 제거하니 적절히 수렴하는 것을 확인할 수 있었다.
오늘도 하나 알아간다..!
'Error report > Pytorch' 카테고리의 다른 글
ERROR report: Torch.no_grad change sequence length (0) | 2024.03.04 |
---|---|
ERROR report: Pytorch rnnt loss, RuntimeError: output length mismatch (0) | 2024.02.26 |