체크포인트 선정하기

학습이 끝나면 보통 eval/loss가 가장 낮은 체크포인트를 골라 추론에 쓴다. 나도 그렇게 했는데, 정작 loss가 더 높은 마지막 epoch 체크포인트가 실제 점수는 더 높게 나와서 한참 갸웃했다. WandB 차트를 보면서 어떤 체크포인트를 써야 하는지 다시 생각했던 걸 정리해봤다.

loss가 낮은 걸 골랐는데 점수가 더 낮았다#

처음엔 당연히 eval/loss가 최저인 지점을 추론용으로 썼다. 그런데 오히려 loss가 더 높은 마지막 epoch를 썼을 때 점수가 0.6986에서 0.7336으로 올랐다.

checkpoint-paradox-testscore.png

리더보드 제출 결과인데, 아래쪽 lora(1번)가 loss 최저 지점, 위쪽 light_cp(2번)가 마지막 epoch다. loss로 고른 1번이 더 낮은 0.6986, loss가 더 높았던 2번이 0.7336이었다.

차트를 보면 왜 그런지 보인다#

WandB 차트를 같이 놓고 보니 이유가 드러났다.

checkpoint-paradox-wandb.png

오른쪽 eval/loss를 보면 1번 지점(초반)에서 loss가 가장 낮고, 이후 학습이 진행될수록 loss가 계속 올라간다(2번 방향). 그런데 왼쪽 eval/macro_f1을 보면 f1은 어느 지점(3번) 이후로 거의 평평하게 유지된다. 즉 loss는 점점 나빠지는데 정작 우리가 평가하는 지표인 f1은 떨어지지 않았다.

이건 전형적인 과적합의 모습이다. 모델이 정답에 점점 확신을 갖는 방향으로 학습되면서(틀린 걸 더 크게 틀리거나 맞는 걸 과하게 확신해서) loss는 올라가지만, argmax로 정답을 고르는 분류 성능 자체는 유지되는 것이다. loss와 우리가 진짜 보고 싶은 metric이 항상 같이 움직이지 않는다는 걸 직접 본 셈이다.

그럼 어떤 체크포인트를 써야 하나#

여기서 의문이 하나 더 생겼다. loss 최저(1번)도 마지막 epoch(2번)도 정답이 아니라면, f1이 처음으로 최대를 찍은 지점(3번)은 어떨까. 차트상에서 f1은 3번 이후로 계속 동일하고 loss는 높아지는 방향이라, 이 3번 지점이 과적합이 가장 덜 된 상태일 수 있다고 봤다.

그래서 단순히 loss 최저나 마지막 epoch을 쓰는 대신, f1이 최초로 최대를 찍은 epoch을 체크포인트로 잡는 로직을 따로 구현해 비교해보기로 했다.

추론용 체크포인트, 무엇을 기준으로 골라야 할까?

eval/loss 최저 지점이 자동으로 최선은 아니다. 평가 지표(f1)와 loss가 따로 움직이면, 최종 목표인 지표를 기준으로 체크포인트를 골라야 한다.

정리
  • loss 최저 체크포인트가 분류 성능 최고를 보장하지 않는다
  • loss는 오르는데 f1이 평평하면 과적합 신호. loss와 metric은 따로 움직일 수 있다
  • 추론용 체크포인트는 loss가 아니라 실제 평가 지표 기준으로 고르는 게 맞다

댓글