Ultralytics YOLO27: انضم إلى قائمة الانتظار.
الدرسمتوسط

وضع التسميات والتدريب على تجزئة الكائنات

اكتب تسميات المضلعات، وتحقق منها برمجيًا، ودرّب yolo26n-seg.pt على COCO8-seg، وشخّص نموذجًا من خلال الفجوة بين مقاييس الصناديق والأقنعة.

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

النتيجة

تحقق من مجموعة تسميات المضلعات بحثًا عن الصفوف ذات التنسيق غير الصحيح، ودرّب yolo26n-seg.pt على coco8-seg.yaml، وحدد ما ينبغي إصلاحه استنادًا إلى الفجوة بين mAP50-95 للصناديق والأقنعة.

المسار السريع
إذا كنت تعرف الأساسيات بالفعل، فإليك النسخة المختصرة.
  1. اكتب صفًا واحدًا لكل كائن: فهرس الفئة، ثم أزواج رؤوس x y المطبّعة، على ألا يقل عدد الرؤوس عن ثلاثة.

  2. شغّل أداة للتحقق من التسميات بحثًا عن أعداد فردية من القيم، وإحداثيات خارج النطاق، ومساحات مضلعات منخفضة بشكل مريب.

  3. yolo segment train data=coco8-seg.yaml model=yolo26n-seg.pt epochs=1 imgsz=320.

  4. اعتمد mAP50-95 للأقنعة (metrics.seg.map) بوصفه معيار القبول، واستخدم الفجوة بينه وبين mAP50-95 للصناديق (metrics.box.map) للتشخيص.

عملي

صف تسمية المضلع#

تجزئة الكائنات باستخدام Ultralytics YOLO عند ممر مشاة في مدينة، مع قناع منفصل لكل سيارة والحافلة وكل شخص

يحتوي ملف تسميات التجزئة على صف واحد لكل كائن، مثل تسمية الكشف، لكنه يسرد مخطط الكائن على هيئة أزواج رؤوس مطبّعة بدلًا من صندوق. فيما يلي صف فعلي من COCO8-seg بعد اختصاره:

45 0.782016 0.986521 0.937078 0.874167 0.957297 0.782021 0.950562 0.739333 0.825844 0.561792 ...
الموضعصف الكشفصف التجزئة
1فهرس الفئة (45 هو bowl)فهرس الفئة
2–5x_center y_center width heightأول رأسيْن، x1 y1 x2 y2
6+—رؤوس إضافية، بعدد يتناسب مع ما يحتاج إليه المخطط
الوحداتمطبّعة إلى 0–1مطبّعة إلى 0–1 (إحداثي x بالبكسل ÷ عرض الصورة، وإحداثي y بالبكسل ÷ ارتفاع الصورة)

ثلاث قواعد أساسية تحمل معظم العبء: ثلاثة رؤوس على الأقل لكل كائن، وقسمة الإحداثيات على أبعاد الصورة، وصف واحد لكل مثيل حتى عندما يتلامس كائنان من الفئة نفسها. يتضمن دليل مجموعة بيانات التجزئة المواصفات الكاملة.

تدرّب تسميات المضلعات أيضًا الصناديق وخرائط الفئات

المضلعات مجموعة شاملة من تسميات الصناديق. يدرّب مجلد التسميات نفسه yolo26n.pt (إذ يستنتج Ultralytics كل صندوق من مضلعه) وyolo26n-sem.pt (إذ يحوّل المضلعات إلى خرائط فئات نقطية) — وقد درّبنا كليهما على coco8-seg.yaml. إذا تغيرت الخطة بعد وضع التسميات، فلن تضيع الميزانية.

تحقق من التسميات قبل التدريب#

لن يوقف التدريب صف يحتوي على عدد فردي من القيم، أو إحداثي مكتوب بالبكسل، أو مخطط مرسوم حول العنصر الخطأ. تقرأ أداة التحقق هذه مجموعة البيانات باستخدام أداة التحميل الخاصة بـ Ultralytics، وترفض الصفوف ذات التنسيق غير الصحيح، وتطبع مساحة كل مضلع بجانب الصندوق الذي ستشتقه Ultralytics منه:

from pathlib import Path

import numpy as np

from ultralytics.data.utils import check_det_dataset

data = check_det_dataset("coco8-seg.yaml")  # resolves paths, downloads if needed
for label in sorted(Path(data["path"], "labels", "train").glob("*.txt"))[:2]:
    for n, row in enumerate(label.read_text().splitlines(), 1):
        cls, *coords = row.split()
        if len(coords) % 2 or len(coords) < 6:
            print(f"{label.name}:{n} BAD: needs an even number of values and at least 3 vertices")
            continue
        xy = np.array(coords, dtype=float).reshape(-1, 2)
        if xy.min() < 0 or xy.max() > 1:
            print(f"{label.name}:{n} BAD: coordinates must be normalized to 0-1")
            continue
        x, y = xy[:, 0], xy[:, 1]
        area = 0.5 * abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)))  # shoelace formula
        w, h = xy.max(0) - xy.min(0)  # the box Ultralytics derives from the polygon
        name = data["names"][int(cls)]
        print(f"{label.stem} {name:9s} {len(xy):3d} vertices  polygon {area:.3f}  box {w * h:.3f}  fill {area / (w * h):.2f}")
000000000009 bowl       12 vertices  polygon 0.391  box 0.569  fill 0.69
000000000009 bowl       14 vertices  polygon 0.145  box 0.238  fill 0.61
000000000009 broccoli   50 vertices  polygon 0.161  box 0.252  fill 0.64
000000000009 bowl       55 vertices  polygon 0.079  box 0.531  fill 0.15
000000000009 orange     13 vertices  polygon 0.007  box 0.011  fill 0.64
000000000009 orange     13 vertices  polygon 0.005  box 0.009  fill 0.61
000000000009 orange     18 vertices  polygon 0.012  box 0.019  fill 0.61
000000000009 orange     12 vertices  polygon 0.010  box 0.022  fill 0.44
000000000025 giraffe    82 vertices  polygon 0.072  box 0.234  fill 0.31
000000000025 giraffe    19 vertices  polygon 0.010  box 0.027  fill 0.38

المساحات هي كسور من الصورة، لذا يغطي الوعاء الأول 39% من صورته. نسبة الامتلاء هي مساحة المضلع مقسومة على مساحة الصندوق، وهي العمود الذي ينبغي تفحصه:

  • تقع معظم الكائنات المدمجة (الأوعية والبرتقال والبروكلي) ضمن النطاق 0.6–0.7.
  • قيمة الزرافة، 0.31، حقيقية: تترك الأرجل الطويلة والرقبة معظم صندوقها فارغًا — وهذا هو سبب حاجة هذا الكائن إلى قناع أصلًا.
  • قيمة الوعاء الثالث، 0.15، هي الصف الذي ينبغي للمراجع فتحه. لا يظهر من هذا الوعاء سوى حافة رفيعة حول الطعام، لذا يشكل مخططه شريطًا ضيقًا داخل صندوق كبير. وهذا صحيح هنا؛ أما في بياناتك، فكثيرًا ما تشير نسبة الامتلاء المنخفضة هذه إلى أن المخطط مرسوم حول كائن غير صحيح.
قاعدة اتخاذ القرار

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

احصل على المضلعات دون تتبع كل حافة#

يُعد تتبع المخططات يدويًا الجزء المكلف من وضع تسميات البيانات. تحقق من الاختصار المناسب قبل أن يبدأ أي شخص:

لديك بالفعلالأداة
ملف JSON بتنسيق COCO يتضمن التجزئةconvert_coco(labels_dir, use_segments=True) من ultralytics.data.converter
أقنعة PNG (قيمة البكسل = فهرس الفئة + 1، و0 = الخلفية)convert_segment_masks_to_yolo_seg(masks_dir, output_dir, classes) — تظهر الكائنات المتلامسة من الفئة نفسها على هيئة مضلع واحد، لذا افصل بينها أثناء المراجعة
تسميات الصناديق فقطyolo_bbox2segment(im_dir) — يمرر كل صندوق إلى SAM لإنشاء مضلع
لا شيء بعدالتعليق الذكي ووضع التسميات على دفعات — انقر مرة واحدة، ثم راجع المضلع

في Ultralytics Platform، يشغّل الوضع الذكي SAM: تنتج نقرة إيجابية على الكائن ونقرة سلبية على ما ينبغي استبعاده قناعًا تراجعه بعد ذلك.

الوضع الذكي في Ultralytics Platform مع اختيار SAM 2.1 Tiny: تنتج نقرة إيجابية وأخرى سلبية على روبوت مستودع قناعه

راجع كل مضلع مُنشأ آليًا

يدرّب القناع الذي يمتد إلى الخلفية النموذج على فعل الشيء نفسه. راجع المضلعات المُنشأة آليًا وفق معيار الجودة في الصناديق مقابل الأقنعة، ثم أعد فحص التسميات أعلاه.

التدريب على COCO8-seg#

فسيفساء التدريب COCO8-seg: حُمُر وحشية، وزرافة، وعلب غداء من البروكلي والبرتقال، ومزهرية زهور، ولكل كائن قناعه الملون وفهرس فئته

يتبع التدريب سير عمل الكشف باستخدام نموذج -seg ومجموعة بيانات تجزئة. يستغرق إكمال حقبة واحدة باستخدام imgsz=320 على وحدة CPU محمولة ثوانٍ، وهذا يكفي لإثبات عمل المسار كاملًا:

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
model.train(data="coco8-seg.yaml", epochs=1, imgsz=320, device="cpu")
metrics = model.val()
print(f"box  mAP50-95: {metrics.box.map:.3f}")
print(f"mask mAP50-95: {metrics.seg.map:.3f}")
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95)     Mask(P          R      mAP50  mAP50-95)
                   all          4         17      0.909      0.449      0.661      0.482      0.685      0.409      0.557      0.377
                 horse          1          2          1      0.993      0.995      0.564      0.619      0.857      0.663      0.199
box  mAP50-95: 0.482
mask mAP50-95: 0.377

تجعل صور التحقق الأربع هذه الأرقام غير موثوقة؛ المهم هو اكتمال التشغيل وكتابة weights/best.pt في runs/segment/. استخدم دليل مهمة التجزئة للبيانات الحقيقية، ودرّب النموذج وفق الجدول الكامل على GPU.

اقرأ مقاييس الصناديق والأقنعة جنبًا إلى جنب#

يحتوي جدول التحقق على مجموعتين. تقيّم الصناديق كل صندوق متوقع بمقارنته بالصندوق الذي توحي به التسمية؛ أما الأقنعة فتقيّم وحدات البكسل المتوقعة بمقارنتها بالمضلع الموسوم. ويستخدم كلاهما آلية mAP نفسها؛ والاختلاف الوحيد هو IoU.

غالبًا ما تكون قيمة mAP50-95 للأقنعة أقل من نظيرتها للصناديق، لأن IoU على مستوى البكسل أشد صرامة: يظل التداخل جيدًا حتى عندما ينحرف الصندوق بضعة بكسلات، بينما تفقد الأقنعة التي لا تشمل ذراعًا أو تمتد إلى الطريق IoU بسرعة عند العتبات 0.75–0.95. يوضح صف horse هذه الحالة بأقصى وضوح — تبلغ قيمة mAP50-95 للصناديق 0.564 وللأقنعة 0.199. عثر النموذج على الحصانين ورسم صندوقيهما جيدًا، لكنه لم يرسم مخططي الأرجل والذيل. استخدم الفجوة لتحديد ما ينبغي إصلاحه:

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

يدمج overlap_mask=True أقنعة المثيلات في صورة واحدة أثناء التدريب، ويخفّض mask_ratio=4 دقة أقنعة التدريب. لا يغيّر أي منهما دقة الأقنعة المتنبأ بها — فهذا من اختصاص retina_masks في الدرس التالي. اتركهما على القيم الافتراضية ما لم تقس سببًا يدعو إلى تغييرهما.

جرّبه

شغّل check_seg_labels.py على مجموعة COCO8-seg كاملة (التدريب والتحقق)، وسجّل الصفوف الثلاثة ذات أدنى نسبة امتلاء. ثم درّب yolo26n-seg.pt على coco8-seg.yaml لحقبة واحدة باستخدام imgsz=320، وسجّل mAP50-95 للصناديق والأقنعة والفئة صاحبة أكبر فجوة، وافتح val_batch0_pred.jpg في مجلد التحقق للعثور على كائن يبدو قناعه أسوأ بوضوح من صندوقه.

متى يُعدّ مكتملًا
تكون قد أتممت الدرس عند تحقق جميع الشروط التالية.
  • أفادت أداة التحقق من التسميات بعدم وجود أي صفوف BAD، وحددت الصفوف الثلاثة ذات أدنى نسبة امتلاء مع قرار الإبقاء على كل منها أو إصلاحه.

  • اكتمل التدريب، ويوجد best.pt في runs/segment/، وسجلت قيمتي mAP50-95.

  • حددت الفئة صاحبة أكبر فجوة بين الصندوق والقناع، والخطوة التالية التي يوصي بها مخطط القرار.

عرض الحل

للتحقق من كل تقسيم، استبدل المجلد في الحلقة بـ Path(data["path"], "labels").rglob("*.txt"). ثم درّب النموذج:

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
model.train(data="coco8-seg.yaml", epochs=1, imgsz=320, device="cpu")
metrics = model.val()
print(f"box  mAP50-95: {metrics.box.map:.3f}")   # 0.482 in our run
print(f"mask mAP50-95: {metrics.seg.map:.3f}")   # 0.377 in our run

الفجوة البالغة 0.1 متوقعة: يعاقب IoU للأقنعة كل بكسل حدودي، بينما لا يعاقب IoU للصناديق سوى الحواف الأربع. في تشغيلنا، الفئة صاحبة أكبر فجوة هي horse (الصندوق 0.564، والقناع 0.199). قيمة mAP للصندوق جيدة، أما القناع فأقل منها بكثير، لذا يشير المخطط إلى جودة المخططات: تحقق من تلك المضلعات أولًا، ثم جرّب نموذجًا أكبر أو قيمة imgsz أعلى.

ما الخطوة التالية

بعد ذلك، سنحوّل الأقنعة المتوقعة إلى أرقام: المساحات والمخططات والتداخلات والقصاصات الشفافة.

سجّل الدخول لحفظ التقدم