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

يحتوي ملف تسميات التجزئة على صف واحد لكل كائن، مثل تسمية الكشف، لكنه يسرد مخطط الكائن على هيئة أزواج رؤوس مطبّعة بدلًا من صندوق. فيما يلي صف فعلي من 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–5 | x_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: تنتج نقرة إيجابية على الكائن ونقرة سلبية على ما ينبغي استبعاده قناعًا تراجعه بعد ذلك.

يدرّب القناع الذي يمتد إلى الخلفية النموذج على فعل الشيء نفسه. راجع المضلعات المُنشأة آليًا وفق معيار الجودة في الصناديق مقابل الأقنعة، ثم أعد فحص التسميات أعلاه.
التدريب على 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 في الدرس التالي. اتركهما على القيم الافتراضية ما لم تقس سببًا يدعو إلى تغييرهما.
عرض الحل
للتحقق من كل تقسيم، استبدل المجلد في الحلقة بـ 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 أعلى.