Ultralytics YOLO27: Únete a la lista de espera.
Get Started
Entrena tu primer modelo YOLO·Datos·Lección 4/10
Lecciónprincipiante

Prepara un conjunto de datos personalizado

Organiza las imágenes y las etiquetas en el formato Ultralytics YOLO, convierte las cajas en píxeles a líneas de etiquetas normalizadas y detecta las etiquetas defectuosas antes de entrenar.

Una carpeta mal nombrada o una etiqueta sin normalizar no detiene el entrenamiento. Ultralytics omite las imágenes defectuosas y sigue adelante, así que entrenas con parte de tus datos, obtienes un modelo mediocre y pierdes una tarde buscando la causa en el sitio equivocado.

Esta lección trata la parte mecánica de un conjunto de datos de detección: carpetas, líneas de etiquetas, conversión y comprobaciones. Trabajarás con el conjunto de datos real de píldoras médicas de 115 imágenes que se utiliza para entrenar en el resto del curso. En Buenas prácticas de anotación se explica cómo decidir qué recopilar y cómo etiquetarlo.

Resultado

Puedes organizar un conjunto de datos en el formato Ultralytics YOLO, convertir las cajas en píxeles en líneas de etiquetas normalizadas y detectar etiquetas que falten o estén dañadas a partir de la línea del análisis antes de entrenar.

Vía rápida
Si ya tienes experiencia, aquí tienes un resumen.
  1. Crea images/{train,val} y labels/{train,val} con nombres de archivo coincidentes.

  2. Escribe una línea class x_center y_center width height por objeto, con todos los valores entre 0 y 1.

  3. Convierte las cajas en píxeles dividiendo entre la anchura y la altura de la imagen.

  4. Dibuja un archivo de etiquetas sobre su imagen y comprueba que la línea del análisis indica 0 corrupt.

Práctico

Obtén el conjunto de datos de prácticas#

Cuadro de diálogo Nuevo conjunto de datos de Ultralytics Platform: zona para soltar imágenes, vídeos o conjuntos de datos YOLO, COCO y NDJSON, seguida de los campos de nombre, URL, descripción y tipo de tarea

La estructura siguiente también es válida como archivo ZIP en el cuadro de diálogo Nuevo conjunto de datos de Ultralytics Platform, así que puedes subir sin cambios el conjunto de datos que prepares aquí. Descarga 92 fotogramas de entrenamiento y 23 de validación de píldoras en blísteres y descomprímelos en my_dataset:

curl -L -o medical-pills.zip https://github.com/ultralytics/assets/releases/download/v0.0.0/medical-pills.zip
unzip -q medical-pills.zip -d my_dataset
my_dataset/
├── images/
│   ├── train/   Frame_0.jpg, Frame_100.jpg, ... (92 images)
│   └── val/     Frame_144.jpg, ... (23 images)
└── labels/
    ├── train/   Frame_0.txt, Frame_100.txt, ... (92 files)
    └── val/     Frame_144.txt, ... (23 files)

No hay ningún manifiesto. Ultralytics encuentra cada etiqueta sustituyendo /images/ por /labels/ en la ruta de la imagen y cambiando la extensión por .txt, así que images/val/Frame_144.jpg lee labels/val/Frame_144.txt. Esto tiene dos consecuencias:

  • Las carpetas deben llamarse exactamente images y labels, y estar una junto a la otra.
  • Una imagen con un archivo de etiquetas vacío o inexistente es una imagen de fondo: es válida y útil para enseñar al modelo qué no debe detectar, pero solo si esa era tu intención.

Interpreta una línea de etiqueta#

Archivo de etiquetas YOLO para zidane.jpg, una fila por objeto: índice de clase, seguido del centro x, centro y, anchura y altura normalizados

Cada línea corresponde a un objeto: un índice de clase entero, seguido del centro y el tamaño de la caja delimitadora como fracciones de la anchura y la altura de la imagen. Una línea real de labels/train/Frame_0.txt:

0 0.330729 0.816204 0.103125 0.121296
  • 0: índice de clase 0, que el archivo YAML denominará pill.
  • 0.330729 0.816204: el centro de la caja está al 33 % de la anchura y al 82 % de la altura.
  • 0.103125 0.121296: la caja ocupa aproximadamente el 10 % de la anchura y el 12 % de la altura de la imagen.

Ejemplo práctico: convierte una caja en píxeles#

Las herramientas de etiquetado suelen exportar las esquinas en píxeles (x1, y1, x2, y2). Divide entre el tamaño de la imagen. La persona situada más a la izquierda en bus.jpg, de 810×1080, de la lección anterior ocupa desde (49, 398) hasta (240, 902):

CampoFórmulaValor
x_center(x1 + x2) / 2 / width(49 + 240) / 2 / 810 = 0.178395
y_center(y1 + y2) / 2 / height(398 + 902) / 2 / 1080 = 0.601852
width(x2 − x1) / width191 / 810 = 0.235802
height(y2 − y1) / height504 / 1080 = 0.466667

La mayoría de las herramientas de etiquetado, y herramientas como Roboflow, pueden exportar directamente al formato YOLO. Para COCO JSON, sigue la guía de entrenamiento con COCO JSON; el repositorio JSON2YOLO cubre otros formatos. Para archivos XML de VOC de Pascal, puedes aplicar la fórmula anterior con un script breve:

import xml.etree.ElementTree as ET
from pathlib import Path

CLASSES = ["person", "bus"]  # index = class id; must match names in data.yaml

def voc_to_yolo(xml_file: Path, out_dir: Path) -> None:
    root = ET.parse(xml_file).getroot()
    w, h = int(root.find("size/width").text), int(root.find("size/height").text)
    lines = []
    for obj in root.iter("object"):
        name = obj.find("name").text
        if name not in CLASSES:
            continue
        box = obj.find("bndbox")
        x1, y1, x2, y2 = (float(box.find(k).text) for k in ("xmin", "ymin", "xmax", "ymax"))
        xc, yc, bw, bh = (x1 + x2) / 2 / w, (y1 + y2) / 2 / h, (x2 - x1) / w, (y2 - y1) / h
        lines.append(f"{CLASSES.index(name)} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}")
    out_dir.mkdir(parents=True, exist_ok=True)
    (out_dir / f"{xml_file.stem}.txt").write_text("\n".join(lines) + "\n")

voc_to_yolo(Path("bus.xml"), Path("labels"))
print(Path("labels/bus.txt").read_text())

Si lo ejecutas en un bus.xml que contenga las cajas de la persona y el autobús de la lección anterior, imprimirá el ejemplo práctico y el autobús:

0 0.178395 0.601852 0.235802 0.466667
1 0.495679 0.454167 0.991358 0.482407

Comprueba todo antes de entrenar#

Dibuja algunos archivos de etiquetas sobre sus imágenes. Una clase desplazada, las coordenadas x e y intercambiadas o cajas alrededor de sombras se ven a simple vista, pero no en las métricas:

from ultralytics.data.utils import visualize_image_annotations

visualize_image_annotations(
    "my_dataset/images/train/Frame_0.jpg",
    "my_dataset/labels/train/Frame_0.txt",
    {0: "pill"},
)

Después, deja que Ultralytics compruebe todos los archivos. Analiza las etiquetas la primera vez que lee un conjunto de datos y decide, línea por línea, si cada imagen se puede usar:

La línea del análisis indica el resultado: 23 images, 0 backgrounds, 0 corrupt es el aspecto que tiene un conjunto de datos correcto. Cualquier otro resultado corresponde a uno de los errores siguientes.

Evita estos errores#

Olvidarse de la normalización

Síntoma: ignoring corrupt image/label: non-normalized or out of bounds coordinates [634. 881. 198. 163.] y un recuento de corrupt distinto de cero. Causa: se han usado valores de píxel en lugar de fracciones. Solución: divide entre la anchura y la altura de la imagen. Si algún valor de etiqueta supera 1, significa que el cuadro nunca se normalizó.

La carpeta de etiquetas tiene un nombre incorrecto

Síntoma: yolo val analiza 0 images, 23 backgrounds y muestra la advertencia No labels found; el entrenamiento se detiene con ValueError: train: No labels found, en este caso porque la carpeta de etiquetas se llamaba annotations. Solución: asigna exactamente los nombres images y labels a las carpetas, y asegúrate de que los nombres de archivo coincidan.

Los índices de clase empiezan en 1

Síntoma: Label class 1 exceeds dataset class count 1. Possible class labels are 0-0. Causa: la herramienta de exportación numeró las clases empezando por 1. Solución: las clases de YOLO empiezan en 0; resta 1 en el script de conversión o corrige el ajuste de exportación.

Esquinas frente a centros

Si los cuadros aparecen desplazados media caja hacia abajo y a la derecha, has escrito x1 y1 w h en lugar de x_center y_center w h. Dibujar un archivo permite detectarlo en segundos; ninguna comprobación de análisis puede hacerlo.

Para realizar comprobaciones sistemáticas en todo un conjunto de datos, consulta Control de calidad de los conjuntos de datos. Los conjuntos integrados, como coco8, coco128 y african-wildlife, son buenos ejemplos de estructuras que puedes copiar; en la descripción general de conjuntos de datos se enumeran todos. El entrenador aplica aumento de datos a tus etiquetas, así que una limpieza rápida de los datos aquí beneficia cada época.

Pruébalo

Descarga el conjunto de datos de píldoras en my_dataset. Entrega tres comprobaciones: el número de imágenes y etiquetas de cada partición; el resultado de un script que imprima cualquier valor de etiqueta fuera del intervalo 0–1 (no debería imprimir nada); y un archivo de etiquetas dibujado sobre su imagen con visualize_image_annotations. Si tienes imágenes etiquetadas propias, convierte 10 al mismo formato y dibuja una.

Cuándo se considera terminado
Has terminado la lección cuando se cumplen todas estas condiciones.
  • my_dataset contiene images/train, images/val, labels/train y labels/val, con nombres de archivo y cantidades coincidentes.

  • El script de comprobación no encuentra ningún valor de etiqueta fuera del intervalo 0–1.

  • Has dibujado al menos un archivo de etiquetas sobre su imagen y las cajas están colocadas sobre las píldoras.

Mostrar solución
for s in train val; do
  echo "$s: $(ls my_dataset/images/$s | wc -l) images, $(ls my_dataset/labels/$s | wc -l) labels"
done
# train: 92 images, 92 labels
# val:   23 images, 23 labels
from pathlib import Path

for txt in Path("my_dataset/labels").rglob("*.txt"):
    for line in txt.read_text().splitlines():
        values = [float(v) for v in line.split()[1:]]
        if any(v < 0 or v > 1 for v in values):
            print(txt, line)

Si el script no genera resultados, todas las coordenadas están normalizadas. Si las cantidades de cada partición coinciden, todas las imágenes tienen un archivo de etiquetas; la línea del análisis de la próxima lección confirmará que no hay archivos dañados.

Qué viene después

Las carpetas están listas. A continuación, escribe el único archivo YAML que indica a Ultralytics dónde están y qué significan las clases.