YOLO Vision 2026:

شرح بنية YOLO: من YOLOv3 إلى YOLO26#

يُبنى كل نموذج Ultralytics YOLO من ثلاث مراحل: backbone يستخرج السمات، وneck يدمجها عبر المقاييس، وhead يتنبأ بالصناديق والفئات. يوثّق هذا الدليل الوحدات التي تكوّن كل مرحلة وكيف تغيّرت من YOLOv3 إلى YOLO26، مع تتبّع كل مكوّن إلى تعريفه في ملفات الإعداد ضمن ultralytics/cfg/models/ وإلى فئات الوحدات في ultralytics/nn/modules/.

يُعرَّف كل نموذج تعريفيًا في ملف YAML على شكل قائمة مرتبة من الطبقات، حيث تتبع كل طبقة تنسيق [from, repeats, module, args]: الطبقة أو الطبقات التي تغذيها، وعدد مرات تكرار الوحدة، وفئة الطبقة (Conv، C3k2، SPPF، Detect، …)، ووسائط المُنشئ الخاصة بها. يوثّق دليل إعداد YAML للنموذج هذا التنسيق — بما في ذلك كيفية توسّع repeats وargs وفق مضاعفي العمق والعرض للمتغير — إلى جانب نظام حلّ الوحدات بالكامل. يركّز هذا الدليل على الوحدات نفسها وكيف تغيّرت من إصدار إلى آخر.

المراحل الثلاث#

يمرّر كل نموذج Ultralytics YOLO الصورة عبر ثلاث مراحل متتابعة، لكل منها مهمة مميزة:

المرحلةالمهمةالمخرجات
Backboneاستخراج السمات من صورة الإدخال بدقات متعددةخرائط سمات بمعدلات أخذ عينات 8 و16 و32 ‏(P3 وP4 وP5)
Neckدمج السمات عبر المقاييس كي تحصل الكائنات الصغيرة والكبيرة على السياقخرائط سمات مدمجة متعددة المقاييس
Headالتنبؤ بالصناديق المحيطة ودرجات الفئات من السمات المدمجةالكشفات لكل نقطة ارتكاز

الوحدة الأساسية هي كتلة Conv (المعرّفة في conv.py): التفاف ثنائي الأبعاد، وتطبيع دفعي، وتنشيط SiLU، تُطبَّق بالتتابع. وتُبنى كل وحدة أكبر أدناه من خلال تركيب كتل Conv.

مخططات البنية#

تحافظ كل نسخة على الهيكل نفسه backbone → neck → head، وتغيّر مراحل محددة. تعرض علامات التبويب أدناه البنية الخاصة بكل إصدار: تتبع مراحل backbone وneck الإعدادات في ultralytics/cfg/models/، بينما تُرسم رأسا YOLOv3 وYOLOv5 بصيغتهما الأصلية المعتمدة على نقاط الارتكاز، بدلًا من رأس المتغير u الخالي من نقاط الارتكاز الذي تأتي به إعدادات حزميهما فعليًا. يوضح التنقل بين علامات التبويب ما أضافه كل جيل. باختصار، التسلسل هو: YOLOv3 كاشف معتمد على نقاط الارتكاز ويستخدم FPN فقط؛ يضيف YOLOv5 مسار PAN من الأسفل إلى الأعلى وSPPF؛ ينتقل YOLOv8 إلى كتلة C2f مع رأس خالٍ من نقاط الارتكاز وDFL؛ يُدرج YOLO11 انتباه C2PSA وكتلة C3k2؛ ويضيف YOLO26 وصلة متبقية SPPF ويجعل الرأس خاليًا من NMS وDFL. تتبع ألوان العقد اصطلاح مخطط التوثيق: أخضر للإدخال، وأزرق لـbackbone، وأردوازي للتجميع المكاني والانتباه، وبرتقالي لـneck، وأرجواني لـhead والإخراج.

flowchart TD
    IN[Input 640x640]:::start --> ST[Conv stem<br/>5x stride-2 down to P1-P5]:::proc
    ST --> BB[Darknet-53 backbone<br/>stacked Bottleneck]:::proc
    BB --> FPN[Neck FPN only<br/>top-down Upsample + Concat]:::decide
    FPN --> HD[Detect head<br/>3 scales, anchor-based]:::out
    HD --> O[Predictions + NMS]:::out
    classDef start fill:#4CAF50,color:#fff
    classDef proc fill:#2196F3,color:#fff
    classDef decide fill:#FF9800,color:#fff
    classDef out fill:#9C27B0,color:#fff

تعرض مخططات YOLOv3 وYOLOv5 الرأس الأصلي المعتمد على نقاط الارتكاز. توفّر حزمة ultralytics إعدادَي YOLOv3u وYOLOv5u الخاليين من نقاط الارتكاز — وهما backbone ‏Darknet-53 نفسه وC3 مع رأس Detect الخاص بـYOLOv8 — كما هو موضح ضمن رأس الكشف.

كتل Backbone: Bottleneck → C3 → C2f → C3k2#

يكدّس backbone كتلة CSP (التقسيم الجزئي عبر المراحل) متكررة بين طبقات خفض العينات Conv ذات الخطوة 2. وهذه الكتلة المتكررة هي أكثر ما تغيّر عبر الإصدارات. توجد جميع الكتل أدناه في block.py؛ ويمثل c1/c2 قنوات الإدخال/الإخراج، بينما يمثل c = 0.5 * c2 العرض الداخلي.

Bottleneck ‏(YOLOv3)#

الوحدة الأساسية هي Bottleneck: طبقتا Conv (نواتا افتراضيتان (3, 3)) مع إضافة متبقية اختيارية عندما shortcut=True وc1 == c2. يكدّس backbone Darknet-53 الخاص بـYOLOv3 هذه الوحدات مباشرةً، من دون تقسيم CSP، ويجري الكشف على ثلاثة مقاييس (خطوات 8 و16 و32).

C3 ‏(YOLOv5)#

يقسم C3 الخاص بـYOLOv5 الإدخال عبر التفافين 1x1: يغذي cv1 كتل Bottleneck المتتابعة داخل n (نواتا (1, 1) ثم (3, 3))، بينما يتجاوزها cv2. ثم يُدمج المساران ويُدمجان بواسطة 1x1 ثالث من نوع Conv:

def forward(self, x):
    # C3: bottleneck path m(cv1(x)) concatenated with bypass cv2(x), then fused by cv3
    return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

يصل خرج كتلة bottleneck النهائية فقط إلى التفاف الدمج، لذلك يرى cv3 خريطتي سمات.

C2f ‏(YOLOv8)#

يغيّر C2f الخاص بـYOLOv8 ("كتلة CSP Bottleneck ذات التفافين، أسرع") السمات التي تصل إلى التفاف الدمج:

  1. يقسم cv1 = Conv(c1, 2 * c, 1) ثم chunk(2) الخرج إلى موترين بعدد قنوات c.
  2. تعمل كتل n Bottleneck(c, c) (نواتا (3, 3) و(3, 3)) بالتتابع، بحيث تتلقى كل منها خرج الكتلة السابقة.
  3. تُدمج جميع الموترات الوسيطة n + 2 وتُدمج بواسطة cv2 = Conv((2 + n) * c, c2, 1).

بينما يمرّر C3 خريطتي سمات إلى التفاف الدمج، يمرّر C2f العدد n + 2 — إذ يُعاد استخدام كل خرج وسيط من bottleneck.

C3k2 ‏(YOLO11 وYOLO26)#

يستخدم YOLO11 وYOLO26 C3k2، وهي فئة فرعية من C2f تستبدل الوحدة المتكررة. وتصبح كل كتلة من كتل n، بحسب أعلام المُنشئ:

  • Bottleneck عادية (الافتراضي، c3k=False
  • كتلة C3k ‏(c3k=True) — وهي متغير C3 بحجم نواة قابل للضبط، أو
  • زوج Bottleneck + PSABlock ‏(attn=True).

تعيّن وسيطة YAML الثانية c3k ما لم يكن المقياس m أو l أو x، إذ تفرض هذه المقاييس القيمة True — وهكذا تخدم yolo11.yaml جميع المتغيرات الخمسة. لذلك تنشئ [-1, 2, C3k2, [512, False]] الوحدات الداخلية Bottleneck عند n وs، لكنها تنشئ الوحدات الداخلية C3k عند m وl وx؛ ويمثل العدد 512 عدد القنوات قبل التحجيم، الذي يحوّله مضاعف العرض للمتغير إلى 128 عند n وإلى 768 عند x. وبالنسبة إلى وحدات CSP، يتحول الحقل repeats — وقيمته هنا 2 قبل تحجيمه بمضاعف العمق للمتغير — إلى عدد التكرارات الداخلية للكتلة بدلًا من تكديس وحدات منفصلة.

التجميع المكاني: SPP → SPPF#

في نهاية backbone، توسّع كتلة تجميع الهرم المكاني مجال الاستقبال. استبدل YOLOv5 كتلة SPP الأصلية متعددة النوى بـ**SPPF** (التجميع الهرمي المكاني - سريع): ‏MaxPool2d(kernel_size=5, stride=1, padding=2) واحد يُطبَّق n = 3 مرات بالتتابع، مع دمج الإدخال وجميع المخارج الثلاثة المجمعة ودمجها بواسطة 1x1 من نوع Conv. وهذا مكافئ رياضيًا لـSPP(k=(5, 9, 13)) لكنه أقل تكلفة، لأن عمليات التجميع المتسلسلة 5x5 تغطي مجالات الاستقبال الخاصة بالنوى الأكبر.

يمرّر YOLO26 علامة اختصار (SPPF, [1024, 5, 3, True])؛ وبما أن c1 == c2 == 1024 موجود في أعمق طبقة، يضيف SPPF وصلة متبقية (return y + x).

الانتباه المكاني: C2PSA ‏(YOLO11+)#

أضاف YOLO11 C2PSA بعد SPPF. وهي كتلة CSP يكون فرعها النشط عبارة عن تكديس من وحدات PSABlock n (الانتباه الحساس للموضع): يقسم cv1 = Conv(c1, 2 * c, 1) السمات، ويمرر نصفها عبر تكديس PSABlock، ثم يدمج cv2 = Conv(2 * c, c1, 1) عملية الدمج. تطبّق كل وحدة PSABlock انتباهًا متعدد الرؤوس، يليهَتْ شبكة تغذية أمامية من طبقتين (Conv(c, 2 * c, 1)Conv(2 * c, c, 1))، ولكل منهما وصلة متبقية. ويحافظ YOLO26 على backbone نفسه المكوّن من C3k2 + C2PSA.

Neck: ‏FPN + PAN#

يدمج neck خرائط السمات P3/P4/P5 الخاصة بـbackbone باستخدام شبكة هرم السمات (FPN) من الأعلى إلى الأسفل، تليها شبكة تجميع المسارات (PAN) من الأسفل إلى الأعلى. وفي قسم head ضمن YAML، يتكون FPN من nn.Upsample + Concat (لنقل المعلومات الدلالية إلى الدقات الأعلى)، بينما يتكون PAN من Conv + Concat بخطوة 2 (لنقل معلومات تحديد الموضع إلى الأعلى):

# YOLO11 head (FPN top-down, then PAN bottom-up)
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 2, C3k2, [512, False]] # 13
# ... second upsample + concat to P3 ...
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 13], 1, Concat, [1]] # cat head P4 (PAN)
- [-1, 2, C3k2, [512, False]] # 19

يعيد neck استخدام كتلة backbone الخاصة بجيله — C3 في YOLOv5، وC2f في YOLOv8، وC3k2 في YOLO11 وYOLO26 — ولذلك تستخدم كل نقطة دمج الوحدة نفسها التي يستخدمها backbone. وتغذي المخارج الثلاثة المدمجة الرأس. ويمثل YOLOv3 الاستثناء: إذ يقتصر neck فيه على FPN من الأعلى إلى الأسفل (ولا يحتوي head في YAML الخاص به على خفض عينات بخطوة 2)، من دون مسار PAN الصاعد الذي قدمه YOLOv5.

رأس الكشف: من المعتمد على نقاط الارتكاز إلى الخالي منها إلى الخالي من NMS#

يحوّل الرأس خرائط السمات الثلاث المدمجة إلى تنبؤات لمهمة الكشف. وقد تغيّر تصميمه عبر الإصدارات من الاعتماد على نقاط الارتكاز إلى الاستغناء عنها ثم إلى الاستغناء عن NMS.

Detect خالٍ من نقاط الارتكاز ومفصول#

استخدم YOLOv3 وYOLOv5 الأصليان رأسًا معتمدًا على نقاط الارتكاز ومقترنًا: صناديق ارتكاز محددة مسبقًا وفرعًا مشتركًا لتنبؤات الصناديق والفئات. وتحافظ مستودعات ultralytics/yolov3 وultralytics/yolov5 المستقلة على هذا التصميم المعتمد على نقاط الارتكاز. أما حزمة ultralytics الرئيسية فتوفّر بدلًا من ذلك المتغيرين YOLOv3u وYOLOv5u الخاليين من نقاط الارتكاز — وهما backbone ‏Darknet-53 نفسه وC3 مع رأس Detect الخالي من نقاط الارتكاز الخاص بـYOLOv8 — كما أن إعدادَي yolov3.yaml وyolov5.yaml الموثقين هنا هما متغيرا u هذان، وليس التصميم التاريخي.

رأس Detect (head.py) خالٍ من نقاط الارتكاز ومفصول: يشغّل فرعين متوازيين لكل مستوى هرمي، ويتنبأ مباشرةً على نقاط الشبكة بدلًا من التنبؤ مقابل صناديق الارتكاز.

  • فرع الصندوق (cv2): Conv(x, c2, 3)Conv(c2, c2, 3)Conv2d(c2, 4 * reg_max, 1).
  • فرع الفئة (cv3): في YOLO11 وYOLO26، كتلتان قابلتان للفصل عمقيًا (DWConv + 1x1 Conv) → Conv2d(c3, nc, 1)؛ ويستخدم YOLOv8 المتغير القديم، أي طبقتي 3x3 ConvConv2d(c3, nc, 1).

لذلك تُصدر كل نقطة ارتكاز no = nc + 4 * reg_max مخرجات. ويؤدي حذف نقاط الارتكاز المحددة مسبقًا إلى إزالة أحجام صناديق الارتكاز ونسب أبعادها من المعلمات الفائقة التي يجب ضبطها.

خسارة البؤرة التوزيعية (DFL)#

يجري YOLOv8 وYOLO11 انحدار كل إحداثي من إحداثيات الصندوق الأربعة على شكل توزيع عبر reg_max = 16 حاويات بدلًا من قيمة عددية واحدة (الصيغة التكاملية من خسارة البؤرة المعممة). تعيد وحدة DFL تشكيل قنوات الصندوق 4 * reg_max إلى (4, reg_max)، وتطبّق softmax على حاويات reg_max، ثم تأخذ فهرس الحاوية المتوقع — أي ترجيح كل فهرس باحتمال softmax الخاص به ثم جمعها — بوصفه الإحداثي المتنبأ به. ويُنفّذ ذلك عبر التفاف 1x1 ثابت، أوزانه هي فهارس الحاويات arange(reg_max)، ولذلك يصبح المجموع الموزون حاصل ضرب نقطيًا واحدًا.

YOLO26: خالٍ من NMS وDFL#

يضبط YOLO26 معلمتَي YAML اللتين يقرأهما الرأس مباشرةً:

  • end2end: True — تنسخ Detect فروعها بعمق إلى رأس واحد لواحد (one2one_cv2/one2one_cv3) ينتج تنبؤًا واحدًا لكل كائن، فتزيل خطوة المعالجة اللاحقة كبت القيمة العظمى غير المحلية (NMS). راجع دليل الكشف الشامل من البداية إلى النهاية لمعرفة تفاصيل التصدير والترحيل.
  • reg_max: 1 — مع حاوية واحدة، يصبح self.dfl هو nn.Identity() وno = nc + 4؛ فيجري الرأس انحدار الإحداثيات مباشرةً، ولا تظهر أي عملية DFL في مخطط ONNX المُصدَّر.

عبر أحجام نماذجه الخمسة (n/s/m/l/x)، يحقق YOLO26 قيمة mAP تتراوح بين 40.9 و57.5 على COCO، بزمن استجابة TensorRT على T4 يتراوح بين 1.7 و11.8 ملي ثانية، وفقًا لما ورد في ورقة YOLO26.

ملخص إصدار بإصدار#

الإصداركتلة Backboneالتجميع المكانيالانتباهرأس الكشفDFL
YOLOv3Darknet-53 (Bottleneck)لا يوجد في الإعداد الأساسيلا يوجدالأصلي: معتمد على نقاط الارتكاز؛ متغير u: خالٍ من نقاط الارتكازلا / نعم (u)
YOLOv5C3 ‏(CSP)SPPFلا يوجدالأصلي: معتمد على نقاط الارتكاز؛ متغير u: خالٍ من نقاط الارتكازلا / نعم (u)
YOLOv8C2fSPPFلا يوجدخالٍ من نقاط الارتكاز، مفصولنعم (reg_max=16)
YOLO11C3k2SPPFC2PSAخالٍ من نقاط الارتكاز، مفصولنعم (reg_max=16)
YOLO26C3k2SPPF + اختصارC2PSAخالٍ من نقاط الارتكاز، خالٍ من NMS (end2end)محذوف (reg_max=1)

للاطلاع على تفاصيل كل نموذج، وجداول الأداء، وأمثلة الاستخدام، راجع الصفحات الفردية لكل من YOLOv3 وYOLOv5 وYOLOv8 وYOLO11 وYOLO26.

افحص البنية بنفسك#

تطبع طريقة model.info() ملخصًا للطبقات والمعلمات وFLOPs، وتتوفر قائمة الوحدات المحللة عبر model.model.model.

فحص بنية نموذج YOLO
from ultralytics import YOLO

# Load a pretrained model
model = YOLO("yolo11n.pt")

# Fuse Conv + BatchNorm layers so counts match the published specs
model.fuse()

# Print a summary: layers, parameters, gradients, GFLOPs
model.info()

# Inspect the detection head (the last module in the network)
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| end2end:", head.end2end)

يُظهر تشغيل المقتطف عبر ثلاثة أجيال التغيّرات رقميًا. وهذه مخرجات حقيقية لنماذج مدمجة من حزمة ultralytics، وتطابق أعداد المعلمات وFLOPs المنشورة في كل صفحة نموذج:

النموذجالطبقاتالمعلماتGFLOPsreg_maxend2endطبقة DFL
YOLOv8n723,151,9048.716FalseDFL
YOLO11n1002,616,2486.516FalseDFL
YOLO26n1222,408,9325.51TrueIdentity

يعرض YOLO26n القيم reg_max=1 وend2end=True وطبقة DFL باسم Identity — وهي السمة المعمارية لرأسه الخالي من NMS وDFL.

أعداد النماذج المدمجة وغير المدمجة

تُبلَّغ قيم المعلمات وFLOPs للنموذج المدمج (model.fuse())، الذي يدمج كل Conv وطبقة التطبيع الدفعي الخاصة به. ويتوافق ذلك مع المواصفات المنشورة؛ إذ يعرض checkpoint المحمَّل حديثًا أعدادًا أعلى قليلًا قبل الدمج.

الخلاصة#

تغيّرت بنية YOLO عبر الإصدارات مرحلةً واحدة في كل مرة: انتقل backbone من Darknet-53 إلى كتل C3 وC2f وC3k2 المعتمدة على CSP مع انتباه C2PSA؛ وحافظ neck على بنيته FPN + PAN، بينما أصبح SPP هو SPPF؛ وانتقل الرأس من الاعتماد على نقاط الارتكاز إلى الاستغناء عنها، ثم إلى تصميم YOLO26 الشامل من البداية إلى النهاية، الخالي من NMS وDFL.

لتعريف بنيات مخصصة، راجع دليل إعداد YAML للنموذج، أو قارن النماذج في صفحات النماذج. ولطرح الأسئلة، تواصل عبر GitHub أو Discord.

الأسئلة الشائعة#

  • يحتوي نموذج YOLO على backbone يستخرج السمات من الصورة عند خطوات 8 و16 و32، وneck يدمج هذه السمات عبر المقاييس باستخدام FPN وPAN، وhead يتنبأ بالصناديق المحيطة ودرجات الفئات. ويتبع كل نموذج Ultralytics YOLO من YOLOv3 إلى YOLO26 هذا التصميم ذي المراحل الثلاث.

  • C2f (YOLOv8) هي كتلة CSP تدمج مخرجات كل خرائط الميزات الداخلية Bottleneckn + 2 — قبل طبقة الالتفاف الخاصة بالدمج، بينما تمرر C3 الأقدم خريطتين فقط. أما C3k2 (YOLO11 وYOLO26) فهي فئة فرعية من C2f يمكنها استبدال كل Bottleneck بكتلة C3k (وهي أحد متغيرات C3 ذات حجم نواة قابل للتهيئة) عند ضبط علامة c3k. وتُعرَّف كلتاهما في block.py.

  • يُجري YOLO11 ثلاثة تغييرات بنيوية على YOLOv8: إذ يستبدل كتلة العمود الفقري والرقبة C2f بالكتلة C3k2، ويُدرج كتلة الانتباه الذاتي C2PSA بعد SPPF، وينقل فرع التصنيف في الرأس إلى طبقات التفاف أخف قابلة للفصل عمقيًا. ويحافظ كلاهما على رأس Detect نفسه، الخالي من المراسي والمفصول، مع انحدار DFL من خلال reg_max=16، ولذلك تقلل التغييرات عدد المعلمات وعمليات FLOPs مع رفع الدقة، بدلًا من إعادة تصميم واجهة الكشف.

  • نماذج Ultralytics YOLO الحديثة خالية من المراسي. يستخدم YOLOv8 وYOLO11 وYOLO26 رأس Detect خاليًا من المراسي ومفصولًا، مع فرعين منفصلين لانحدار الصناديق والتصنيف. كان YOLOv3 الأصلي وYOLOv5 يعتمدان على المراسي، لكن Ultralytics توفرهما في نسختَي YOLOv3u وYOLOv5u، وتستخدم إعداداتهما رأسًا خاليًا من المراسي مثل رأس YOLOv8.

  • نعم — يضبط YOLO26 القيمة end2end=True، ما يمنح Detect رأسًا واحدًا لواحد يُنتج تنبؤًا واحدًا لكل كائن ويزيل خطوة المعالجة اللاحقة لقمع القيم غير العظمى المطلوبة في النماذج السابقة. راجع دليل الكشف من طرف إلى طرف للاطلاع على التفاصيل.

  • يُجري DFL انحدار كل إحداثي من إحداثيات الصندوق بوصفه توزيعًا ناعمًا عبر reg_max فواصل (16 افتراضيًا في YOLOv8 وYOLO11)، ويأخذ القيمة المتوقعة بوصفها الإحداثي بدلًا من التنبؤ بقيمة عددية مفردة. يضبط YOLO26 القيمة reg_max=1، ولذلك تصبح طبقة DFL عملية هوية، ويُجري الرأس انحدار الإحداثيات مباشرةً، ولا تظهر أي عملية DFL في المخططات المُصدَّرة إلى ONNX أو TensorRT.

  • حمّل النموذج في Python واستدعِ model.info() للحصول على ملخص للطبقات والمعلمات وGFLOPs. توجد الطبقات التي جرى تحليلها في model.model.model — فعلى سبيل المثال، model.model.model[-1] هو رأس Detect، ويعرض سمات مثل reg_max وend2end. وتُعرَّف البنية الكاملة في ملف إعداد YAML للنموذج.

المساهمون

التعليقات