Özel Bir Veri Kümesi Hazırla
Görüntüleri ve etiketleri Ultralytics YOLO biçiminde düzenle, piksel koordinatlı kutuları normalize edilmiş etiket satırlarına dönüştür ve eğitimden önce bozuk etiketleri yakala.
Yanlış adlandırılmış tek bir klasör ya da normalize edilmemiş bir etiket eğitimin çökmesine yol açmaz. Ultralytics bozuk görüntüleri atlayıp devam eder; böylece verilerinin yalnızca bir bölümüyle eğitim yapar, vasat bir model elde eder ve nedenini yanlış yerde ararken bir öğleden sonranı kaybedersin.
Bu derste nesne tespiti veri kümesinin mekanik yönlerini ele alacağız: klasörler, etiket satırları, dönüştürme ve kontroller. Kursun geri kalanında eğitim için kullanılan, gerçek 115 görüntülük tıbbi hap veri kümesi üzerinde çalışacaksın. Neleri toplaman ve nasıl etiketlemen gerektiğini Etiketleme için En İyi Uygulamalar konusu ele alıyor.
Uygulamalı
Alıştırma Veri Kümesini Al#

Aşağıdaki düzen, Ultralytics Platform'un Yeni Veri Kümesi iletişim kutusunun ZIP dosyası olarak kabul ettiği düzenle aynıdır; dolayısıyla burada hazırladığın veri kümesini değiştirmeden yükleyebilirsin. Blister ambalajlardaki hapların 92 eğitim ve 23 doğrulama karesini indir ve my_dataset içine aç:
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_datasetmy_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)Manifest dosyası yok. Ultralytics, görüntü yolundaki /images/ değerini /labels/ ile ve uzantıyı .txt ile değiştirerek her etiketi bulur; bu nedenle images/val/Frame_144.jpg, labels/val/Frame_144.txt dosyasını okur. Bunun iki sonucu var:
- Klasörlerin yan yana ve tam olarak
imagesilelabelsadlarına sahip olması gerekir. - Etiket dosyası boş ya da eksik olan bir görüntü arka plan görüntüsüdür: geçerlidir ve modele neyi tespit etmemesi gerektiğini öğretmek için yararlıdır; ancak bunu yalnızca bilerek yaptıysan kullan.
Etiket Satırını Oku#

Her satır tek bir nesneyi belirtir: önce bir tamsayı sınıf indeksi, ardından sınırlayıcı kutunun merkezi ve boyutu, görüntü genişliğinin ve yüksekliğinin kesirleri olarak verilir. labels/train/Frame_0.txt dosyasından gerçek bir satır:
0 0.330729 0.816204 0.103125 0.1212960: YAML dosyasındapilladı verilecek sınıf indeksi 0.0.330729 0.816204: kutunun merkezi, yatayda yolun %33'ünde ve dikeyde %82'sinde.0.103125 0.121296: kutu, görüntünün genişliğinin yaklaşık %10'u ve yüksekliğinin %12'si kadar.
Uygulamalı Örnek: Piksel Koordinatlı Bir Kutuyu Dönüştür#
Etiketleme araçları çoğu zaman piksel cinsinden köşe koordinatlarını dışa aktarır (x1, y1, x2, y2). Görüntü boyutlarına böl. Önceki dersteki 810×1080 boyutlu bus.jpg görüntüsünde en soldaki kişi (49, 398) ile (240, 902) koordinatları arasında:
| Alan | Formül | Değer |
|---|---|---|
x_center | (x1 + x2) / 2 / genişlik | (49 + 240) / 2 / 810 = 0.178395 |
y_center | (y1 + y2) / 2 / yükseklik | (398 + 902) / 2 / 1080 = 0.601852 |
width | (x2 − x1) / genişlik | 191 / 810 = 0.235802 |
height | (y2 − y1) / yükseklik | 504 / 1080 = 0.466667 |
Çoğu etiketleme aracı ve Roboflow gibi araçlar YOLO biçimini doğrudan dışa aktarabilir. COCO JSON için COCO JSON eğitim kılavuzunu izle; diğer biçimler için JSON2YOLO deposuna bak. Pascal VOC XML için yukarıdaki formül kısa bir betiğe sığar:
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())Önceki dersteki kişi ve otobüs kutularını içeren bir bus.xml üzerinde çalıştırıldığında, uygulamalı örneği ve otobüsü yazdırır:
0 0.178395 0.601852 0.235802 0.466667
1 0.495679 0.454167 0.991358 0.482407Eğitimden Önce Kontrol Et#
Birkaç etiket dosyasını ilgili görüntülerin üzerine çiz. Sınıfın kaymış olması, x ile y'nin yer değiştirmesi veya kutuların gölgeleri sarması gözle kolayca fark edilir ama metriklerde görünmez:
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"},
)Ardından Ultralytics'in her dosyayı denetlemesini sağla. Veri kümesini ilk okuduğunda etiketleri tarar ve her görüntünün kullanılabilir olup olmadığına satır satır karar verir:
Tarama satırı sonucu bildirir: sağlıklı bir veri kümesinin nasıl göründüğünü 23 images, 0 backgrounds, 0 corrupt gösterir. Bunun dışındaki her şey aşağıdaki hatalardan biridir.
Bu Hatalardan Kaçın#
Belirti: ignoring corrupt image/label: non-normalized or out of bounds coordinates [634. 881. 198. 163.] ve sıfırdan farklı bir corrupt sayısı. Neden: Kesirler yerine piksel değerleri kullanılmış. Çözüm: Genişlik ve yükseklik değerlerine böl. Etiket değeri 1'den büyükse kutu hiç normalize edilmemiş demektir.
Belirti: yolo val, 0 images, 23 backgrounds klasörünü tarayıp No labels found uyarısı veriyor ve eğitim ValueError: train: No labels found ile duruyor — bu durumda etiket klasörünün adı annotations olduğu için. Çözüm: Eşleşen dosya adlarıyla klasörleri tam olarak images ve labels şeklinde adlandır.
Belirti: Label class 1 exceeds dataset class count 1. Possible class labels are 0-0. Neden: Dışa aktarma aracı sınıfları 1'den numaralandırmış. Çözüm: YOLO sınıfları 0'dan başlar; dönüştürme betiğinde 1 çıkar veya dışa aktarma ayarını düzelt.
Kutular yarım kutu kadar aşağı ve sağa kaymış çiziliyorsa x_center y_center w h yerine x1 y1 w h yazmışsın demektir. Tek bir dosyayı çizdirmek bunu saniyeler içinde ortaya çıkarır; tarama denetimi bunu yapamaz.
Tüm veri kümesinde sistematik kontroller için Veri Kümesi Kalite Kontrolü konusuna bak. coco8, coco128 ve african-wildlife gibi yerleşik kümeler, örnek alınabilecek iyi düzenlere sahiptir; veri kümelerine genel bakış hepsini listeler. Eğitici, etiketlerine veri artırma uygular; bu nedenle burada yapacağın hızlı bir veri temizliği her epoch'ta karşılığını verir.
Çözümü göster
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 labelsfrom 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)Betikten çıktı alınmaması her koordinatın normalize edildiği anlamına gelir. Her bölmedeki sayımların eşit olması her görüntünün bir etiket dosyası olduğunu gösterir; sonraki derste tarama satırı bozuk dosya olmadığını doğrular.