Validation Data
검증 데이터는 개발 중에 평가하는 별도 데이터 분할로, 하이퍼파라미터 튜닝, 체크포인트 선택, 최종 테스트 전 과적합 감지에 사용됩니다.
검증 데이터는 학습에서 제외하고 개발 중 반복적으로 점수를 측정하는 라벨링 데이터의 일부입니다. 이를 사용해 모델을 비교하고 하이퍼파라미터를 조정하며, 체크포인트를 선택하고 과적합을 감지합니다. 모델은 검증 데이터로 가중치를 업데이트하지 않으므로, 검증 점수를 통해 학습 데이터에서 학습한 내용이 보지 못한 이미지에 얼마나 잘 적용되는지 확인할 수 있습니다. 검증 세트와 개발(dev) 세트는 동의어입니다. 검증 점수를 바탕으로 내리는 모든 결정은 모델을 해당 분할에 조금 더 맞추므로, 최종적으로 편향되지 않은 추정치를 얻기 위해 별도의 테스트 세트를 남겨 둡니다.
학습, 검증, 테스트 분할#
라벨링된 데이터셋은 보통 세 부분으로 나뉩니다:
- 학습 세트: 옵티마이저가 가중치를 맞추는 데 사용하는 예제로, 일반적으로 데이터의 70~80%입니다.
- 검증 세트: 학습 실행이 끝난 후 또는 에포크마다 점수를 측정해 학습률, 모델 크기, 증강 강도, 학습 중단 시점 등의 선택을 안내합니다.
- 테스트 세트: 모든 선택을 확정한 후 한 번 점수를 측정해 예상되는 실제 성능을 보고합니다.
이미지가 수천 개 규모인 데이터셋에서는 70/15/15 또는 80/10/10 분할이 일반적입니다. 매우 큰 데이터셋은 신뢰할 수 있는 추정치를 얻기 위해 더 작은 비율만 검증에 사용합니다. ImageNet-1k는 학습 이미지 1,281,167개에 대해 검증 이미지 50,000개를 보류합니다. 테스트 라벨이 공개되지 않으므로 ImageNet 정확도는 관례적으로 해당 검증 세트에서 보고하며, 이 경우 검증 세트가 테스트 세트 역할도 합니다.
유용한 검증 세트는 모델이 배포에서 마주할 데이터와 일치해야 하며 학습 세트와 겹치지 않아야 합니다. 여러 이미지가 같은 동영상, 환자 또는 위치에서 나온 경우 무작위 이미지 수준 분할은 정보를 누출합니다. 모델이 객체 대신 장면을 인식할 수 있기 때문입니다. 환자나 녹화 세션별로 그룹을 기준으로 분할하면 이러한 데이터 유출을 방지할 수 있습니다.
하이퍼파라미터 튜닝 및 모델 선택#
경사 하강법으로 가중치를 학습하는 반면, 하이퍼파라미터는 여러 후보를 학습한 다음 검증 점수가 가장 높은 후보를 선택해 정합니다. 학습 점수로는 이러한 선택을 할 수 없습니다. 모델이 더 크고 더 오래 학습될수록 학습 데이터에 더 잘 맞는 경우가 거의 항상 있기 때문입니다. 아래의 scikit-learn 스크립트는 번들된 숫자 데이터셋에서 결정 트리의 깊이를 튜닝합니다:
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# Split 1,797 digit images 60/20/20 into training, validation, and test sets
X, y = load_digits(return_X_y=True)
X_train, X_rest, y_train, y_rest = train_test_split(X, y, test_size=0.4, random_state=0, stratify=y)
X_val, X_test, y_val, y_test = train_test_split(X_rest, y_rest, test_size=0.5, random_state=0, stratify=y_rest)
# Fit one model per candidate tree depth and score each on the validation set
val_scores = {}
for depth in (2, 4, 8, 16):
model = DecisionTreeClassifier(max_depth=depth, random_state=0).fit(X_train, y_train)
val_scores[depth] = model.score(X_val, y_val)
print(f"depth {depth}: train {model.score(X_train, y_train):.3f}, validation {val_scores[depth]:.3f}")
# Refit the winner and score the test set exactly once
best = max(val_scores, key=val_scores.get)
final = DecisionTreeClassifier(max_depth=best, random_state=0).fit(X_train, y_train)
print(f"Chosen depth {best}: test accuracy {final.score(X_test, y_test):.3f}")깊이가 커질수록 학습 정확도는 계속 상승해 깊이 16에서 1.000에 도달하지만, 검증 정확도는 깊이 8에서 0.836으로 최고점을 찍은 뒤 트리가 데이터를 암기하기 시작하면서 깊이 16에서는 0.825로 떨어집니다. 검증 결과를 기준으로 깊이 8을 선택하면, 손대지 않은 테스트 세트에서 0.853의 점수를 얻습니다.
조기 종료 및 체크포인트 선택#
딥러닝 학습 루프는 일반적으로 매 에포크마다 검증 세트의 점수를 계산합니다. 네트워크가 학습 데이터에 점점 더 잘 맞춰지면서 학습 손실은 계속 감소하지만, 검증 손실이나 정확도는 결국 정체된 후 악화됩니다. 조기 종료는 정해진 에포크 수(인내 횟수) 동안 검증 점수가 개선되지 않으면 학습을 끝내고, 가장 점수가 좋았던 에포크의 가중치를 유지합니다.
Ultralytics의 YOLO26 학습은 기본적으로 이 루프를 실행합니다. 매 에포크마다 데이터셋 YAML의 val 분할에서 점수를 계산하고, 가장 높은 검증 적합도(탐지의 경우 mAP50-95를 기준으로 함)를 기록한 에포크를 best.pt로 저장하며, 개선 없이 patience 에포크가 지나면 학습을 중단합니다. 기본값은 100입니다.
from ultralytics import YOLO
# 사전 학습된 YOLO26 nano 탐지기 로드
model = YOLO("yolo26n.pt")
# 매 에포크 후 val 분할에서 검증하고, 개선 없이 10 에포크가 지나면 중단합니다
results = model.train(data="coco8.yaml", epochs=50, patience=10)소규모 데이터셋을 위한 교차 검증#
데이터가 부족하면 하나의 보류 분할만 사용하는 것은 예제를 낭비하고 점수의 변동성을 높입니다. K-겹 교차 검증은 데이터를 K개 폴드로 나누고, 각기 다른 폴드를 검증용으로 보류하는 K개의 모델을 학습한 뒤 K개 점수의 평균을 계산합니다. 따라서 모든 예제를 학습과 검증에 모두 사용합니다. 5겹과 10겹이 일반적이며, 계층화 및 그룹화 방식은 각 폴드에서 클래스 비율을 균형 있게 유지하거나 관련 이미지를 같은 폴드에 배치합니다. 테스트 세트는 모든 폴드 바깥에 별도로 유지합니다.
검증 데이터와 관련 용어#
- 테스트 데이터: 마지막에 한 번 점수를 측정합니다. 선택을 내리는 데 다시 사용하면 두 번째 검증 세트가 되어 점수가 더는 편향되지 않은 추정치가 아닙니다.
- 학습 데이터: 옵티마이저가 가중치를 학습하는 데 사용하는 유일한 분할입니다.
- 교차 검증: 어떤 예제가 검증 데이터 역할을 할지 순환하는 절차로, 하나의 데이터셋에서 K개의 검증 점수를 산출합니다.
- 임상 및 규제 문서에서의 검증: 의료 및 규제 산업에서 모델 검증은 완성된 모델을 독립적인 외부 데이터로 평가한다는 의미인 경우가 많으며, 이는 머신러닝 용어로 테스트 세트에 해당합니다.










