Recopila datos representativos de alta calidad
Obtén imágenes de condiciones reales de despliegue, incluye los metadatos de captura en cada nombre de archivo, controla la cobertura con respecto a la especificación y muestrea los vídeos sin saturar el conjunto de datos.
La mayoría de los fallos de los conjuntos de datos se deben a la recopilación. Un equipo captura ejemplos nítidos con una cámara durante una semana, la validación parece excelente y el modelo se viene abajo en la segunda ubicación. La recopilación marca el techo: ni la calidad de las etiquetas, ni el aumento de datos ni los hiperparámetros pueden enseñar al modelo una escena que nunca aparece en el conjunto de datos.
Práctico
La variabilidad supera al volumen#
Compara dos conjuntos de datos destinados al mismo despliegue:
| Conjunto de datos | Resultado de validación | En producción |
|---|---|---|
| 10.000 fotogramas casi idénticos, una cámara, solo al mediodía | Alto: los fotogramas de validación se parecen a los de entrenamiento | El rendimiento cae con otra cámara y al anochecer |
| 1.500 fotogramas distribuidos entre 12 escenarios de la especificación | Más moderado | Resiste bien, porque la producción se parece a los datos |
La puntuación de validación del primer conjunto de datos es alta solo porque la validación mide la única condición que cubre. En producción, un modelo solo rinde tan bien como el escenario peor cubierto al que se enfrenta. Prioriza la cobertura de la especificación al recopilar datos y deja el volumen en segundo lugar.
Elige las fuentes en el orden adecuado#
La mayor parte del conjunto de datos debe proceder de la configuración real de producción. La guía de recopilación y anotación de datos explica cada fuente con más detalle:
| Fuente | Cuándo resulta útil | Cuándo perjudica |
|---|---|---|
| Cámaras de producción en directo | Lo más parecido al despliegue | Lento; puede requerir acuerdos de datos |
| Grabaciones archivadas de cámaras de producción | Mucha variabilidad en poco tiempo | Las grabaciones antiguas pueden no coincidir con la configuración actual |
| Conjuntos de datos públicos (COCO, Open Images, VOC) | Arranque con clases comunes | Desfase de dominio con respecto a tus escenas |
| Capturas escenificadas | Casos extremos concretos a demanda | Demasiado limpias; es fácil depender demasiado de ellas |
| Imágenes sintéticas o generadas | Riesgos y fallos poco frecuentes que no puedes esperar a que ocurran | El modelo puede aprender el estilo del generador |
| Recopilación de imágenes web | Variedad económica | Calidad irregular y riesgo relacionado con las licencias |
Usa imágenes escenificadas, públicas y sintéticas para cubrir carencias concretas y documentadas en la especificación, y controla su proporción en el conjunto de datos para medir si ayudan. En Ultralytics Platform, Generar imágenes similares añade variaciones generadas a partir de una imagen existente a un conjunto de datos, sin etiquetar y listas para anotar.
Incluye los metadatos en el nombre del archivo#
Cada imagen necesita al menos un ID de cámara, el día de captura y un número de fotograma o clip. Sin ellos, no podrás separar los datos por grupos más adelante, rastrear una regresión hasta su origen ni recopilar más datos de un escenario poco representado. El soporte más duradero es el nombre del archivo: cam2_2026-05-01_000124.jpg sobrevive a todas las herramientas, exportaciones y cargas. La búsqueda de conjuntos de datos de Ultralytics Platform encuentra nombres de archivo y metadatos personalizados, así que estas claves se podrán seguir buscando tras la carga.
Este script crea el conjunto de datos de prácticas que se utiliza en el resto del curso. Copia las imágenes etiquetadas de COCO128 y les cambia el nombre como si cuatro cámaras las hubieran capturado durante cuatro días, con cam1 sobrerrepresentada, como suele ocurrir con una cámara cómoda de usar:
import shutil
from pathlib import Path
from ultralytics.data.utils import check_det_dataset, img2label_paths
data = check_det_dataset("coco128.yaml") # 128 COCO images stand in for your camera captures
out = Path("datasets/practice")
(out / "images").mkdir(parents=True, exist_ok=True)
(out / "labels").mkdir(parents=True, exist_ok=True)
for i, image in enumerate(sorted(Path(data["train"]).glob("*.jpg"))):
camera = ("cam1", "cam1", "cam2", "cam3", "cam4")[i % 5] # cam1 over-collected, like a real site
name = f"{camera}_2026-05-0{i // 32 + 1}_{i:06d}" # camera, capture day, frame number
shutil.copy(image, out / "images" / f"{name}.jpg")
label = Path(img2label_paths([str(image)])[0])
if label.exists():
shutil.copy(label, out / "labels" / f"{name}.txt")
print(len(list((out / "images").glob("*.jpg"))), "images written to", out)128 images written to datasets/practice
Al cargar los datos en Ultralytics Platform, se conservan esos nombres de archivo. El cuadro de diálogo de carga también admite vídeos y conjuntos de datos completos, y sus opciones incluyen el desenfoque de rostros para proteger la privacidad.
Controla la cobertura con respecto a la especificación#
Con los metadatos en los nombres de archivo, basta con contar para calcular la cobertura. Establece las cuotas a partir de tu especificación y deja que el script indique qué recopilar a continuación:
from collections import Counter
from pathlib import Path
QUOTA = {"cam1": 30, "cam2": 30, "cam3": 30, "cam4": 30} # images per camera, from your spec
images = sorted(Path("datasets/practice/images").glob("*.jpg"))
cameras = Counter(p.stem.split("_")[0] for p in images)
days = Counter(p.stem.split("_")[1] for p in images)
for camera, quota in QUOTA.items():
gap = quota - cameras[camera]
print(f"{camera}: {cameras[camera]:3d} / {quota} {'ok' if gap <= 0 else f'collect {gap} more'}")
print("days:", dict(sorted(days.items())))cam1: 52 / 30 ok
cam2: 26 / 30 collect 4 more
cam3: 25 / 30 collect 5 more
cam4: 25 / 30 collect 5 more
days: {'2026-05-01': 32, '2026-05-02': 32, '2026-05-03': 32, '2026-05-04': 32}La regla de decisión: deja de recopilar datos de cualquier fuente que supere su cuota y dedica el esfuerzo a cubrir las carencias. Aquí, cam1 ya representa el 40 % de las imágenes. Otra semana de grabaciones de esa cámara añadiría volumen, pero no ampliaría la cobertura.
Muestrea los vídeos sin saturar el conjunto de datos#
El vídeo es la fuente más barata y la más fácil de usar mal. A 30 fotogramas por segundo, un minuto genera 1.800 fotogramas casi idénticos; etiquetar dos veces el mismo momento cuesta dinero e infla las métricas. Conserva un fotograma solo cuando la escena haya cambiado desde el último que guardaste:
from pathlib import Path
import cv2
from ultralytics.utils.downloads import safe_download
video = "solutions_ci_demo.mp4" # a short public demo clip; swap in your own footage
safe_download(f"https://github.com/ultralytics/assets/releases/download/v0.0.0/{video}")
Path("frames").mkdir(exist_ok=True)
cap = cv2.VideoCapture(video)
fps = cap.get(cv2.CAP_PROP_FPS)
read = kept = 0
last = None
while True:
ok, frame = cap.read()
if not ok:
break
thumb = cv2.cvtColor(cv2.resize(frame, (64, 64)), cv2.COLOR_BGR2GRAY).astype(float)
if last is None or abs(thumb - last).mean() > 10: # keep a frame only when the scene has changed
cv2.imwrite(f"frames/clip01_{read:06d}.jpg", frame) # the clip ID stays in the filename
kept, last = kept + 1, thumb
read += 1
print(f"{read} frames at {fps:.0f} FPS -> {kept} kept")62 frames at 30 FPS -> 6 keptEl clip de dos segundos contiene 62 fotogramas, pero solo 6 momentos visualmente distintos. El script compara pequeñas miniaturas en escala de grises, así que procesa rápidamente horas de grabación. Sube el umbral de 10 para conservar menos fotogramas de cámaras estáticas; bájalo para escenas con mucho movimiento. Reparte también el presupuesto entre clips: 20 fotogramas de cada uno de 50 clips son mejor que 1.000 fotogramas de uno solo.
Dos fotogramas separados por un segundo comparten la iluminación, el fondo y, normalmente, los mismos objetos. Si acaban tanto en entrenamiento como en validación, la evaluación se hace con imágenes que el modelo ya ha visto prácticamente. Conserva el ID del clip en todos los nombres de archivo para que Dividir correctamente el conjunto de datos mantenga unido cada clip.
Evita los errores al recopilar datos#
| Error | Síntoma | Solución |
|---|---|---|
| Recopilación durante una sola semana | mAP de validación alto, pero fallos en otras estaciones o turnos | Reparte la captura entre varias semanas o meses |
| Una sola cámara | Falla con la segunda cámara | Captura imágenes con cada tipo de cámara que vayas a usar |
| Solo datos escenificados | Falla con el desorden real | Mantén las imágenes escenificadas como una pequeña minoría controlada |
| Fotogramas duplicados | Métricas infladas y trabajo de etiquetado desperdiciado | Muestrea según los cambios de escena; Ultralytics Platform también omite las copias exactas al subirlas |
| Un solo operador o turno | Apariencia no prevista y desequilibrio entre clases | Muestrea en distintos turnos, centros y entre distintas personas |
| Faltan casos poco frecuentes | No detecta los incidentes de seguridad más importantes | Captura específica, escenificación o ampliación con datos sintéticos |
Sesgo y consentimiento#
El sesgo es un problema de recopilación, no de modelado: ningún hiperparámetro puede corregir la ausencia de un grupo en los datos. La guía de recopilación de datos enumera cuatro medidas: fuentes diversas, representación equilibrada, revisiones periódicas de la cobertura y medidas de mitigación, como sobremuestrear los grupos infrarrepresentados.
Si las imágenes contienen rostros, matrículas u otros datos personales, necesitas obtener el consentimiento y definir una política de conservación antes de empezar la recopilación. La entrada del glosario sobre privacidad de datos es un buen punto de partida, y Privacidad, regiones y cumplimiento explica cómo mantener los datos en la jurisdicción adecuada con dataRegion.
Mostrar solución
Para el conjunto de práctica, el informe de cobertura ofrece un plan directo:
| Fuente | Recuento / cuota | Acción |
|---|---|---|
cam1 | 52 / 30 | Deja de recopilar: ya representa el 40 % de todas las imágenes |
cam2 | 26 / 30 | Recopila 4 más |
cam3 | 25 / 30 | Recopila 5 más |
cam4 | 25 / 30 | Recopila 5 más |
Cada cámara cubre los cuatro días, así que las carencias corresponden a cada cámara, no a cada día. Reparte las 14 imágenes nuevas entre al menos dos días nuevos para que aporten una condición distinta, en lugar de más de lo mismo de una tarde. Si una cámara no puede cubrir su carencia (por ejemplo, una cámara que solo ve escenas nocturnas), añade una fila en las especificaciones para la condición que falta e indica si la cubres con imágenes escenificadas o generadas, para poder medir su efecto más adelante.