شرح بنية 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 ذات التفافين، أسرع") السمات التي تصل إلى التفاف الدمج:
- يقسم
cv1 = Conv(c1, 2 * c, 1)ثمchunk(2)الخرج إلى موترين بعدد قنواتc. - تعمل كتل
nBottleneck(c, c)(نواتا(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 Conv→Conv2d(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 |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53 (Bottleneck) | لا يوجد في الإعداد الأساسي | لا يوجد | الأصلي: معتمد على نقاط الارتكاز؛ متغير u: خالٍ من نقاط الارتكاز | لا / نعم (u) |
| YOLOv5 | C3 (CSP) | SPPF | لا يوجد | الأصلي: معتمد على نقاط الارتكاز؛ متغير u: خالٍ من نقاط الارتكاز | لا / نعم (u) |
| YOLOv8 | C2f | SPPF | لا يوجد | خالٍ من نقاط الارتكاز، مفصول | نعم (reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | خالٍ من نقاط الارتكاز، مفصول | نعم (reg_max=16) |
| YOLO26 | C3k2 | SPPF + اختصار | C2PSA | خالٍ من نقاط الارتكاز، خالٍ من NMS (end2end) | محذوف (reg_max=1) |
للاطلاع على تفاصيل كل نموذج، وجداول الأداء، وأمثلة الاستخدام، راجع الصفحات الفردية لكل من YOLOv3 وYOLOv5 وYOLOv8 وYOLO11 وYOLO26.
افحص البنية بنفسك#
تطبع طريقة model.info() ملخصًا للطبقات والمعلمات وFLOPs، وتتوفر قائمة الوحدات المحللة عبر model.model.model.
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 المنشورة في كل صفحة نموذج:
| النموذج | الطبقات | المعلمات | GFLOPs | reg_max | end2end | طبقة DFL |
|---|---|---|---|---|---|---|
| YOLOv8n | 72 | 3,151,904 | 8.7 | 16 | False | DFL |
| YOLO11n | 100 | 2,616,248 | 6.5 | 16 | False | DFL |
| YOLO26n | 122 | 2,408,932 | 5.5 | 1 | True | Identity |
يعرض 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 تدمج مخرجات كل خرائط الميزات الداخليةBottleneck—n + 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 للنموذج.