ML Learning Hub
رؤية الحاسوبمتوسط

اكتشاف الأجسام: YOLO وFaster-RCNN

من تصنيف الصور إلى تحديد وتسمية كل كائن في المشهد

من النوافذ المتحركة إلى YOLO — IoU وصناديق الإرساء وNMS وmAP. كيف يكتشف YOLO 80 فئة جسم في الوقت الفعلي بـ30 إطار في الثانية.

45 min
11 مخططات
8 المفاهيم المغطاة

المتطلبات الأساسية

CNN Architectures

المفاهيم المغطاة

IoUAnchor BoxesNMSmAPYOLOFaster-RCNNFPNTwo-Stage vs One-Stage

الصيغ الرئيسية

IoU

التقاطع على الاتحاد — مقياس جودة الصندوق الحدودي؛ IoU > 0.5 هو كشف صحيح اصطلاحاً

mAP

متوسط متوسط الدقة — المساحة تحت منحنى الدقة-الاستدعاء، متوسطة عبر جميع الفئات

خسارة YOLO

مجموع موزون: انحدار الصندوق + ثقة الموضوعية + احتمالات الفئة

NMS

الاحتفاظ فقط بالصندوق الأعلى ثقةً عندما تتداخل عدة صناديق بشكل كبير على نفس الجسم

محاكاة تفاعلية

Loading visualization…
🎯

ما وراء التصنيف: أين وماذا؟

motivation

تُجيب تصنيف الصور على «هل يوجد قط؟». الكشف يُجيب على «أين القطط، وهل يوجد أيضاً كلاب؟». هذا التحول من علامة واحدة إلى عدد متغير من المخرجات (فئة، صندوق حدود) هو ما يجعل الكشف عن الأجسام المهمة المحورية في القيادة الذاتية والتصوير الطبي وتسجيل التجزئة والمراقبة. كل سيارة ذاتية القيادة تشغّل كاشفاً في الوقت الفعلي يعالج أكثر من 30 إطاراً في الثانية. التطور من مصنّفات النافذة المنزلقة (DPM, 2010) → كاشفات مرحلتين (RCNN, 2014؛ Faster-RCNN, 2015) → كاشفات مرحلة واحدة (YOLO v1, 2016 → v8, 2023) هو أحد أسرع المجالات تطوراً في رؤية الحاسوب.

يمرر Tesla Autopilot 8 كاميرات عبر شبكة كشف مخصصة بـ36 إطاراً/ثانية على شريحة 72 TOPS. يجب أن يتناسب النموذج بأكمله في ميزانية زمن استجابة ضيقة مع الكشف عن أجسام على بعد 200 متر.

💡

مرحلتان مقابل مرحلة واحدة: المقايضة الأساسية

intuition

**كاشفات مرحلتين (Faster-RCNN):** المرحلة 1 — شبكة اقتراح المناطق (RPN) تقترح ~300 منطقة مرشحة. المرحلة 2 — رأس تصنيف + انحدار يُحسّن كل اقتراح. الميزة: دقة عالية. العيب: بطيء. **كاشفات مرحلة واحدة (YOLO، SSD):** قسّم الصورة إلى شبكة. كل خلية تتنبأ مباشرةً بإزاحات الصندوق ودرجة الموضوعية واحتمالات الفئة في مرور أمامي واحد. الميزة: سريع. العيب: أصعب في التدريب ويفوّت الأجسام الصغيرة المتداخلة. **مبني على المراسي مقابل بدون مراسي:** YOLO v1-v3 استخدم صناديق مراسي. YOLO v8 / FCOS / CenterNet بدون مراسي — يتنبأ مباشرةً بمركز + عرض/ارتفاع الصندوق، أبسط وغالباً أفضل.

YOLO = 'You Only Look Once.' الفكرة: بدلاً من تشغيل مصنّف في آلاف مواضع النافذة المنزلقة، التنبؤ بجميع الصناديق في وقت واحد في مرور واحد للشبكة.

⚙️

خط أنابيب استدلال YOLO

algorithm
1

قسّم صورة الإدخال إلى شبكة S×S (مثل 13×13 لإدخال 416 بكسل في YOLO v2).

2

لكل خلية: تنبّأ بـ B صندوقاً حدودياً (كل منها: x, y, w, h نسبة إلى الخلية + درجة موضوعية) وC احتمالاً للفئة.

3

إحداثيات الصندوق: x, y هي إزاحات من مركز الخلية (0-1)، w/h هي إزاحات مقياس لوغاريتمي من أحجام المراسي.

4

الموضوعية × احتمال الفئة = درجة ثقة خاصة بالفئة لكل صندوق.

5

طبّق الإخماد غير الأقصى (NMS): لكل فئة رتّب الصناديق حسب الثقة، احتفظ بالأعلى ثقةً، اخمد الصناديق بـIoU > 0.5 مع الصندوق المحتفظ به، كرر.

6

المخرج النهائي: قائمة بطول متغير من الصفوف (فئة، ثقة، x1, y1, x2, y2).

</>

اكتشاف الأجسام مع YOLOv8

code
python72 lines
class="tok-comment"># pip install ultralytics
from ultralytics import YOLO
import numpy as np
import cv2

class="tok-comment"># ── class="tok-num">1. Load pretrained YOLO v8 ────────────────────────────────────────────────
model = YOLO(class="tok-str">"yolov8n.pt")   class="tok-comment"># nano model (class="tok-num">3.2M params, fastest)
class="tok-comment"># Other sizes: yolov8s.pt, yolov8m.pt, yolov8l.pt, yolov8x.pt

class="tok-comment"># ── class="tok-num">2. Inference on a single image ────────────────────────────────────────────
results = model(class="tok-str">"path/to/image.jpg", conf=class="tok-num">0.25, iou=class="tok-num">0.5)

for r in results:
    boxes = r.boxes                  class="tok-comment"># Boxes object
    for box in boxes:
        x1, y1, x2, y2 = box.xyxy[class="tok-num">0].tolist()  class="tok-comment"># absolute pixel coords
        conf  = box.conf[class="tok-num">0].item()              class="tok-comment"># confidence score
        cls   = int(box.cls[class="tok-num">0].item())          class="tok-comment"># class index
        label = model.names[cls]
        print(fclass="tok-str">"{label}: {conf:.2f} at ({x1:.0f},{y1:.0f},{x2:.0f},{y2:.0f})")

class="tok-comment"># ── class="tok-num">3. Fine-tuning on custom dataset ─────────────────────────────────────────
class="tok-comment"># Dataset format: YOLO txt format
class="tok-comment"># data.yaml:
class="tok-comment">#   train: /path/to/train/images
class="tok-comment">#   val:   /path/to/val/images
class="tok-comment">#   nc: class="tok-num">3                       # number of classes
class="tok-comment">#   names: [class="tok-str">'cat', class="tok-str">'dog', class="tok-str">'car']

model = YOLO(class="tok-str">"yolov8s.pt")     class="tok-comment"># start from ImageNet pretrained
results = model.train(
    data=class="tok-str">"data.yaml",
    epochs=class="tok-num">50,
    imgsz=class="tok-num">640,
    batch=class="tok-num">16,
    lr0=class="tok-num">0.01,                   class="tok-comment"># initial learning rate
    lrf=class="tok-num">0.01,                   class="tok-comment"># final lr fraction
    augment=True,               class="tok-comment"># mosaic, flip, scale augmentation
    device=class="tok-num">0,                   class="tok-comment"># GPU class="tok-num">0
)
print(fclass="tok-str">"mAP50: {results.metrics.mAP50:.4f}")

class="tok-comment"># ── class="tok-num">4. IoU calculation from scratch ──────────────────────────────────────────
def iou(box1, box2):
    class="tok-str">"""box = [x1, y1, x2, y2]"""
    x1 = max(box1[class="tok-num">0], box2[class="tok-num">0]); y1 = max(box1[class="tok-num">1], box2[class="tok-num">1])
    x2 = min(box1[class="tok-num">2], box2[class="tok-num">2]); y2 = min(box1[class="tok-num">3], box2[class="tok-num">3])
    inter = max(class="tok-num">0, x2-x1) * max(class="tok-num">0, y2-y1)
    area1 = (box1[class="tok-num">2]-box1[class="tok-num">0]) * (box1[class="tok-num">3]-box1[class="tok-num">1])
    area2 = (box2[class="tok-num">2]-box2[class="tok-num">0]) * (box2[class="tok-num">3]-box2[class="tok-num">1])
    return inter / (area1 + area2 - inter + class="tok-num">1e-6)

gt   = [class="tok-num">100, class="tok-num">50, class="tok-num">250, class="tok-num">200]
pred = [class="tok-num">110, class="tok-num">60, class="tok-num">260, class="tok-num">210]
print(fclass="tok-str">"\nIoU = {iou(gt, pred):.4f}")

class="tok-comment"># ── class="tok-num">5. Manual NMS ─────────────────────────────────────────────────────────────
def nms(boxes, scores, iou_threshold=class="tok-num">0.5):
    class="tok-str">"""Boxes: (N,class="tok-num">4) xyxy, Scores: (N,)"""
    order = np.argsort(scores)[::-class="tok-num">1]
    keep  = []
    while len(order) > class="tok-num">0:
        i = order[class="tok-num">0]
        keep.append(i)
        ious = np.array([iou(boxes[i], boxes[j]) for j in order[class="tok-num">1:]])
        order = order[class="tok-num">1:][ious < iou_threshold]
    return keep

boxes  = np.array([[class="tok-num">100,class="tok-num">50,class="tok-num">250,class="tok-num">200],[class="tok-num">105,class="tok-num">55,class="tok-num">255,class="tok-num">205],[class="tok-num">200,class="tok-num">100,class="tok-num">350,class="tok-num">250]])
scores = np.array([class="tok-num">0.95, class="tok-num">0.87, class="tok-num">0.72])
kept   = nms(boxes, scores)
print(fclass="tok-str">"Kept boxes: {kept}")  class="tok-comment"># [class="tok-num">0, class="tok-num">2] — box class="tok-num">1 suppressed (overlaps with class="tok-num">0)
⚠️

mAP وفخ عتبة IoU

pitfall

mAP@0.5 وmAP@0.5:0.95 تحكيان قصصاً مختلفة جداً. نموذج بـmAP@0.5 ممتاز لكن mAP@0.5:0.95 ضعيف يُحدّد مواقع الأجسام بشكل فضفاض — مقبول للمهام الخشنة، سيئ للإمساك الروبوتي. أيضاً تعامل mAP جميع الفئات بالتساوي مما يُخفي الأداء السيئ على الفئات النادرة. للمجموعات غير المتوازنة أبلغ عن AP لكل فئة منفصلاً. مخاطر شائعة: (1) نسيان تطبيع إحداثيات الصندوق بحجم الصورة. (2) استخدام عتبة ثقة منخفضة جداً أثناء NMS — احتفظ بـconf_threshold ≈ 0.25 أثناء الاستدلال. (3) الإفراط في التخصيص على المجموعات الصغيرة — استخدم دائماً تعزيزاً قوياً.

تحسين بنسبة 1% في mAP على معيار COCO (80 فئة، 330 ألف صورة) يمثل أشهراً من البحث — السياق مهم عند مقارنة النماذج في مجالك.

?اختبار المعرفة

يتم حفظ التقدم في متصفحك — لا حاجة لحساب.

تحتاج مهندس ذكاء اصطناعي أو عالم بيانات؟

أبني نماذج تعلم آلي مخصصة، ووكلاء ذكاء اصطناعي، ورؤية حاسوب، وأتمتة — من الفكرة إلى الإنتاج.