الرؤية الحاسوبية2018متوسط11 دقيقة قراءة

YOLOv3: تحسين تدريجي

YOLOv3: An Incremental Improvement

Redmon, J. · Farhadi, A. — arXiv

المشكلة

الكاشفات ثنائية المرحلة مثل Faster R-CNN تعمل بخطوتين: أولاً تقترح مناطق قد تحتوي أجساماً، ثم تصنّف كل منطقة على حدة. النتيجة دقيقة لكنها بطيئة جداً ولا تصلح للفيديو اللحظي. في المقابل، كان YOLOv2 سريعاً لكنه لم يكن يُجيد كشف الأجسام الصغيرة، ولم يكن قادراً على إعطاء الجسم الواحد أكثر من تسمية. الميدان كان بحاجة إلى كاشف أحادي المرحلة يجمع سرعة التطبيقات اللحظية مع دقة تشمل جميع أحجام الأجسام.

الإسهام

قدّم YOLOv3 ثلاث ترقيات محورية. الأولى: عمود فقري جديد هو -53، شبكة أعمق تستخدم اتصالات تخطّي وتحقّق دقة ResNet-152 نفسها لكن بضعف السرعة. الثانية: تنبؤ عبر ثلاثة أحجام لخرائط السمات (13×13 و26×26 و52×52) مستوحى من شبكة هرم السمات، وهذا حسّن كشف الأجسام الصغيرة تحسيناً كبيراً. الثالثة: مصنّفات لوجستية مستقلة بدلاً من softmax، مما أتاح متعدد التسميات للفئات المتداخلة. عند دقة 320×320 يعمل في 22 مللي ثانية بدقة 28.2 mAP، مساوياً لأداء SSD لكن أسرع ثلاث مرات.

الأثر

أصبح YOLOv3 الخيار الأول للتطبيقات اللحظية: القيادة الذاتية، والمراقبة، والروبوتات، والرؤية على الهواتف المحمولة. تصميمه متعدد المقاييس وشبكته الأساسية Darknet وضعا القالب الذي بنت عليه جميع الإصدارات اللاحقة: YOLOv4 وv5 وv7 وv8. أسلوب الورقة العفوي وصراحتها في عرض ما لم ينجح جعلاها من أكثر الأوراق استشهاداً ومحبّةً في مجال الرؤية الحاسوبية. كما أن قرار جوزيف ريدمون بإيقاف أبحاث YOLO لمخاوف أخلاقية فتح نقاشاً واسعاً حول المسؤولية في الذكاء الاصطناعي.

تخيّل أنك في مروحية تتفقّد مدينة من الأعلى. يشبه أن تتوقف فوق كل نقطة مثيرة للاهتمام وتُخرج المنظار وتتفحّصها بدقة — النتيجة موثوقة، لكن الأمر يستغرق وقتاً طويلاً لو أردت تغطية المدينة كلها.

YOLO هو الطيّار الذي يلتقط صورة واحدة للمدينة بأكملها ثم يقرأها فوراً ليحدّد كل سيارة ومبنى وشخص. ما يضيفه YOLOv3 هو ترقية الكاميرا بـثلاث عدسات: واسعة للمباني الكبيرة، ومتوسطة للسيارات، ومقرِّبة للمشاة — وبهذا لا يفلت شيء مهما صغر حجمه.

المشكلة: إما السرعة وإما الدقة، اختر واحدة

بحلول عام 2018، انقسم ميدان إلى مدرستين واضحتين:

  • الكاشفات ثنائية المرحلة (مثل Faster R-CNN وR-FCN): تعمل بخطوتين — أولاً تقترح مناطق مرشّحة قد تحتوي أجساماً، ثم تصنّف كل منطقة. دقتها عالية لكنها أبطأ من أن تواكب الفيديو اللحظي، إذ تحتاج مئات المللي ثوانٍ لكل إطار.

  • (مثل YOLOv2 وSSD): تعالج الصورة كاملةً دفعة واحدة وتتنبأ بـ مباشرةً. سريعة بما يكفي للفيديو، لكنها أضعف في التقاط الأجسام الصغيرة ولا تستطيع التعامل مع الفئات المتداخلة.

YOLOv2 تحديداً كان يعاني من ثلاث نقاط ضعف جوهرية: ضحل نسبياً، وكشف عند مقياس واحد فقط، واعتماد على دالة التي تُجبر كل جسم على الانتماء لفئة واحدة فقط. لو أن هناك «امرأة» ترتدي «فستاناً»، لم يكن بالإمكان تعيين التسميتين معاً — واحدة فقط تفوز.

افتح في المختبر
بدّل بين الكشف أحادي المقياس (YOLOv2) والكشف متعدد المقاييس (YOLOv3). لاحظ كيف تضيع الأجسام الصغيرة عندما نستخدم الشبكة الخشنة 13×13 فقط.
تستيقظ التجربة عند وصولك…

Darknet-53: عمود فقري أعمق وأسرع

الترقية الأولى تخصّ . في النسخة السابقة استخدم YOLOv2 شبكة Darknet-19 المكوّنة من 19 فقط. YOLOv3 يستبدلها بـDarknet-53: ثلاث وخمسون طبقة التفافية مرتّبة في ، مستعيرةً فكرة من ResNet.

كل كتلة متبقية تجمع بين لضغط القنوات وتقليل الحسابات، ثم التفاف 3×3 لاستخلاص السمات المكانية، وبعدها تُضاف المدخلات الأصلية إلى الناتج. هذا هو نمط «الطريق المختصر» نفسه من ResNet: تتدفق عبر مسار التخطّي دون أن تتلاشى، وهذا يسمح للشبكة أن تكون أعمق بكثير دون أن تقع في .

والنتيجة؟ يحقّق Darknet-53 نفس دقة التصنيف التي يحققها ResNet-152 على ، لكنه يعمل بسرعة تقارب الضعف. السبب أنه يستخدم بدلاً من لتقليل الأبعاد، وليس فيه أي — كل معاملاته مرشّحات التفافية.

افتح في المختبر
انقر على أي كتلة متبقية لترى بنيتها الداخلية. لاحظ كيف يضغط الالتفاف 1×1 القنوات أولاً، ثم يوسّعها الالتفاف 3×3.
تستيقظ التجربة عند وصولك…

التنبؤ بالصندوق المحيط: حين تلتقي المراسي بالسيجمويد

لا يبدأ YOLOv3 التنبؤ بإحداثيات الصندوق المحيط من الصفر، بل ينطلق من محسوبة مسبقاً. هذه الصناديق هي أشكال نموذجية تُستخرج بتشغيل خوارزمية على في بيانات . فكّر في المراسي كأنها «تخمينات أولية» لأشكال الأجسام الشائعة: طويلة ونحيلة كشخص واقف، عريضة وقصيرة كسيارة، أو مربّعة تقريباً كوجه.

بعد ذلك تتنبأ الشبكة بـإزاحات من هذه المراسي. لكل صندوق محيط تُخرج الشبكة أربعة أعداد — tx,ty,tw,tht_x, t_y, t_w, t_h — بالإضافة إلى tot_o.

bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=phethb_x = \sigma(t_x) + c_x \qquad b_y = \sigma(t_y) + c_y \qquad b_w = p_w e^{t_w} \qquad b_h = p_h e^{t_h}
التنبؤ بالصندوق المحيط من إزاحات المراسيσ(tₓ)، σ(tᵧ) = إزاحة المركز مضغوطة بالسيجمويد داخل خلية الشبكة · cₓ، cᵧ = الزاوية العلوية اليسرى للخلية · pʷ، pʰ = عرض وارتفاع المرساة · eᵗʷ، eᵗʰ = تحجيم أسّي لأبعاد المرساة

لماذا نستخدم دالة على إحداثيات المركز؟ السبب بسيط: بدونها قد يقع المركز المتوقَّع في أي مكان من الصورة، وهذا يجعل التدريب غير مستقر. السيجمويد تحصر المخرج بين 0 و1، فيبقى المركز داخل الخاصة به. الأمر أشبه بأن تقول للشبكة: «حرّكي مركز المرساة كما تشائين داخل هذه الخلية، لكن لا تنقليه إلى خلية أخرى.»

أما العرض والارتفاع فيعتمدان على تحجيم أسّي: الشبكة تتنبأ بمقدار التمديد أو التقليص المطلوب للمرساة. حين يكون tw=0t_w = 0 فالمعنى «أبقِ عرض المرساة كما هو»، وحين يكون tw=1t_w = 1 فالمعنى «اضربه في e2.7e \approx 2.7».

أما درجة وجود الجسم σ(to)\sigma(t_o) فوظيفتها الإجابة عن سؤال محدد: «هل يوجد فعلاً جسم في هذا المكان، أم أن الصندوق يحيط بخلفية فارغة؟» كل جسم حقيقي في البيانات يُسنَد إلى مرساة واحدة فقط — تلك التي تحقّق أعلى معه. وإذا تقاطعت مرساة أخرى مع الجسم بنسبة تتجاوز 0.5 لكنها ليست الأفضل تطابقاً، تُتجاهل ببساطة أثناء التدريب — لا تُعامَل كمثال إيجابي ولا كمثال سلبي.

افتح في المختبر
اسحب أشرطة التمرير لتغيير قيم tₓ وtᵧ وtᵤ وtₕ وراقب كيف يتغيّر الصندوق المتوقَّع (الأزرق) بالنسبة للمرساة (الخط المتقطع).
تستيقظ التجربة عند وصولك…

الكشف متعدد المقاييس: ثلاثة مستويات تكبير

القفزة الأكبر في YOLOv3 هي : التنبؤ بالأجسام عند ثلاثة مقاييس مختلفة، بإلهام من . لنبدأ بالفكرة الحدسية:

تخيّل أنك تنظر إلى صورة لمدينة. لتجد ناطحات السحاب تحتاج رؤية بانورامية — شبكة خشنة تغطّي كل خلية فيها مساحة واسعة من الصورة. أما لتجد لافتات الشوارع فتحتاج تكبيراً — شبكة دقيقة تغطّي كل خلية فيها رقعة صغيرة. YOLOv3 يستخدم المقياسين معاً، ويضيف مقياساً وسيطاً بينهما.

تُنتج الشبكة بثلاث دقّات مختلفة. لصورة مدخلة بحجم 416×416:

  • 13×13 ( 32): كل خلية ترى رقعة 32×32 بكسل من الصورة الأصلية. هنا تُكشف الأجسام الكبيرة باستخدام المراسي الثلاث الأكبر حجماً.

  • 26×26 (خطوة 16): كل خلية ترى رقعة 16×16. هنا تُكشف الأجسام المتوسطة بمراسٍ متوسطة.

  • 52×52 (خطوة 8): كل خلية ترى رقعة 8×8. هنا تُكشف الأجسام الصغيرة بالمراسي الثلاث الأصغر.

لبناء المقاييس الأدقّ، يأخذ YOLOv3 خريطة السمات العميقة (13×13) ويرفع دقّتها عبر ، ثم يضمّها مع خريطة السمات الأبكر (26×26) من العمود الفقري. هذه هي فكرة شبكة هرم السمات: الطبقات العميقة تحمل فهماً دلالياً غنياً — تعرف أن «هذا كلب» — بينما الطبقات السطحية تحتفظ بتفاصيل مكانية دقيقة — تعرف أن «حافة الجسم عند البكسل 47». حين ندمجهما نحصل على الاثنين معاً.

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

التصنيف متعدد التسميات: ما بعد softmax

في النسخة السابقة، استخدم YOLOv2 دالة softmax للتنبؤ بفئة الجسم. هذه الدالة تفرض أن يكون مجموع احتمالات جميع الفئات مساوياً للواحد، وبالتالي كل جسم يحصل على تسمية واحدة لا غير. المشكلة أن مجموعات البيانات الحقيقية كثيراً ما تحتوي فئات متداخلة: «امرأة» و«شخص» يصفان الجسم ذاته، و«سيارة» و«مركبة» كذلك.

يستبدل YOLOv3 الـsoftmax بـمصنّفات مستقلة — دالة سيجمويد واحدة لكل فئة. كل فئة تأخذ قراراً ثنائياً مستقلاً: نعم أو لا. هذا يعني أن الصندوق المحيط الواحد يمكنه الآن أن يكون «امرأة» باحتمال 0.95 و«شخص» باحتمال 0.98 في الوقت ذاته، لأن الدرجات لم تعد تتنافس فيما بينها.

دالة للتنبؤ بالفئة تتغيّر أيضاً: بدلاً من التي تفترض أن الفئات متنافية، نستخدم الآن — حدّ خسارة مستقل لكل فئة على حدة. هذا التغيير يبدو بسيطاً لكنه فتح أمام YOLO القدرة على العمل مع مجموعات بيانات ذات تسميات هرمية أو متداخلة.

تجميع المكوّنات معاً

بنية YOLOv3 الكاملة تعمل كخط أنابيب يمرّ عبر ثلاث مراحل متتابعة:

المرحلة الأولى — استخلاص السمات (Darknet-53): الصورة المدخلة تمرّ عبر 53 طبقة التفافية مع كتل متبقية. كل كتلة تستخدم مع دالة تنشيط . بدلاً من التجميع الأقصى لتصغير الأبعاد، تُستخدم التفافات بخطوة (stride=2) مما يقلّل ضياع المعلومات.

المرحلة الثانية — ( متعدد المقاييس): تُسحب خرائط سمات من ثلاثة أعماق مختلفة في العمود الفقري. خريطة السمات الأعمق تُرفع دقّتها ثم تُضمّ إلى الخريطة الأبكر، مكوِّنةً هرماً يجمع كل مستوى فيه بين الفهم الدلالي والدقة المكانية.

المرحلة الثالثة — رؤوس الكشف: عند كل مقياس من الثلاثة، تتنبأ شبكة التفافية فرعية صغيرة بمصفوفة ثلاثية الأبعاد بحجم S×S×[3×(4+1+C)]S \times S \times [3 \times (4 + 1 + C)] — ثلاث مراسٍ لكل خلية، كل مرساة تحمل 4 إحداثيات للصندوق ودرجة وجود واحدة وC درجة فئة. في مجموعة COCO التي تحتوي 80 فئة يصبح الحجم S×S×255S \times S \times 255.

المحصّلة: لصورة مدخلة بحجم 416×416، يولّد YOLOv3 عدد (132+262+522)×3=10,647(13^2 + 26^2 + 52^2) \times 3 = 10{,}647 صندوق محيط. معظم هذه الصناديق يُستبعد بسبب انخفاض درجة الوجود، ثم تُنظَّف البقية عبر .

افتح في المختبر
انقر على أي مرحلة لتوسيع بنيتها الداخلية وعرض تدفق البيانات خلالها.
تستيقظ التجربة عند وصولك…

الفكرة الجوهرية في شيفرة برمجية

فك ترميز الصناديق المحيطة في YOLOv3 — من مخرجات الشبكة إلى إحداثيات البكسلpython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def decode_yolo_boxes(raw_output, anchors, grid_size, img_size=416):
    """فك ترميز مخرجات YOLO الخام إلى (x, y, w, h) بإحداثيات البكسل.

    raw_output: (S, S, 3, 5+C) — 3 مراسٍ، 4 إحداثيات + 1 وجود + C فئة
    anchors:    (3, 2) — عرض وارتفاع كل مرساة بالبكسل
    grid_size:  S — مثلاً 13 أو 26 أو 52
    """
    S = grid_size
    stride = img_size / S

    # بناء شبكة إزاحات الخلايا: cx, cy لكل خلية
    cx = np.arange(S).reshape(1, S, 1)   # (1, S, 1)
    cy = np.arange(S).reshape(S, 1, 1)   # (S, 1, 1)

    # استخراج التنبؤات الخام
    tx = raw_output[..., 0]   # إزاحة مركز x
    ty = raw_output[..., 1]   # إزاحة مركز y
    tw = raw_output[..., 2]   # مُعامل تحجيم العرض
    th = raw_output[..., 3]   # مُعامل تحجيم الارتفاع
    to = raw_output[..., 4]   # درجة الوجود

    # فك الترميز — هذه هي معادلة الصندوق المحيط كاملةً
    bx = (sigmoid(tx) + cx) * stride        # إحداثي x للمركز بالبكسل
    by = (sigmoid(ty) + cy) * stride        # إحداثي y للمركز بالبكسل
    bw = anchors[:, 0] * np.exp(tw)         # العرض بالبكسل
    bh = anchors[:, 1] * np.exp(th)         # الارتفاع بالبكسل
    obj = sigmoid(to)                        # احتمال وجود الجسم

    return np.stack([bx, by, bw, bh, obj], axis=-1)

# مثال: فك ترميز المقياس 13×13 مع المراسي الثلاث الأكبر
# anchors_large = np.array([[116,90], [156,198], [373,326]])
# boxes = decode_yolo_boxes(raw_13x13, anchors_large, 13)

الأداء: السرعة مقابل الدقة

يحقّق YOLOv3 توازناً مميّزاً على منحنى السرعة مقابل الدقة:

  • عند دقة 320×320: يعمل في 22 مللي ثانية (45 إطاراً في الثانية) بدقة 28.2 ، وهو أداء يكافئ SSD لكن بسرعة أعلى ثلاث مرات.

  • عند 416×416: يصل إلى 31.0 mAP في 29 مللي ثانية.

  • عند 608×608: يحقّق 33.0 mAP في 51 مللي ثانية — وهو أداء قريب من RetinaNet لكن أسرع منه 3.8 مرات.

على معيار mAP@50 الأقدم — وهو المعيار الذي يتألق فيه YOLOv3 — يسجّل 57.9 mAP@50 عند دقة 608×608، مقارباً لمستوى RetinaNet. لكن حين ننتقل إلى المعيار الأكثر صرامة mAP@[.5:.95]، يتراجع أداء YOLOv3 بوضوح. الورقة تعترف بصراحة أن النموذج يعاني مع دقة تحديد موضع الصندوق المحيط عند عتبات تقاطع على اتحاد مرتفعة.

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

افتح في المختبر
مرّر المؤشر فوق كل كاشف لمقارنة زمن الاستدلال مع الدقة. YOLOv3 يهيمن على المنطقة العلوية اليسرى (سريع ودقيق معاً).
تستيقظ التجربة عند وصولك…

أشياء جرّبناها ولم تنجح

لماذا يُعدّ YOLOv3 مهمّاً

YOLOv3 لم يكن لحظة اختراق مفاجئة — بل كان درساً عملياً متقناً في الهندسة التدريجية. ريدمون أخذ ثلاث أفكار أثبتت نجاحها كلٌّ على حدة: أعمدة فقرية أعمق مع ، وأهرامات سمات، ومصنّفات مستقلة — ثم صهرها في منظومة واحدة متماسكة. النتيجة أثبتت أن التحسينات الصغيرة، حين تُنفَّذ بإتقان، يمكن أن تُحدث فرقاً جوهرياً في قدرات الكاشف.

والأهم من ذلك أن YOLOv3 أرسى القالب المعماري الذي تسير عليه عائلة YOLO بأكملها حتى اليوم: عمود فقري التفافي عميق ← دمج سمات متعدد المقاييس ← رؤوس كشف عند كل مقياس. جميع الإصدارات التالية — YOLOv4 وv5 وv7 وv8 وv11 — تبني على هذا الهيكل نفسه وتطوّره.

  1. 2016

    YOLOv1

    النسخة الأصلية «تنظر مرة واحدة فقط». صاغت كشف الأجسام كمسألة انحدار واحدة. سرعتها كانت ثورية لكنها عانت من تحديد مواقع خشن وأداء ضعيف مع الأجسام الصغيرة.

  2. 2017

    YOLOv2 / YOLO9000

    أضاف صناديق المراسي وتسوية الدُّفعات والتدريب بدقّات متعددة. نسخة YOLO9000 استطاعت كشف أكثر من 9000 فئة عبر التدريب المشترك على بيانات الكشف والتصنيف.

  3. 2018

    YOLOv3

    عمود فقري Darknet-53، وكشف متعدد المقاييس بأسلوب هرم السمات، ومصنّفات لوجستية مستقلة. أصبح القالب المعماري الذي بُنيت عليه جميع إصدارات YOLO اللاحقة.

  4. 2020

    YOLOv4

    أضاف بوتشكوفسكي وفريقه عمود CSPDarknet الفقري وعنق PANet ومجموعة حيل تدريبية مثل تعزيز الفسيفساء وخسارة CIoU. رفعوا الدقة دون التضحية بالسرعة.

  5. 2020

    DETR

    محوِّل الكشف DETR من فيسبوك تخلّى عن المراسي والكبت غير الأقصى تماماً، واستبدلهما بمحوِّل مرمِّز-فاك ترميز ومطابقة ثنائية الأطراف — نموذج مختلف كلياً.

  6. 2023

    YOLOv8

    وحّد إطار Ultralytics الكشف والتقطيع وتقدير الوضعية في منظومة واحدة. رأس كشف بلا مراسٍ ووحدات C2f وفصل بين فرعَي التصنيف وتحديد الموقع.

المرجعRedmon, Farhadi. YOLOv3: An Incremental Improvement. arXiv, 2018.

مصطلحات هذه الورقة