Ultralytics YOLO27: 대기자 명단에 등록하세요.
Get Started
강의초급

데이터셋 사양 정의하기

수집 전에 시나리오, 할당량, 변동 요인, 엣지 케이스, 배경 이미지를 계획하고 Ultralytics의 목표 규모에 맞춰 계획을 수립하세요.

사양 없이 진행하는 팀은 조명이 밝은 낮에 한 대의 카메라로 찍은 사진 5,000장만 확보한 뒤, 첫 운영일 해 질 무렵에 실패하는 모델을 만들게 됩니다. 데이터셋 사양은 이미지 쇼핑 목록입니다. 모델이 처리해야 할 모든 시나리오와 각 시나리오에 필요한 이미지 수, 과대표집할 희귀 사례를 정합니다. 작성에는 한 시간이 걸리지만, 수집 작업을 어디에 집중할지 결정합니다.

학습 성과

변동 요인과 엣지 케이스를 다루는 할당량이 포함된 시나리오 표를 작성하고, 라벨이 지정된 데이터셋이 운영 목표 규모에 얼마나 못 미치는지 측정하세요.

속성 과정
이미 사용법을 알고 계신다면, 간단히 요약해 드리겠습니다.
  1. 카메라, 위치, 시간, 조건을 각각 할당량과 함께 행별 시나리오로 작성하세요.

  2. 운영 환경 기준으로 클래스당 이미지 ≥1,500장 및 라벨링된 인스턴스 ≥10,000개를 목표로 할당량을 설정하세요.

  3. 알려진 엣지 케이스마다 별도의 행을 만들고 과대표집하세요.

  4. 이미지의 0~10%를 객체가 없는 배경 이미지로 확보하세요.

실습형

사양의 역할#

사양은 목표와 카메라를 연결하는 다리입니다. 데이터 수집을 이끌며, 첫 모델이 목표를 달성하지 못했을 때 다시 확인할 문서입니다.

학습 설정이 아니라 사양으로 돌아가는 순환 구조입니다. 목표를 달성하지 못하는 이유는 대개 사양에 포함되지 않은 시나리오 때문입니다. CV 프로젝트 단계 가이드에서도 동일한 라이프사이클을 설명합니다.

시나리오를 행으로 작성하세요#

시나리오는 모델이 처리해야 하는 캡처 조건의 조합 하나를 뜻합니다. 할당량이 포함된 행을 사용하면 누군가 카메라를 들기 전에 데이터 공백을 파악할 수 있습니다.

시나리오카메라위치시간대조건할당량참고 사항
주간 도크cam-1~cam-4A~C 구역08:00–17:00상관없음1,200가장 혼잡한 시간대
야간 도크cam-1~cam-4A~C 구역22:00–04:00상관없음400나트륨등 조명, 적은 인원
비 오는 날 하역cam-2, cam-3B 구역상관없음비가 오는 경우에만200드물지만 중요함
적재된상관없음상관없음상관없음팔레트 높이 2개 초과150뒤에 있는 사람을 가림
배경상관없음상관없음상관없음빈 도크150객체 없음, 라벨 없음

문서로 작성할 수 없는 시나리오는 모델이 학습 중에 보지 못하며, 운영 환경에서 실패하는 원인이 됩니다.

목표 규모에 맞춰 사양을 설정하세요#

Ultralytics의 최고의 학습 결과를 위한 팁에서 운영 환경에 적용할 수 있는 일반적인 기준을 제시합니다.

목표권장 사항
클래스당 이미지 수≥ 1,500
클래스당 라벨링된 인스턴스 수≥ 10,000
배경 이미지(라벨 없음)데이터셋의 0~10%; COCO는 약 1%입니다
다양성다양한 시간대, 계절, 날씨, 조명, 각도, 소스 및 카메라

이는 운영 모델을 위한 기준입니다. 클래스당 라벨이 지정된 객체 수백 개면 실험을 시작하기에 충분하며, 첫 모델을 통해 데이터가 더 필요한 시나리오를 가장 빠르게 파악할 수 있습니다. 데이터셋이 기준에 얼마나 못 미치는지 확인하려면 수량을 세어 보세요. 이 스크립트는 자동으로 다운로드되는 COCO의 128개 이미지 하위 집합인 COCO128에서 실행됩니다.

from collections import Counter
from pathlib import Path

from ultralytics.data.utils import IMG_FORMATS, check_det_dataset, img2label_paths

IMAGES_PER_CLASS, INSTANCES_PER_CLASS = 1500, 10_000  # Ultralytics production targets

data = check_det_dataset("coco128.yaml")  # downloads COCO128 (~7 MB) on first run; swap in your data YAML
images = [p for p in Path(data["train"]).rglob("*.*") if p.suffix[1:].lower() in IMG_FORMATS]
image_count, instance_count, background = Counter(), Counter(), 0
for label in map(Path, img2label_paths([str(p) for p in images])):
    classes = [int(r.split()[0]) for r in label.read_text().splitlines() if r.strip()] if label.exists() else []
    instance_count.update(classes)
    image_count.update(set(classes))
    background += not classes

print(f"{len(images)} images, {background} background ({background / len(images):.0%}, target 0-10%)")
print(f"{'class':>12} {'images':>7} {'instances':>10} {'of target':>10}")
ranked = instance_count.most_common()
for cls, n in ranked[:3] + ranked[-3:]:  # best and worst covered classes
    coverage = min(image_count[cls] / IMAGES_PER_CLASS, n / INSTANCES_PER_CLASS)
    print(f"{data['names'][cls]:>12} {image_count[cls]:>7} {n:>10} {coverage:>10.1%}")

never_labeled = [name for i, name in data["names"].items() if i not in instance_count]
print(f"{len(never_labeled)} classes in names with zero labels: {never_labeled[:4]} ...")
128 images, 2 background (2%, target 0-10%)
       class  images  instances  of target
      person      61        254       2.5%
         car      12         46       0.5%
         cup      10         36       0.4%
        bear       1          1       0.0%
      banana       1          1       0.0%
        skis       1          1       0.0%
9 classes in names with zero labels: ['fire hydrant', 'parking meter', 'sheep', 'cow'] ...

결과 읽는 방법:

  • 커버리지는 이미지 비율과 인스턴스 비율 중 더 낮은 값입니다. 클래스에는 두 가지가 모두 필요하기 때문입니다. 커버리지가 가장 높은 클래스인 person조차 운영 기준의 2.5%에 불과합니다.
  • 인스턴스가 하나뿐인 클래스(bear, banana, skis)는 학습하거나 측정할 수 없습니다. 자체 데이터셋에서는 해당 클래스를 수집하거나 v1에서 제외하세요.
  • 라벨이 하나도 없는 클래스는 YAML에 나열되어 있지만 실제로 그려진 적은 없습니다. 그래도 모델은 해당 클래스를 예측하는 데 용량을 할당합니다. names에서 해당 클래스를 제거하거나 학습 전에 데이터를 수집하세요.

변동 요인을 다루세요#

해안 산책로에서 수행한 Ultralytics YOLO 탐지: 카메라 가까이 있는 사람과 자전거 이용자, 개 한 마리, 서로 다른 거리에 있는 차량에 라벨이 지정된 박스와 신뢰도 점수가 표시되어 있습니다

한 프레임에도 가까이 있거나 멀리 있는 사람, 자전거, 개, 자동차가 함께 나타납니다. 실제 사양은 이러한 범위를 의도적으로 계획해야 합니다. 각 변동 요인에 대해 사양이 이를 다루는지, 아니면 적용되지 않는 이유가 무엇인지 기록하세요. 비어 있는 행은 운영 환경에서 발견하게 될 시나리오입니다.

차원예시
시간낮, 밤, 새벽, 해 질 녘
날씨맑음, 흐림, 비, 안개, 눈
조명밝음, 어두움, 눈부심, 짙은 그림자, 여러 광원 혼합
카메라모델, 렌즈, 설치 높이, 시야각
지리현장, 도시, 국가
사람 및 작업자교대조, 팀, 유니폼, 보호 장비
제품 변형SKU, 패키징 개정판, 색상
객체 크기가깝고 큰 객체, 중거리 객체, 멀고 작은 객체
가림가림 없음, 부분 가림, 심한 가림, 유리 뒤
장비 상태더럽거나 김 서린 렌즈, 손상된 팔레트, 마모된 바닥 표시

수량보다 변동성이 중요합니다. 이 행들에 걸쳐 분산된 이미지 1,500장이 정오에 한 대의 카메라로 촬영한 이미지 5,000장보다 가치가 높습니다.

배경 이미지와 엣지 케이스 계획하기#

배경 이미지는 빈 하역장처럼 라벨링된 객체가 없는 프레임입니다. 이러한 이미지는 모델이 아무것도 없는 상황을 학습하도록 하여 오탐을 줄입니다.

배경 이미지가 저장되는 방식

Ultralytics YOLO 형식에서 배경 이미지는 라벨 파일이 비어 있거나 라벨 파일이 없는 이미지입니다. 학습 과정에서 스캔 로그(… 1200 images, 90 backgrounds, 0 corrupt)에 두 유형 모두 집계됩니다. 첫 에포크를 시작하기 전에 이 수치를 목표인 0~10%와 비교하세요.

엣지 케이스에는 심한 가림, 프레임 가장자리에서 잘린 객체, 특이한 방향, 쌓인 객체, 지게차 마스트 옆의 철제 기둥처럼 비슷하게 보이는 객체가 포함됩니다. 각 엣지 케이스에 별도의 할당량 행을 지정하세요.

자연 발생 빈도만 따르면 엣지 케이스가 부족해집니다

팔레트 더미 뒤에 사람이 나타나는 프레임이 200개 중 1개라면, 자연 발생 빈도로 수집한 데이터셋 1,500개에는 그런 프레임이 약 7개뿐이며, 학습하기에는 턱없이 부족합니다. 엣지 케이스를 의도적으로 오버샘플링하세요. 해당 케이스의 할당량은 실제 영상에서 차지하는 비중보다 훨씬 커야 합니다.

사양을 완벽하게 작성할 필요는 없습니다

문서만으로 모든 시나리오를 떠올릴 수는 없습니다. 사양을 대체로 올바르게 작성하고, 첫 모델을 빠르게 학습한 다음 모델의 실수로 놓친 시나리오를 찾아내세요.

사용해 보기

프로젝트에 맞는 시나리오 표 초안을 작성하세요. 표에는 수치로 된 할당량이 있는 행 5~10개와 배경 행, 알려진 엣지 케이스별 행 하나씩을 포함합니다. 배포 현장에서 근무하는 사람과 함께 검토하고, 그 사람이 언급하는 모든 시나리오를 추가하세요. 그런 다음 이미 라벨링된 데이터나 COCO128에 volume_gap.py을 실행하고, 가장 많이 포함된 클래스와 가장 적게 포함된 클래스를 기록하세요. 결과물: 표와 커버리지 수치가 포함된 spec.md.

완료 조건
다음 조건을 모두 충족하면 레슨을 완료한 것입니다.
  • 시나리오 표에는 수치로 된 할당량이 있는 행이 5개 이상 있으며, 배경 및 엣지 케이스 행도 포함되어 있습니다.

  • 변동성 차원 10개 중 최소 5개가 포함되어 있거나 명시적으로 제외되어 있습니다.

  • 할당량의 합계는 클래스별 이미지 및 인스턴스 목표치 이상이어야 합니다. 그렇지 않다면 그 차이를 v1 예외로 문서화해야 합니다.

정답 보기

할당량은 이미지 목표치뿐 아니라 인스턴스 목표치에서도 산출해야 합니다. 주차장 차량 계수기에서 두 개의 클래스를 사용하고, 파일럿 영상에서 이미지당 자동차는 평균 3대, 트럭은 0.5대라고 가정해 보겠습니다.

클래스이미지당 인스턴스 수인스턴스 10,000개에 필요한 이미지 수최소 이미지 수 1,500장을 충족하는 데 필요한 이미지 수계획
car3.0≈ 3,3001,500이미지 3,300장
truck0.5≈ 20,0001,500트럭이 10배 더 자주 나타나는 하역장 입구에서 집중 촬영

일반 영상으로 자동차는 충분히 확보됩니다. 트럭은 무작위로 이미지 20,000장을 촬영해야 하므로, 모든 이미지 수집량을 6배로 늘리는 대신 명세에 전용 시나리오 행(평일 06:00~10:00 하역장 입구)을 추가합니다. 배경 행은 약 5%(밤의 빈 주차장)로 설정하고, 눈에 덮인 장면과 프레임 밖으로 일부 잘린 트럭을 엣지 케이스 행으로 추가하세요.

다음 단계

명세를 작성했으니 다음 강의에서는 명세를 실제로 충족하는 이미지를 수집합니다.