`Early Stopping`을 처음 사용했을 때의 이야기입니다. 최근 똑같이 실수해서 메모합니다.
K-폴드 교차검증을 하는 경우, 저는 폴드 인덱스를 for 문에 넣어 전반적인 성능을 확인합니다. 이 방법은 보다 일반적인 결과를 낼 수 있어 좋지만, 아무래도 시간을 많이 잡아먹습니다. 그러다 학부때 `Early Stopping`을 알게되어 교차검증에 사용해 보았는데, 이게 웬걸... 빠르긴 한데, 첫번째 폴드만 성능이 제대로 나오고, 나머지 성능은 말도 안되게 낮게 나왔습니다.
더보기
참고
`Early Stopping`은 불필요한 학습을 줄여, 과적합을 방지하는 매우 유용한 머신러닝 기법입니다. 보통 아래와 같은 방식으로 작동합니다.
- 모니터링 대상 설정: 특정 성능 지표(예: val_loss, val_accuracy)를 모니터링하도록 지정합니다. train_loss보다는 보통 검증 데이터에 대한 val_loss나 val_accuracy를 사용하여 일반화 성능을 직접 평가합니다.
- 변화 허용 범위 (min_delta): 설정된 성능 지표의 개선을 감지할 때 얼마나 큰 변화가 일어나야 하는지를 정의합니다. 예를 들어 min_delta=0.01로 설정하면, 검증 손실이 0.01 이상 감소해야 개선된 것으로 간주합니다.
- 인내 횟수 (patience): 개선이 이루어지지 않는 epoch 횟수, 즉 모델 성능이 개선되지 않는 시점이 얼마나 지속될지를 지정합니다. 예를 들어 patience=10으로 설정하면, 10번의 epoch 동안 성능이 개선되지 않으면 학습을 중단합니다.
- 최적화 방향 설정 (mode): mode='min'이나 mode='max'로 지정하여 성능 지표가 감소하는 것이 좋은지(min, 예: val_loss) 증가하는 것이 좋은지(max, 예: val_accuracy) 설정합니다.
문제는 바로 `Early Stopping` 오브젝트를 전역변수로 설정했기 때문입니다...! (?) (이런 실수를...)
모델을 한 스크립트에 하나만 만드는 경우에는 전역변수로 지정해도 큰 문제는 없지만, 저의 경우 교차검증마다 모델을 학습시키다보니 발생한 문제였습니다. For문을 돌 때마다 새로운 `Early Stopping`객체를 만들어 학습시 적용했어야 했는데, 전역변수로 설정하여 `Early Stopping` 내부 상태인 `patience`나 `best_score`와 같은 값이 모델간 공유되어 버려, 다른 폴드들에서 학습시 `epoch 0`에서 종료되어 버리게 된 것입니다.
'코딩 > 이슈' 카테고리의 다른 글
[PyTorch] Softmax + CrossEntropyLoss (0) | 2024.11.06 |
---|---|
[PyTorch] MultilabelAUPRC (0) | 2024.10.30 |
[PyTorch] 모델 평가시 주의, trainloader shuffle (0) | 2024.10.25 |
[pandas] 피쳐엔지니어링 주의: 더미코딩 순서 (0) | 2024.10.23 |
[PyTorch] torchmetrics: Multiclass vs. Multilabel F1-score (1) | 2024.09.11 |