Asosiy qismga o'tish

YOLO qayerdan kelgan: R-CNN dan YOLO26 gacha

2-bob 8 kod bloki 3905 so'z

Bu bobning kodi: kod/02_yolo_tarixi.py — kitob papkasidan ishga tushiring: python kod/02_yolo_tarixi.py

Nega tarix kerak

"YOLO" bitta model emas. Bu 2015-yilda paydo bo'lgan g'oya, keyin esa turli jamoalar o'z modellariga qo'ygan nom. YOLOv4 ni bir jamoa, YOLOv5 ni boshqa kompaniya, YOLOv6 ni yana boshqasi yozgan. Versiya raqami katta bo'lsa, model albatta yaxshiroq degani emas. Litsenziyalari ham har xil: birini bemalol sotish mumkin, boshqasi uchun butun kodingizni ochishga majbursiz.

Har bir versiya bitta aniq muammoni hal qilgan. Qaysi muammoni bilsangiz, YOLO11 ichidagi qismlar (anchor, uch masshtab, NMS, DFL) nega kerakligi o'z-o'zidan tushunarli bo'ladi. 4–6-boblarda aynan shu qismlarni ochamiz.

YOLO dan oldin: ikki bosqichli detektorlar

2013-yil noyabrida Ross Girshick va hamkasblari R-CNN ni chiqarishdi ("Rich feature hierarchies for accurate object detection and semantic segmentation", arXiv 1311.2524). G'oya ikki bosqichli edi:

  1. Qayerda nimadir bor? Rasmdan ~2 000 ta "shubhali" bo'lak (region proposal) oddiy algoritm bilan kesib olinadi.
  2. U nima? Har bir bo'lak alohida CNN dan o'tkaziladi va sinfi aniqlanadi.

Aniqlik keskin oshdi: PASCAL VOC 2012 da mAP 53.3%, oldingi eng yaxshi natijadan 30% dan ko'proq nisbiy yaxshilanish. Lekin bitta rasm uchun CNN ~2 000 marta ishlaydi. Real vaqt haqida gap ham bo'lmasdi.

Keyingi ikki yil shu sekinlik bilan kurashildi. Fast R-CNN (2015) CNN ni butun rasmga bir marta qo'llab, bo'laklarni tayyor xususiyatlardan kesadigan qildi. Faster R-CNN (2015) bo'laklarni topishni ham neyron tarmoqqa topshirdi. Tezlashdi, lekin ikki bosqich qoldi: avval "qayerda", keyin "nima".

YOLOv1 (2015): bir marta qarash

2015-yil 8-iyunda Joseph Redmon, Santosh Divvala, Ross Girshick va Ali Farhadi "You Only Look Once: Unified, Real-Time Object Detection" maqolasini chiqarishdi (arXiv 1506.02640). Asosiy jumla:

"We frame object detection as a regression problem to spatially separated bounding boxes and associated class probabilities."

Ya'ni: detection — bu regressiya. Bo'laklar yo'q, ikki bosqich yo'q. Bitta tarmoq, butun rasmga bir marta qaraydi va hamma box larni birdaniga chiqaradi. Maqoladagi tezlik: sekundiga 45 kadr, kichik versiyasi (Fast YOLO) 155 kadr.

Qanday qilib? Rasm S × S to'rga bo'linadi (YOLOv1 da 7 × 7). Obyektning markazi qaysi katakka tushsa, o'sha katak shu obyekt uchun javobgar:

kod/02_yolo_tarixi.pyyangi fayl · 1-qator: from kitob_yordam import fig, show
python23 qator
import cv2
import matplotlib.pyplot as plt
from ultralytics import YOLO
from ultralytics.utils import ASSETS

model = YOLO("weights/yolo11n.pt")
natija = model.predict(ASSETS / "bus.jpg", verbose=False)[0]
img = cv2.imread(str(ASSETS / "bus.jpg"))[:, :, ::-1]   # BGR -> RGB
H, W = img.shape[:2]
S = 7                                                   # YOLOv1 to'ri: 7 x 7 katak

_, ax = plt.subplots(figsize=(5, 6.4))
ax.imshow(img)
for i in range(1, S):                                   # katak chegaralari
    ax.axvline(W * i / S, color="white", lw=1)
    ax.axhline(H * i / S, color="white", lw=1)
for (xc, yc, w, h), c in zip(natija.boxes.xywh.tolist(), natija.boxes.cls.tolist()):
    ustun, qator = int(xc // (W / S)), int(yc // (H / S))   # markaz qaysi katakka tushdi
    ax.add_patch(plt.Rectangle((ustun * W / S, qator * H / S), W / S, H / S, color="yellow", alpha=0.4))
    ax.plot(xc, yc, "o", color="red", ms=7)
    print(f"{natija.names[int(c)]:6s} markazi ({xc:4.0f}, {yc:4.0f}) -> katak: qator {qator}, ustun {ustun}")
ax.axis("off")
fig("grid7.png", "YOLOv1 g'oyasi: obyekt markazi (qizil nuqta) tushgan katak (sariq) shu obyekt uchun javobgar.")
Chiqish
bus    markazi ( 400,  479) -> katak: qator 3, ustun 3
person markazi ( 740,  637) -> katak: qator 4, ustun 6
person markazi ( 143,  652) -> katak: qator 4, ustun 1
person markazi ( 284,  635) -> katak: qator 4, ustun 2
person markazi (  34,  714) -> katak: qator 4, ustun 0

YOLOv1 g'oyasi: obyekt markazi (qizil nuqta) tushgan katak (sariq) shu obyekt uchun javobgar.

YOLOv1 g'oyasi: obyekt markazi (qizil nuqta) tushgan katak (sariq) shu obyekt uchun javobgar.

Har bir katak nimani chiqaradi? YOLOv1 da: B = 2 ta box (har biri x, y, w, h va ishonch — 5 ta raqam) va C = 20 ta sinf ehtimoli (PASCAL VOC da 20 sinf). Butun chiqish bitta tensor:

kod/02_yolo_tarixi.pydavomi
python2 qator
S, B, C = 7, 2, 20
print("YOLOv1 chiqishi:", f"{S} x {S} x {B * 5 + C}", "=", S * S * (B * 5 + C), "ta raqam,", S * S, "ta katak")
Chiqish
YOLOv1 chiqishi: 7 x 7 x 30 = 1470 ta raqam, 49 ta katak

Bu g'oyaning zaif joyi ham shu yerdan ko'rinadi: 49 ta katak, har birida 2 ta box. Bitta katakka uchta odamning markazi tushsa (olomon, uzoqdagi kichik obyektlar, bir to'da qush), bittasi albatta yo'qoladi. Keyingi versiyalarning katta qismi aynan shu cheklov bilan kurashgan. YOLO11 da kataklar soni qancha ekanini shu bobning oxirida o'lchaymiz.

v2 va v3: anchor lar va uch masshtab

YOLOv2 / YOLO9000 (dekabr 2016, arXiv 1612.08242). Asosiy yangilik — anchor box lar: har katak box ni noldan emas, oldindan tayyor shakllardan ("bo'yi baland ingichka", "keng past" ...) boshlab, ularni biroz o'zgartirib chiqaradi. Shakllar datasetdagi box larni k-means bilan guruhlab tanlangan. Odam uchun tik, mashina uchun yotiq shakl tayyor turadi, tarmoqqa faqat tuzatish qoladi.

YOLOv3 (aprel 2018, arXiv 1804.02767). Kuchliroq tayanch tarmoq (Darknet-53) va eng muhimi — uch masshtabda bashorat: katta obyektlar qo'pol to'rda, kichiklar mayda to'rda qidiriladi. Bu g'oya bugungi YOLO11 da ham turibdi: uning uchta chiqishi 8, 16 va 32 piksel qadamli to'rlar (4-bob).

Uch versiyaning hammasi Redmon ning o'z C kutubxonasi Darknet da yozilgan. Uning litsenziyasi hazil bilan yozilgan, lekin mazmuni aniq:

"0. Darknet is public domain. 1. Do whatever you want with it. 2. Stop emailing me about it!"

Ya'ni asl YOLO — hech qanday shartsiz, jamoat mulki.

2020: Redmon ketadi, YOLO nomga aylanadi

2020-yil 20-fevralda Joseph Redmon Twitter da shunday yozdi:

"I stopped doing CV research because I saw the impact my work was having. I loved the work but the military applications and privacy concerns eventually became impossible to ignore."

Tarjimasi: "Kompyuter ko'rish bo'yicha tadqiqotni to'xtatdim, chunki ishim qanday ta'sir qilayotganini ko'rdim. Bu ishni yaxshi ko'rardim, lekin harbiy qo'llanishlar va shaxsiy hayot daxlsizligi masalalarini e'tiborsiz qoldirib bo'lmay qoldi."

YOLO ni yaratgan odam aynan shu kitob o'rgatadigan narsa — odamlarni kamera orqali kuzatish — sababli sohadan ketdi. Bu IV qismda yana qaytadigan savol: texnologiya ishlaydi, lekin uni qayerda va qanday ishlatish kerak?

Redmon ketganidan keyin "YOLO" nomini boshqalar davom ettirdi:

Model Yil Muallif Nima qo'shgan
YOLOv4 2020 Alexey Bochkovskiy va boshq. Darknet da, o'sha davrdagi eng yaxshi usullar to'plami
YOLOv5 2020 Ultralytics (kompaniya) PyTorch da, maqolasiz; pip install va 3 qatorda o'qitish
YOLOX 2021 Megvii anchor siz bosh
YOLOv6 2022 Meituan sanoatda ishlatish uchun
YOLOv7 2022 Wang, Bochkovskiy, Liao YOLOv4 mualliflarining davomi
YOLOv8 2023 Ultralytics anchor siz, ajratilgan bosh, DFL; bitta kutubxonada detect/seg/pose
YOLOv9 2024 Wang, Yeh, Liao PGI (gradient ma'lumotini saqlash)
YOLOv10 2024 Tsinghua universiteti NMS siz o'qitish
YOLO11 2024 Ultralytics C3k2 va C2PSA bloklari, kamroq parametr
YOLO12 2025 Tian, Ye, Doermann attention ga asoslangan
YOLO26 2026 Ultralytics NMS siz, DFL siz, CPU uchun

Xulosa: YOLOv6 ni YOLOv5 ning "yangi versiyasi" deb o'ylash xato. Ular raqobatchi jamoalar.

Ultralytics davri: v8 → 11 → 26

Bugun eng ko'p ishlatiladigan YOLO lar bitta kompaniyadan — Ultralytics. Uchalasi ham bitta ultralytics kutubxonasida, kodi bir xil (YOLO("...pt")), faqat fayl nomi farq qiladi.

  • YOLOv8 (10-yanvar 2023). Anchor lardan voz kechdi: har katak box ni tayyor shakldan emas, to'g'ridan-to'g'ri o'zidan chegaragacha bo'lgan masofalar sifatida chiqaradi. Box va sinf uchun alohida "bosh" (split head). Box chegarasini DFL (Distribution Focal Loss) bilan taqsimot sifatida bashorat qiladi — 5–6-boblarda ochamiz.
  • YOLO11 (sentabr 2024). Ichki bloklar almashdi: v8 dagi C2f o'rniga C3k2, oxiriga C2PSA (attention bloki). Ultralytics ma'lumotiga ko'ra YOLO11m, YOLOv8m dan 22% kam parametr bilan aniqroq.
  • YOLO26 (yanvar 2026). Tanasi YOLO11 bilan bir xil bloklardan (C3k2, SPPF, C2PSA). O'zgarish boshda va o'qitishda: NMS kerak emas (bosh har obyektga bitta box chiqarishni o'rganadi), DFL olib tashlangan, yangi loss (ProgLoss, STAL) va optimizator (MuSGD). Ultralytics ning da'vosi: YOLO26n CPU da (ONNX) YOLO11n dan 43% gacha tez.

Da'volarni o'zimiz tekshiramiz.

O'zimiz o'lchaymiz: v8n, 11n, 26n

Uchala modelning eng kichik (nano) versiyasini yonma-yon qo'yamiz. Avval tuzilishi. Ultralytics ning .pt fayli ichida og'irliklardan tashqari metama'lumot ham saqlanadi: fayl qachon yaratilgan va qaysi litsenziya bilan:

kod/02_yolo_tarixi.pydavomi
python17 qator
import pandas as pd
from ultralytics.utils.torch_utils import get_flops, get_num_params

modellar = {n: YOLO(f"weights/{n}.pt") for n in ["yolov8n", "yolo11n", "yolo26n"]}
qatorlar = []
for n, m in modellar.items():
    bosh = m.model.model[-1]                              # oxirgi qatlam = Detect "boshi" (head)
    qatorlar.append({
        "model": n,
        "parametr, mln": get_num_params(m.model) / 1e6,
        "GFLOPs (640)": get_flops(m.model, imgsz=640),
        "reg_max (DFL)": bosh.reg_max,                    # 16 = DFL bor, 1 = DFL yo'q
        "NMS kerakmi": "yo'q" if getattr(bosh, "end2end", False) else "ha",
        "sana (.pt ichida)": m.ckpt["date"][:10],
        "litsenziya (.pt ichida)": m.ckpt["license"].split(" ")[0],
    })
show(pd.DataFrame(qatorlar))
modelparametr, mlnGFLOPs (640)reg_max (DFL)NMS kerakmisana (.pt ichida)litsenziya (.pt ichida)
yolov8n3.1578.85816ha2022-12-30AGPL-3.0
yolo11n2.6246.61416ha2024-09-25AGPL-3.0
yolo26n2.5726.1191yo'q2025-12-15AGPL-3.0

GFLOPs — bitta 640 × 640 rasm uchun necha milliard amal kerakligi. YOLO11n, YOLOv8n dan 17% kam parametr va 25% kam hisob bilan ishlaydi. YOLO26n o'lchami deyarli YOLO11n bilan bir xil, farq faqat boshda: reg_max 16 dan 1 ga tushgan (DFL yo'q) va NMS kerak emas. Fayl ichidagi sanalar ham qiziq: yolov8n.pt 2022-12-30 da saqlangan, model esa 2023-01-10 da e'lon qilingan.

Endi tarmoqning xom chiqishiga qaraymiz: 640 × 640 lik bo'sh rasm beramiz va nima qaytishini ko'ramiz:

kod/02_yolo_tarixi.pydavomi
python11 qator
import torch

for n, m in modellar.items():
    tarmoq = m.model.eval()                               # ultralytics o'ramining ichidagi PyTorch tarmoq
    with torch.no_grad():
        chiqish = tarmoq(torch.zeros(1, 3, 640, 640))     # (rasmlar soni, kanallar, balandlik, kenglik)
    y = chiqish[0] if isinstance(chiqish, (list, tuple)) else chiqish
    print(f"{n:8s} xom chiqish shakli: {tuple(y.shape)}")

kataklar = [(640 // qadam) ** 2 for qadam in (8, 16, 32)]
print("\n640 da uch masshtab kataklari:", " + ".join(map(str, kataklar)), "=", sum(kataklar))
Chiqish
yolov8n  xom chiqish shakli: (1, 84, 8400)
yolo11n  xom chiqish shakli: (1, 84, 8400)
yolo26n  xom chiqish shakli: (1, 300, 6)

640 da uch masshtab kataklari: 6400 + 1600 + 400 = 8400

Bu ikki xil shakl — YOLO evolyutsiyasining qisqa mazmuni:

  • v8n va 11n: (1, 84, 8400). 8 400 ta katakning har biri 84 ta raqam chiqaradi: 4 tasi box, 80 tasi har sinf ehtimoli. Bu hali tozalanmagan xom natija: bitta odam atrofidagi o'nlab katak uni birdaniga "topadi". NMS ular ichidan eng yaxshisini qoldirib, qolganini o'chiradi (5-bob).
  • 26n: (1, 300, 6). Tayyor ro'yxat: eng ko'pi bilan 300 ta obyekt, har biri 6 ta raqam (x1, y1, x2, y2, ishonch, sinf). NMS kerak emas.

YOLOv1 da 49 ta katak edi, bugun 8 400 ta: 80 × 80 (mayda obyektlar), 40 × 40 va 20 × 20 (katta obyektlar). Olomon muammosi shunday hal qilingan.

Detection natijalari bir xil rasmda:

kod/02_yolo_tarixi.pydavomi
python6 qator
qatorlar = []
for n, m in modellar.items():
    r = m.predict(ASSETS / "bus.jpg", verbose=False)[0]
    qatorlar.append({"model": n, "soni": len(r.boxes),
                     "topilganlar": ", ".join(f"{r.names[int(c)]} {p:.2f}" for c, p in zip(r.boxes.cls, r.boxes.conf))})
show(pd.DataFrame(qatorlar))
modelsonitopilganlar
yolov8n6bus 0.87, person 0.87, person 0.85, person 0.83, person 0.26, stop sign 0.26
yolo11n5bus 0.94, person 0.89, person 0.88, person 0.86, person 0.62
yolo26n5bus 0.92, person 0.91, person 0.91, person 0.87, person 0.53

YOLOv8n qo'shimcha "stop sign" topdi — bu 1-bobda ko'rgan "to'xtash taqiqlangan" belgisi, ya'ni yana xato sinf. Ishonchi 0.26, standart chegaradan (0.25) zo'rg'a o'tgan. Yangi ikki model bu rasmda odamlarga ko'proq ishonadi va ortiqcha box chizmaydi. Bitta rasm, albatta, xulosa uchun yetmaydi: haqiqiy taqqoslash pastda, 5 000 rasmda.

Tezlik

Bitta rasm, batch = 1, PyTorch. Har model avval 5 marta "qizdiriladi" (birinchi chaqiruvlar doim sekin: GPU xotira ajratadi, kodni tayyorlaydi). Keyin 3 aylana o'lchaymiz, har aylanada modellar navbatma-navbat 50 martadan ishlaydi. Navbatma-navbat — chunki kompyuterda boshqa dasturlar ham ishlaydi, va fon yuklamasi o'zgarsa, u bitta modelga emas, hammasiga teng tushsin:

kod/02_yolo_tarixi.pydavomi
python27 qator
import os
import time
import numpy as np

def tezlik(m, qurilma, n=50):
    """Bitta rasm, batch=1, n marta. Har bosqichning medianasi, ms."""
    sp = [m.predict(ASSETS / "bus.jpg", device=qurilma, verbose=False)[0].speed for _ in range(n)]
    return {k: float(np.median([s[k] for s in sp])) for k in ("preprocess", "inference", "postprocess")}

qatorlar = []
for qurilma in ["cuda:0", "cpu"]:
    nusxalar = {n: YOLO(f"weights/{n}.pt") for n in modellar}    # har qurilma uchun alohida nusxa
    for m in nusxalar.values():                                   # qizdirish
        for _ in range(5):
            m.predict(ASSETS / "bus.jpg", device=qurilma, verbose=False)
    olchov = {n: [] for n in nusxalar}
    for _ in range(3):                                            # 3 aylana, modellar navbatma-navbat
        for n, m in nusxalar.items():
            olchov[n].append(tezlik(m, qurilma))
    for n, ol in olchov.items():
        jami = [sum(t.values()) for t in ol]
        qatorlar.append({"qurilma": "GPU" if qurilma != "cpu" else "CPU", "model": n,
                         **{k: round(float(np.median([t[k] for t in ol])), 2) for k in ol[0]},
                         "jami, ms": round(float(np.median(jami)), 2),
                         "3 aylana: min–max": f"{min(jami):.1f}–{max(jami):.1f}"})
show(pd.DataFrame(qatorlar))
print("GPU:", torch.cuda.get_device_name(0), "| CPU iplari (threads):", os.cpu_count())
Chiqish
GPU: NVIDIA GeForce RTX 5070 Ti | CPU iplari (threads): 8
qurilmamodelpreprocessinferencepostprocessjami, ms3 aylana: min–max
GPUyolov8n0.873.440.694.985.0–5.3
GPUyolo11n0.914.710.746.366.2–6.6
GPUyolo26n0.925.680.266.876.8–6.9
CPUyolov8n0.8719.60.3920.8719.9–20.9
CPUyolo11n0.8820.30.421.621.0–21.6
CPUyolo26n0.8621.020.1222.0421.4–22.5

Jadvalni o'qish:

  • GPU da YOLO26n ning tarmoq qismi (inference) YOLO11n dan tez emas, lekin postprocess eng qisqa: NMS yo'qligi aynan shu ustunda ko'rinadi.
  • CPU da (PyTorch, 8 ip) YOLO26n ham tezroq emas. "43% gacha tez" da'vosi ONNX formatidagi model va boshqa protsessor uchun aytilgan. PyTorch da biz buni ko'rmadik. 8-bobda modellarni ONNX ga eksport qilib, da'voni o'sha sharoitda tekshiramiz.
  • Oxirgi ustun — uch aylananing eng kichik va eng katta natijasi. Bitta o'lchov ichida farq kichik bo'lishi mumkin, lekin kitobni har safar qayta yig'ganimizda CPU raqamlari bir necha ms ga o'zgarib turdi: bir safar YOLO26n 24.8 ms, YOLO11n 21.3 ms chiqdi, boshqa safar uchalasi ~20 ms da teng edi. Protsessorni kompyuterdagi boshqa dasturlar ham bo'lishadi. Shuning uchun CPU da 1–2 ms farqqa ishonmang va o'lchovni turli vaqtda takrorlang.
  • Oddiy CPU da ham bitta rasm ~20 ms atrofida, ya'ni bitta oqim uchun sekundiga ~50 kadr. Rasmni diskdan o'qish yoki kameradan dekodlash vaqti bu jadvalga kirmaydi — III qismda to'liq pipeline ni o'lchaymiz.

Aniqlik: COCO val2017 da

Ultralytics o'z saytida har model uchun COCO val2017 dagi aniqlikni (mAP50-95) e'lon qiladi. mAP ning formulasi 7-bobda. Hozircha bilish kerak bo'lgani: 0 dan 100 gacha, qancha katta bo'lsa shuncha yaxshi, va u 5 000 ta rasm ustida hisoblanadi. Biz uni o'zimiz o'lchaymiz.

Avval datasetni yuklab olamiz. Ultralytics ning tayyor coco.yaml fayli butun COCO ni (train bilan ~20 GB) yuklaydi. Bizga faqat val kerak, shuning uchun kerakli ikki qismni o'zimiz olamiz (bir marta ishga tushiriladi, ~830 MB):

kod/yuklab_olish.pyyangi fayl
python14 qator
# COCO val2017 (2-bob): 5 000 rasm (~780 MB) + YOLO formatdagi label lar
import zipfile
from pathlib import Path
from ultralytics.utils import ASSETS_URL
from ultralytics.utils.downloads import download

root = Path("datasets")
if not (root / "coco" / "images" / "val2017").exists():
    download(ASSETS_URL + "/coco2017labels.zip", dir=root, unzip=False)      # label lar arxivi (ichida train ham bor)
    with zipfile.ZipFile(root / "coco2017labels.zip") as z:                  # faqat val qismini ochamiz
        kerak = [n for n in z.namelist() if n.startswith(("coco/labels/val2017/", "coco/val2017.txt"))]
        z.extractall(root, kerak)
    (root / "coco2017labels.zip").unlink()
    download("http://images.cocodataset.org/zips/val2017.zip", dir=root / "coco" / "images", delete=True)

Endi dataset tavsifi (yaml) va uch modelni baholash:

kod/02_yolo_tarixi.pydavomi
python22 qator
import yaml
from pathlib import Path
from ultralytics.utils import LOGGER

LOGGER.setLevel("ERROR")    # ultralytics ning progress bar va log larini o'chiramiz: kitobda faqat jadval qolsin

# ultralytics "train" kalitini ham talab qiladi; biz o'qitmaymiz, shuning uchun unga ham val ro'yxatini beramiz
tavsif = {"path": "datasets/coco", "train": "val2017.txt", "val": "val2017.txt", "names": modellar["yolo11n"].names}
Path("datasets/coco_val.yaml").write_text(yaml.safe_dump(tavsif, allow_unicode=True))

rasmiy = {"yolov8n": 37.3, "yolo11n": 39.5, "yolo26n": 40.9}   # docs.ultralytics.com dagi jadvallardan
sinovlar = [("yolov8n", None), ("yolo11n", None), ("yolo26n", None), ("yolo26n", False)]  # end2end=False: NMS li bosh
qatorlar = []
for n, e2e in sinovlar:
    t0 = time.perf_counter()
    met = YOLO(f"weights/{n}.pt").val(data="datasets/coco_val.yaml", imgsz=640, batch=32, device=0, end2end=e2e,
                                      plots=False, save_json=False, project=Path("out/val").resolve(),
                                      name=f"{n}_{e2e}", exist_ok=True)   # nisbiy project runs/detect/ ichiga tushadi
    qatorlar.append({"model": n + (" (NMS bilan)" if e2e is False else ""), "mAP50-95 (biz)": round(met.box.map * 100, 1),
                     "mAP50-95 (Ultralytics)": rasmiy[n], "mAP50 (biz)": round(met.box.map50 * 100, 1),
                     "vaqt, s": round(time.perf_counter() - t0)})
show(pd.DataFrame(qatorlar))
modelmAP50-95 (biz)mAP50-95 (Ultralytics)mAP50 (biz)vaqt, s
yolov8n37.237.352.139
yolo11n39.339.554.939
yolo26n39.940.955.339
yolo26n (NMS bilan)40.740.956.538

Uch narsa ko'rinadi:

  1. v8n va 11n da o'lchovimiz rasmiy raqamdan atigi 0.1–0.2 past. Ultralytics COCO ning o'z baholash dasturini ishlatadi (buning uchun alohida instances_val2017.json fayli kerak), biz esa uni yuklamadik va ultralytics ning ichki hisobi ishladi. Kichik farq shundan bo'lishi mumkin. Asosiysi, raqamlar tasdiqlandi.
  2. YOLO26n standart rejimida (NMS siz) rasmiy raqamdan 1.0 past. Xuddi shu fayl end2end=False bilan, ya'ni NMS li rejimda, rasmiy raqamga ancha yaqin natija beradi. YOLO26 ichida aslida ikkita bosh bor: biri har obyektga bitta box chiqaradi (NMS kerak emas), ikkinchisi ko'p box chiqaradi va NMS talab qiladi. Bizning o'lchovda NMS dan qutulish 0.7–0.8 mAP turadi. 5-bobda ikkala boshni ochib ko'ramiz.
  3. E'lon qilingan raqamni doim o'zingiz tekshiring va u qaysi rejimda o'lchanganini so'rang. Bir xil model faylidan ikki xil natija chiqdi.

Litsenziya: YOLO bepulmi?

Yuqoridagi jadvalda ko'rdingiz: litsenziya .pt faylning o'zida yozilgan. Ultralytics ning uchala modeli ham AGPL-3.0. Bu nimani anglatadi:

  • O'rganish, tadqiqot, ochiq kodli loyiha — bepul, hech qanday shartsiz.
  • Dasturni boshqalarga tarqatsangiz yoki uni server orqali xizmat sifatida ishlatsangiz (masalan, mijozga dashboard berib, kamerani sizning serveringizda tahlil qilsangiz), butun loyihangiz kodini AGPL-3.0 bilan ochishingiz shart. Oddiy GPL dan farqi aynan shu tarmoq sharti.
  • Kodni yopiq saqlab sotmoqchi bo'lsangiz — Ultralytics dan pullik Enterprise litsenziya olinadi.

Boshqa YOLO lar va yaqin alternativlar (GitHub dagi litsenziya maydonidan, 2026-09-21 holatiga):

Loyiha Litsenziya Yopiq mahsulotda ishlatish
Darknet (YOLOv1–v4) public domain mumkin
Ultralytics (YOLOv5, v8, 11, 26) AGPL-3.0 kod ochiladi yoki Enterprise litsenziya
YOLOv10 (Tsinghua), YOLO12 AGPL-3.0 kod ochiladi
YOLOv6, YOLOv7, YOLOv9 GPL-3.0 tarqatsangiz kod ochiladi
YOLOX (Megvii) Apache-2.0 mumkin
RT-DETR (Baidu, asl repo) Apache-2.0 mumkin
MediaPipe (Google) Apache-2.0 mumkin

Model og'irliklari va o'qitilgan dataset ning o'z shartlari bo'lishi mumkin — bu jadval faqat kod litsenziyasi. Batafsil tahlil va "qanday qilib qonuniy sotish" IV qismda.

Bu kitobda nega YOLO11? O'rganish uchun eng qulayi: eng ko'p qo'llanma, eng ko'p tayyor loyiha, va uning ichida NMS hamda DFL bor — bu ikki g'oya deyarli hamma real tizimlarda uchraydi va ularni tushunmasdan YOLO26 da nima olib tashlanganini tushunib bo'lmaydi. YOLO26 ni 5-bobda (NMS siz bosh) va 8-bobda (CPU va ONNX tezligi) YOLO11 bilan yonma-yon qo'yamiz.

Asosiy fikr

  • R-CNN ikki bosqichda ishlardi (qayerda → nima), YOLO buni bitta regressiyaga aylantirdi: rasm to'rga bo'linadi, markaz tushgan katak obyekt uchun javobgar.
  • "YOLO" — brend, bitta model emas. v4, v5, v6, v7 ... turli jamoalar, turli litsenziyalar. Versiya raqami sifat kafolati emas.
  • Ultralytics modellari AGPL-3.0: o'rganish bepul, yopiq mahsulot sotish uchun esa litsenziya kerak. Litsenziya .pt faylning o'zida yozilgan.

Mashqlar

  1. weights/yolo11n.pt faylidagi boshqa metama'lumotlarni ko'ring: YOLO(...).ckpt.keys(). Qaysi dataset va qaysi o'qitish sozlamalari saqlangan?
  2. grid7.png dagi to'rni S = 13 bilan chizing. Qaysi odamlarning markazi bitta katakka tushib qoladi? YOLOv1 bunday holatda nima qilgan bo'lardi?
  3. Tezlik jadvalini batch = 8 bilan qayta o'lchang (bir xil rasmni 8 marta ro'yxat qilib bering). Bitta rasmga to'g'ri keladigan vaqt qanday o'zgardi va nega?

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar