Conjuntos de dados que refletem a realidade
Audite um conjunto de dados real para identificar lacunas de cobertura antes de rotular mais imagens e transforme essas lacunas em um plano de coleta com negativos difíceis.
A maioria dos modelos de visão que decepcionam não são modelos ruins — são bons modelos treinados com um conjunto de dados que não se parece com o local onde serão implantados. O detector COCO da lição anterior não encontrou nenhum barco em imagens de drone porque os barcos do COCO são fotografados de lado. Uma auditoria de cinco minutos revela essas lacunas antes de você gastar dinheiro com rótulos.
Prático
Os modelos aprendem o conjunto de dados, não o mundo#
Um modelo interpola entre os exemplos que viu. Treine com ruas ensolaradas durante o dia e implante em uma garagem com neblina à noite, e ele falhará — não porque os carros pareçam diferentes, mas porque nunca viu um carro nessas condições. Essa incompatibilidade é chamada de mudança de domínio, e a validação não consegue alertar você sobre ela quando as imagens de validação vêm da mesma coleção enviesada:
A solução é estrutural, não algorítmica: amostre deliberadamente o ambiente de implantação antes de rotular. O guia de coleta e anotação de dados explica os procedimentos.
Audite um conjunto de dados real#

O conjunto de dados medical-pills acima — close-ups de cartelas com cada comprimido delimitado por uma caixa — é um bom exemplo para auditoria. A Ultralytics Platform mostra as contagens principais na página do conjunto de dados; o script abaixo calcula os números que revelam a cobertura na cópia distribuída com ultralytics:
from collections import Counter
from pathlib import Path
from PIL import Image, ImageStat
from ultralytics.data.utils import check_det_dataset
data = check_det_dataset("medical-pills.yaml") # downloads the dataset on first use
for split in ("train", "val"):
images = sorted(Path(data[split]).glob("*.jpg"))
labels = [Path(str(p).replace("/images/", "/labels/")).with_suffix(".txt") for p in images]
rows = [line.split() for f in labels if f.exists() for line in f.read_text().splitlines()]
classes = Counter(data["names"][int(r[0])] for r in rows)
backgrounds = sum(not f.exists() or not f.read_text().strip() for f in labels)
areas = sorted(float(r[3]) * float(r[4]) for r in rows) # box area as a share of the image
sizes = Counter(Image.open(p).size for p in images)
brightness = [ImageStat.Stat(Image.open(p).convert("L")).mean[0] for p in images]
print(f"{split}: {len(images)} images, {backgrounds} backgrounds, {dict(classes)}, sizes {dict(sizes)}")
print(f" boxes: median {areas[len(areas) // 2]:.1%} of the image, {sum(a < 0.01 for a in areas)} of {len(areas)} under 1%")
print(f" brightness: {min(brightness):.0f} to {max(brightness):.0f} (0 = black, 255 = white)")train: 92 images, 0 backgrounds, {'pill': 1623}, sizes {(1920, 1080): 92}
boxes: median 1.4% of the image, 320 of 1623 under 1%
brightness: 171 to 198 (0 = black, 255 = white)
val: 23 images, 0 backgrounds, {'pill': 399}, sizes {(1920, 1080): 23}
boxes: median 1.4% of the image, 79 of 399 under 1%
brightness: 171 to 198 (0 = black, 255 = white)Leia o resultado como um relatório de cobertura, com uma constatação por linha:
| Constatação | O que significa | Decisão |
|---|---|---|
| Uma resolução, 1920×1080 | Uma câmera, uma configuração | Colete imagens de todos os modelos de câmera que serão usados na implantação |
| Brilho de apenas 171–198 | Iluminação de estúdio clara e uniforme, sem cenas escuras | Colete imagens com pouca luz, contraluz e iluminação mista antes de implantar em um balcão de farmácia |
| 0 imagens de fundo | O modelo nunca vê uma cena sem comprimidos | Adicione cartelas vazias, outros comprimidos e balcões vazios como negativos difíceis |
| A caixa mediana ocupa 1,4% da imagem; 1 em cada 5 caixas tem menos de 1% | Objetos pequenos | Mantenha imgsz alto o suficiente e inclua deliberadamente imagens tiradas de longe |
Uma classe, pill | Sem tipos de comprimido | Adequado para contagem; adicione classes apenas se uma decisão exigir isso |
Nada disso aparece na pontuação de validação, pois a validação compartilha todas essas características.
Os quatro eixos de cobertura#
| Eixo | O que coletar | Falha típica quando falta |
|---|---|---|
| Iluminação | Amanhecer, meio-dia, anoitecer, noite, reflexos intensos, contraluz, lâmpadas fluorescentes piscando | A taxa de recuperação despenca durante as trocas de turno ou sob luz solar direta |
| Clima e condições atmosféricas | Chuva, neblina, neve, poeira, condensação na lente | Falsos positivos causados por gotas, objetos não detectados na neblina |
| Oclusão e desordem visual | Alvos parcialmente ocultos, cenas lotadas, objetos cortados pela borda do enquadramento | Os objetos deixam de ser detectados sempre que o alvo não está totalmente visível |
| Câmera e ponto de vista | Lente, altura e ângulo de montagem, resolução, compressão, desfoque de movimento | Funciona na câmera piloto, falha no próximo local |
O ponto de vista é o eixo que faltou no exemplo da marina: a mesma classe vista de um novo ângulo, e a taxa de recuperação caiu para zero.
Negativos difíceis e imagens de fundo#
Um detector também precisa aprender o que não é o alvo. Negativos difíceis parecem superficialmente semelhantes: para um detector de empilhadeiras, uma paleteira, uma plataforma elevatória tipo tesoura, o reflexo de uma empilhadeira em um piso polido ou um cartaz de segurança com a imagem de uma empilhadeira.
No formato YOLO, uma imagem de fundo é simplesmente uma imagem sem arquivo de rótulos — nada para desenhar. As dicas de treinamento do Ultralytics recomendam aproximadamente 0–10% de imagens de fundo para reduzir falsos positivos; o próprio COCO tem cerca de 1%. Preencha essa parcela com negativos difíceis do seu próprio ambiente, em vez de quadros vazios aleatórios. O aumento de dados pode variar o brilho e o ângulo, mas não pode inventar uma paleteira que o modelo nunca viu.
Armadilhas#
Sintoma: 10.000 imagens rotuladas, todas diurnas e da câmera-piloto. Solução: grave imagens com as câmeras de implantação em toda a variedade de condições durante algumas semanas, audite a cobertura e só então pague pela rotulagem. Dados sintéticos podem preencher uma lacuna conhecida, mas não substituem capturas reais.
Sintoma: mAP alto na validação, resultados ruins no primeiro novo local. Solução: lembre-se de que a validação compartilha os pontos cegos do conjunto de dados. Escolha dez imagens aleatórias de treinamento e dez quadros de produção, e peça a um colega para distingui-los; se conseguir, há uma lacuna de domínio.
Para um plano de amostragem com contagens-alvo por condição, continua com Recolher dados representativos e de alta qualidade em Criar conjuntos de dados YOLO de alto desempenho.
Mostrar solução
Para medical-pills implantado no balcão de uma farmácia sob iluminação mista de loja, preenche a grelha com base na auditoria (brilho de 171–198, uma fonte de 1920×1080, zero fundos) e numa rápida passagem pelas imagens, que mostra as mesmas embalagens sobre a mesma superfície clara, sem mãos:
| Classe | Luz forte de estúdio | Luz fraca ou quente de loja | Contraluz / reflexo | Parcialmente coberto por uma mão | Câmara de telemóvel |
|---|---|---|---|---|---|
pill | 2,022 | 0 | 0 | 0 | 0 |
| fundo | 0 | 0 | 0 | — | 0 |
Plano de recolha por ordem de prioridade:
- Luz fraca ou quente de loja — a condição normal do balcão, atualmente com zero imagens.
- Parcialmente coberto por uma mão — acontece em quase todas as interações reais.
- Câmara de telemóvel — um segundo sensor e uma segunda resolução.
- Contraluz / reflexo — as embalagens de folha metálica refletem as janelas e as luzes do teto.
Negativos difíceis: blisters vazios (mesma folha metálica, sem comprimidos) e outros objetos redondos no balcão — moedas, botões, doces. Adiciona-os como imagens de fundo, cerca de 5–10% do conjunto de dados.