Ultralytics YOLO27: 대기자 명단에 등록하세요.
Get Started
고성능 YOLO 데이터셋 구축·학습 및 반복·레슨 8/10
강의초급

데이터셋이 준비되었는지 확인하기

8가지 통과/실패 검사로 첫 학습 실행을 결정하고, 스크립트로 검증할 수 있는 3가지를 자동화하며, 각 실패에 필요한 해결 방법을 파악합니다.

모든 프로젝트에서 팀이 학습을 시작하려는 순간이 찾아옵니다. 데이터셋이 준비되었을 때도 있지만, 분할 데이터 누수나 라벨이 부족한 클래스가 남아 GPU 시간을 일주일이나 낭비하고 신뢰할 수 없는 결과를 만들기도 합니다. 각 항목을 '예', '아니요' 또는 '문서화된 예외'로 평가하는 8가지 검사를 통해 주관적인 판단 대신 객관적으로 결정할 수 있습니다.

학습 성과

8개 항목의 준비 상태 검사로 데이터셋을 평가하고, 개수로 확인할 수 있는 세 가지 검사를 스크립트로 검증한 뒤 진행 결정 또는 우선순위가 정해진 수정 목록을 작성합니다.

속성 과정
이미 사용법을 알고 계신다면, 간단히 요약해 드리겠습니다.
  1. 8개 검사를 모두 '예', '아니요' 또는 '문서화된 예외'로 평가합니다.

  2. readiness.py을 사용해 데이터 수량, 누수, 분할별 클래스 포함 여부 및 배경 이미지 비율을 평가합니다.

  3. 하이퍼파라미터가 아니라 데이터에서 모든 '아니요' 항목을 해결합니다.

  4. 예상 영향을 문서화한 경우에만 알려진 공백을 안고 배포합니다.

실습형

8가지 검사#

#검사 항목통과 기준실패 시 돌아갈 항목
1명확한 목표목표, 작업, 클래스 및 승인 테스트가 문서화되고 합의되어 있습니다비즈니스 목표부터 시작하기
2정의된 클래스각 클래스에 정의가 있고, 해당 클래스에 포함되지 않는 유사한 대상을 명시했습니다목표 및 라벨링 가이드
3대표성 있는 이미지각 사양 시나리오가 할당량을 충족하며, 대부분 실제 운영 환경의 소스에서 가져왔습니다고품질의 대표성 있는 데이터 수집하기
4충분한 데이터 수량클래스당 이미지 ≥ 1,500개 및 인스턴스 ≥ 10,000개, 또는 문서화된 예외사양 및 수집
5일관된 라벨가이드를 작성하고 조정 작업을 완료했으며, 일치율이 ≥ 90%입니다어노테이션 모범 사례
6QC 완료감사 스크립트에 문제가 없고, 의심 사례를 검토했으며, QC 메모를 작성했습니다데이터셋 품질 관리
7정상적인 분할그룹 단위로 분할했고, 각 그룹은 하나의 분할에만 포함되며, 모든 분할에 모든 클래스가 있습니다데이터셋을 올바르게 분할하기
8배경 이미지이미지의 0–10%가 라벨이 없는 빈 프레임입니다사양 및 수집

이 체크리스트는 데이터 수집 및 어노테이션 가이드에서 하나씩 다루는 동일한 결정을 단일 진행/중단 판단으로 통합합니다.

개수로 확인할 수 있는 검사 자동화#

4, 7, 8번 검사는 산술 계산이므로 스크립트로 매번 동일하게 평가할 수 있습니다. 다음 스크립트는 이전 강의에서 group_split.py이 작성한 연습용 세트와 분할 목록을 읽습니다:

from collections import Counter
from pathlib import Path

root = Path("datasets/practice")  # images/, labels/, and the train/val/test.txt lists from group_split.py
splits = {s: [Path(p).stem for p in (root / f"{s}.txt").read_text().split()] for s in ("train", "val", "test")}

def classes(stem):
    label = root / "labels" / f"{stem}.txt"
    return [int(r.split()[0]) for r in label.read_text().splitlines() if r.strip()] if label.exists() else []

stems = [s for split in splits.values() for s in split]
instances = Counter(c for s in stems for c in classes(s))
images = Counter(c for s in stems for c in set(classes(s)))
background = sum(not classes(s) for s in stems) / len(stems)
groups = {split: {s.rsplit("_", 1)[0] for s in names} for split, names in splits.items()}
per_split = {split: {c for s in names for c in classes(s)} for split, names in splits.items()}
shared = (groups["train"] & groups["val"]) | (groups["train"] & groups["test"]) | (groups["val"] & groups["test"])
weakest = min(instances, key=lambda c: (images[c], instances[c]))

checks = {
    "4 volume": (images[weakest] >= 1500 and instances[weakest] >= 10_000,
                 f"weakest class {weakest}: {images[weakest]} images, {instances[weakest]} instances"),
    "7 no shared groups": (not shared, f"{len(shared)} groups appear in more than one split"),
    "7 every class in every split": (all(per_split[s] == set(instances) for s in splits),
                                     ", ".join(f"{s} misses {len(set(instances) - per_split[s])}" for s in splits)),
    "8 background 0-10%": (background <= 0.10, f"{background:.1%} background images"),
}
for name, (ok, detail) in checks.items():
    print(f"{'PASS' if ok else 'FAIL'}  {name:<29} {detail}")
FAIL  4 volume                      weakest class 30: 1 images, 1 instances
PASS  7 no shared groups            0 groups appear in more than one split
FAIL  7 every class in every split  train misses 5, val misses 36, test misses 41
PASS  8 background 0-10%            1.6% background images

그룹 단위 분할로 데이터 누수는 해결했지만, 연습용 세트는 준비와 거리가 멉니다. 가장 약한 클래스(30, skis)에는 라벨이 지정된 인스턴스가 하나뿐이고, val에서는 클래스의 절반을 평가할 수 없습니다. 이미지 128개로 구성된 데모 세트에서는 예상된 결과이며, 일주일 동안 학습하기 전에 이 검사를 통해 확인하려는 바로 그 결과입니다.

스크립트가 깔끔하다고 체크리스트까지 완성되는 것은 아닙니다

스크립트는 수치화할 수 있는 항목을 확인합니다. 점검 항목 1, 2, 3, 5, 6에는 사람이 필요합니다. 합의된 목표, 문서화된 정의, 사양 커버리지, 측정된 일치도 점수, QC 메모가 이에 해당합니다. 각 항목에 대한 근거를 한 줄씩 적어 수동으로 점수를 매기세요.

결정하기: 학습, 공백을 안고 배포 또는 수정#

검사에 실패하면 데이터를 수정하는 대신 다른 방법을 시도하고 싶은 경우가 많습니다:

유혹적인 지름길효과가 없는 이유
"더 큰 모델을 사용해 보세요."더 큰 모델도 라벨 노이즈를 똑같이 충실하게 학습합니다.
"학습률을 조정해 보세요."어떤 옵티마이저 설정도 누락된 클래스나 시나리오를 추가해 주지 않습니다.
"에포크를 더 늘려 학습하세요."데이터가 제한된 상태에서 에포크를 늘리면 더 빨리 과적합됩니다.
"증강을 더 추가하세요."증강은 데이터에 없던 시나리오를 만들어낼 수 없습니다.

거의 준비가 된 세 가지 패턴#

패턴실패한 검사상태해결 방법
다양성 없는 데이터 수량3이미지 5,000개, 카메라 한 대, 예외 상황 없음학습 전에 더 많은 카메라, 장소 및 시간대에서 데이터를 수집합니다
일관성 없는 다양성5어노테이터마다 박스 범위와 가림 정도를 다르게 판단합니다가이드를 완성하고 조정 작업을 진행한 뒤 영향을 받은 샘플의 라벨을 다시 지정합니다
감지하기 어려운 데이터 누수7비디오 프레임을 이미지별로 무작위 분할클립, 카메라 또는 날짜별로 다시 분할합니다. 검증 mAP가 낮아질 것으로 예상해야 합니다. 그 하락이 현실을 반영하기 때문입니다.

알려진 결함을 안고 배포합니다#

모든 검사 항목이 통과하기 전에 범위를 좁힌 첫 번째 모델을 만드는 것이 적절한 경우가 많습니다. 파일럿, 프로토타입 또는 일부 카메라를 대상으로 한 v1이 여기에 해당합니다. 모델을 프로덕션에 배포하면 어두운 곳에서 데이터셋을 다듬는 것보다 실제 문제를 더 빠르게 파악할 수 있습니다. 결함을 안고 배포할 때는 다음 세 가지를 기록합니다:

  • 실패한 검사 항목.
  • 예상되는 영향. 예: "야간 데이터가 없어 어두워진 후 재현율이 낮아질 것으로 예상됩니다".
  • v1을 실행하는 동안 결함을 해결할 데이터 수집 계획.
영향이 명시되지 않은 예외는 점검을 건너뛴 것과 같습니다

"수량: 예외"라고 적으면 다음 담당자는 아무것도 알 수 없습니다. "수량: pallet, 인스턴스 700개. 혼잡한 구역에서 팔레트 재현율이 낮아질 것으로 예상되며, 6월까지 2,000개를 추가 라벨링할 예정"이라고 적으면 관리 가능한 위험이 됩니다. 모든 예외에는 승인 테스트에 예상되는 영향을 명시해야 합니다.

재학습 전에 매번 다시 실행합니다#

시간에 따른 모델 품질: 새로 라벨링된 데이터가 들어오는 동안 품질이 유지되다가 예상된 저하 시점 이후 하락하면서 지금 재학습할지 기다릴지 판단해야 하는 상황

v1에 사용할 준비가 된 데이터셋이 자동으로 v3에도 준비된 것은 아닙니다. 새 클래스, 새 데이터 소스, 새 어노테이터는 각각 이전에 통과했던 검사를 실패하게 만들 수 있으며, 새 라벨이 쌓이는 동안 프로덕션 데이터는 드리프트합니다. 재학습 전에 매번 readiness.py을 다시 실행하고 수동 검사를 재평가합니다. 몇 분이면 충분하며, 이를 건너뛰면 결함이 있는 데이터셋으로 일주일 동안 학습하는 대가를 치를 수 있습니다.

사용해 보기

분할된 데이터셋(또는 연습용 데이터셋)에 readiness.py을 실행한 다음, 각 항목에 대한 근거를 한 줄씩 적어 다섯 가지 수동 검사를 직접 평가합니다. 실패한 각 검사가 승인 테스트를 얼마나 위험에 빠뜨리는지 기준으로 우선순위를 정합니다. 산출물: 8개 행으로 구성된 점수화 체크리스트와 진행 여부 결정 또는 우선순위가 지정된 수정 목록을 QC 메모와 함께 저장합니다.

완료 조건
다음 조건을 모두 충족하면 레슨을 완료한 것입니다.
  • 8개 검사 항목 모두 점수와 근거 한 줄이 있으며, 수치화 가능한 세 항목은 스크립트에서 가져옵니다.

  • 모든 예외에는 승인 테스트에 미칠 예상 영향과 이를 해결할 계획이 명시되어 있습니다.

  • 결정(학습, 결함을 문서화한 후 배포, 또는 먼저 수정)이 체크리스트에 기록되어 있습니다.

정답 보기

연습용 데이터셋의 점수화 체크리스트:

#검사 항목점수근거
1명확한 목표예1과의 실습에서 사용한 objective.md 및 acceptance_test.py
2정의된 클래스아니요COCO의 80개 클래스 이름에는 문서화된 정의나 제외해야 할 유사 클래스가 없습니다.
3대표 이미지아니요coverage.py: cam2–cam4가 할당량 미달입니다.
4충분한 데이터 규모아니요readiness.py: 데이터가 가장 적은 클래스에 이미지가 1개 있습니다.
5일관된 라벨아니요보정 단계의 일치율은 47%입니다.
6QC 완료부분 완료감사를 실행했으며 000000000438.jpg의 의심 항목은 아직 미해결 상태입니다.
7누수 없는 분할아니요공유 그룹은 없지만 검증 데이터에 71개 클래스 중 36개가 누락되었습니다.
8배경 이미지예1.6%

결정: 먼저 수정합니다. 승인 테스트에 대한 위험도 순위: (1) 목표에 필요한 클래스만 남기도록 클래스 목록을 줄여 검사 2, 4, 7을 한 번에 축소합니다. (2) 해당 클래스의 그룹을 더 수집합니다. (3) 멀리 있는 사람에 대한 가이드 규칙을 완성하고 다시 라벨링합니다. 데모 데이터셋은 이 검사를 통과하지 못하며, 그래야 합니다.

다음 단계

체크리스트를 통과하면 다음 강의에서 기준선 미세 조정을 실행하고 결과를 다음 데이터셋 수정 작업으로 연결합니다.