안녕하세요!
딥러닝 모델을 학습시키다 보면 항상 마주치는 벽이 있습니다. 바로 데이터 불균형(Class Imbalance)입니다. 이번 포스팅에서는 96%의 높은 정확도 뒤에 숨은 취약점을 발견하고, 이를 해결하기 위해 데이터셋을 재구축하며 파인튜닝하는 과정을 기록합니다.
1. 초기 모델 진단
첫 번째 학습 결과, Test Accuracy는 96.56%로 매우 훌륭했습니다. 하지만 세부 지표(Confusion Matrix)를 보니 약점이 보였습니다.
- 문제점: 특정 부위(Beef_BottomRound, Beef_Shoulder)의 정밀도(Precision)와 재현율(Recall)이 다른 클래스에 비해 낮음.
- 원인: 데이터 양의 차이. 데이터가 많은 Sirloin(496장)은 잘 맞추지만, 상대적으로 적은 부위에서 오답률이 높음.
2. 해결 전략: 데이터 밸런싱 (Dataset Balancing)
단순히 양만 늘리는 것이 아니라, 모델이 모든 부위를 '공평하게' 학습할 수 있도록 데이터셋을 재설계했습니다.
| 클래스명 | 기존 데이터 (Total) | 균형 데이터 (100장 선별) |
| Beef_BottomRound | 282 | 100 |
| Beef_Sirloin (최다) | 496 | 100 |
| Beef_Ribeye (최소) | 226 | 100 |
| 합계 | 3,548장 | 1,000장 |
💡 Insight: 전체 데이터 수는 줄어들더라도(3,548 → 1,000), 클래스별 비율을 1:1로 맞추면 모델이 특정 클래스에 편향(Bias)되는 것을 막을 수 있습니다.
3. 핵심 테크닉: Focal Loss & Weighted Sampling
데이터셋 조정 외에도 학습 알고리즘 측면에서 두 가지 무기를 준비했습니다.
Focal Loss (포컬 로스)
맞추기 쉬운 샘플의 가중치는 낮추고, 어려운 샘플(Hard Negative)에 집중하게 만드는 손실 함수입니다.
$$FL(p_t) = -(1 - p_t)^\gamma \log(p_t)$$
(여기서 $\gamma$는 어려운 문제에 얼마나 더 집중할지 결정하는 파라미터입니다.)
WeightedRandomSampler
배치(Batch)를 구성할 때 데이터가 적은 클래스를 더 자주 뽑도록 확률을 조정하여 학습 효율을 극대화합니다.
4. 2차 학습 모니터링 (진행 중)
현재 balanced_100 데이터셋으로 재학습을 진행 중입니다.
- Epoch 15/30 기준: Val Acc 0.7533
- 관전 포인트:
- 초반 정확도는 기존보다 낮게 시작함 (데이터 절대량이 줄었기 때문).
- 남겨둔 2,500장의 이미지는 이후 2차, 3차 '교체 학습' 데이터로 활용 예정.
- 하지만 학습이 진행될수록 BottomRound 같은 취약 부위의 Precision이 올라가는지 확인 필요.
Epoch [ 17/30] Train Loss: 1.0991 Train Acc: 0.7863 | Val Loss: 1.0636 Val Acc: 0.7533 | LR: 4.71e-05/4.71e-04 | 71.3s
Epoch [ 18/30] Train Loss: 1.0883 Train Acc: 0.8031 | Val Loss: 1.0692 Val Acc: 0.7667 | LR: 4.13e-05/4.13e-04 | 71.8s
💾 모델 저장: b2_imagenet_beef_100-v1.pth | 메타: b2_imagenet_beef_100-v1.json
⭐ Best Model Updated! (Val Acc: 0.7667, Val Loss: 1.0692)
Epoch [ 19/30] Train Loss: 1.0536 Train Acc: 0.8193 | Val Loss: 1.0687 Val Acc: 0.7733 | LR: 3.57e-05/3.57e-04 | 73.7s
💾 모델 저장: b2_imagenet_beef_100-v1.pth | 메타: b2_imagenet_beef_100-v1.json
⭐ Best Model Updated! (Val Acc: 0.7733, Val Loss: 1.0687)
Epoch [ 20/30] Train Loss: 1.0742 Train Acc: 0.8077 | Val Loss: 1.0658 Val Acc: 0.7800 | LR: 3.02e-05/3.02e-04 | 71.5s
💾 모델 저장: b2_imagenet_beef_100-v1.pth | 메타: b2_imagenet_beef_100-v1.json
⭐ Best Model Updated! (Val Acc: 0.7800, Val Loss: 1.0658)
💾 모델 저장: epoch_020.pth | 메타: epoch_020.json
5. 결론 및 향후 계획
무조건 데이터가 많다고 좋은 것이 아니라, 균형 잡힌 데이터가 모델의 강건함(Robustness)을 결정한다는 것을 배웠습니다.
- Next Step: 현재 학습된 모델의 Confusion Matrix를 다시 그려서 클래스별 편차가 줄어들었는지 확인하기.
- Tip: 정확도가 정체되면 남겨둔 데이터((남는이미지)train_dataset_1)에서 새로운 샘플을 추출해 데이터셋을 교체(Resplit)하며 학습을 이어갈 예정.
'4. [팀] 프로젝트 및 공모전 > 4-2 Meat-A-Eye' 카테고리의 다른 글
| [프로젝트 회고] Meat-A-Eye: AI 기반 축산물 부위 인식 및 관리 플랫폼 개발기 (0) | 2026.02.24 |
|---|---|
| [Meat-A-Eye] 성능 개선 프로세스 상세 메모 블로그 (0) | 2026.02.06 |
| [개발 기록] 대시보드 가격 API 응답 시간 줄이기 - 병렬 호출과 캐시 사용 (0) | 2026.02.02 |
| [개발 기록] KAMIS API 연동 개선 및 대시보드 필터링 로직 최적화 (0) | 2026.02.01 |
| [Meat-A-Eye] 데이터 수집 과정 정리 (0) | 2026.01.24 |
