دليل إعداد نموذج YAML

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

Model YAML configuration workflow.

هيكل الإعداد

يتم تنظيم ملفات نموذج YAML في ثلاثة أقسام رئيسية تعمل معاً لتحديد البنية.

قسم المعلمات

يحدد قسم parameters الخصائص العامة للنموذج وسلوك التوسع:

# Parameters
nc: 80 # number of classes
scales: # compound scaling constants [depth, width, max_channels]
    n: [0.50, 0.25, 1024] # nano: shallow layers, narrow channels
    s: [0.50, 0.50, 1024] # small: shallow depth, standard width
    m: [0.50, 1.00, 512] # medium: moderate depth, full width
    l: [1.00, 1.00, 512] # large: full depth and width
    x: [1.00, 1.50, 512] # extra-large: maximum performance
kpt_shape: [17, 3] # pose models only
  • nc تحدد عدد الفئات التي يتنبأ بها النموذج.
  • scales تحدد عوامل التوسع المركبة التي تضبط عمق النموذج وعرضه وأقصى عدد للقنوات لإنتاج متغيرات مختلفة الأحجام (من النانو إلى الحجم الكبير جداً).
  • kpt_shape تنطبق على نماذج الوضعية. يمكن أن تكون [N, 2] لنقاط رئيسية من نوع (x, y) أو [N, 3] لنوع (x, y, visibility).
تقليل التكرار باستخدام `scales`

يسمح لك معامل scales بإنشاء أحجام نماذج متعددة من نموذج YAML أساسي واحد. على سبيل المثال، عند تحميل yolo26n.yaml، تقرأ Ultralytics نموذج yolo26.yaml الأساسي وتطبق عوامل التوسع n (أي depth=0.50 و width=0.25) لبناء متغير النانو.

`nc` و `kpt_shape` يعتمدان على مجموعة البيانات

إذا كانت مجموعة البيانات الخاصة بك تحدد nc أو kpt_shape مختلفاً، ستقوم Ultralytics تلقائياً بتجاوز إعداد النموذج في وقت التشغيل ليتطابق مع YAML الخاص بمجموعة البيانات.

بنية العمود الفقري والرأس

تتكون بنية النموذج من أقسام العمود الفقري (استخراج الميزات) والرأس (المخصص للمهام):

backbone:
    # [from, repeats, module, args]
    - [-1, 1, Conv, [64, 3, 2]] # 0: Initial convolution
    - [-1, 1, Conv, [128, 3, 2]] # 1: Downsample
    - [-1, 3, C2f, [128, True]] # 2: Feature processing

head:
    - [-1, 1, nn.Upsample, [None, 2, nearest]] # 6: Upsample
    - [[-1, 2], 1, Concat, [1]] # 7: Skip connection
    - [-1, 3, C2f, [256]] # 8: Process features
    - [[8], 1, Detect, [nc]] # 9: Detection layer

تنسيق مواصفات الطبقة

تتبع كل طبقة النمط الثابت: [from, repeats, module, args]

المكونالغرضأمثلة
fromاتصالات الإدخال-1 (السابقة)، 6 (الطبقة 6)، [4, 6, 8] (مدخلات متعددة)
repeatsعدد التكرارات1 (فردي)، 3 (تكرار 3 مرات)
moduleنوع الوحدةConv, C2f, TorchVision, Detect
argsوسائط الوحدة[64, 3, 2] (القنوات، النواة، الخطوة)

أنماط الاتصال

ينشئ حقل from أنماط تدفق بيانات مرنة عبر شبكتك:

- [-1, 1, Conv, [64, 3, 2]]    # Takes input from previous layer
فهرسة الطبقات

يتم فهرسة الطبقات بدءاً من 0. تشير الفهارس السالبة إلى الطبقات السابقة (-1 = الطبقة السابقة)، بينما تشير الفهارس الموجبة إلى طبقات محددة حسب موقعها.

تكرار الوحدة

ينشئ معامل repeats أقساماً أعمق في الشبكة:

- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer

يتم ضرب عدد التكرارات الفعلي في عامل توسيع العمق من إعداد حجم النموذج الخاص بك.

الوحدات المتاحة

يتم تنظيم الوحدات حسب الوظيفة وتعريفها في دليل وحدات Ultralytics. توضح الجداول التالية الوحدات المستخدمة بشكل شائع حسب الفئة، مع توفر العديد منها في الكود المصدري:

العمليات الأساسية

الوحدةالغرضالمصدرالوسائط
Convالتلافيف + BatchNorm + التنشيطconv.py[out_ch, kernel, stride, pad, groups]
nn.Upsampleالرفع المكانيPyTorch[size, scale_factor, mode]
nn.Identityعملية التمريرPyTorch[]

الكتل المركبة

الوحدةالغرضالمصدرالوسائط
C2fعنق زجاجة CSP مع 2 تلافيفblock.py[out_ch, shortcut, expansion]
SPPFتجميع الهرم المكاني (سريع)block.py[out_ch, kernel_size]
Concatالتسلسل حسب القناةconv.py[dimension]

وحدات متخصصة

الوحدةالغرضالمصدرالوسائط
TorchVisionتحميل أي نموذج من torchvisionblock.py[out_ch, model_name, weights, unwrap, truncate, split]
Indexاستخراج موتر معين من القائمةblock.py[out_ch, index]
Detectرأس الكشف YOLOhead.py[nc, anchors, ch]
قائمة الوحدات الكاملة

هذا يمثل مجموعة فرعية من الوحدات المتاحة. للحصول على القائمة الكاملة للوحدات ومعلماتها، استكشف دليل الوحدات.

ميزات متقدمة

تكامل TorchVision

تمكّن وحدة TorchVision التكامل السلس لأي نموذج TorchVision كعمود فقري:

from ultralytics import YOLO

# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)
ميزات متعددة المقاييس

اضبط المعلمة الأخيرة على True للحصول على خرائط ميزات وسيطة للكشف متعدد المقاييس.

وحدة الفهرس لاختيار الميزات

عند استخدام النماذج التي تخرج خرائط ميزات متعددة، تقوم وحدة الفهرس باختيار مخرجات محددة:

backbone:
    - [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]] # Multi-output
head:
    - [0, 1, Index, [192, 4]] # Select 4th feature map (192 channels)
    - [0, 1, Index, [384, 6]] # Select 6th feature map (384 channels)
    - [0, 1, Index, [768, 8]] # Select 8th feature map (768 channels)
    - [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detection

نظام دقة الوحدة

فهم كيفية تحديد موقع الوحدات واستيرادها في Ultralytics أمر حيوي للتخصيص:

عملية البحث عن الوحدة

تستخدم Ultralytics نظاماً من ثلاث طبقات في parse_model:

# Core resolution logic
m = getattr(torch.nn, m[3:]) if "nn." in m else getattr(torchvision.ops, m[4:]) if "ops." in m else globals()[m]
  1. وحدات PyTorch: الأسماء التي تبدأ بـ 'nn.' ← مساحة اسم torch.nn
  2. عمليات TorchVision: الأسماء التي تبدأ بـ 'ops.' ← مساحة اسم torchvision.ops
  3. وحدات Ultralytics البرمجية: يتم توجيه جميع الأسماء الأخرى → إلى مساحة الاسم العالمية (global namespace) عبر عمليات الاستيراد (imports).

سلسلة استيراد الوحدات

تصبح الوحدات القياسية متاحة من خلال عمليات الاستيراد في tasks.py:

from ultralytics.nn.modules import (  # noqa: F401
    SPPF,
    C2f,
    Conv,
    Detect,
    # ... many more modules
    Index,
    TorchVision,
)

دمج الوحدات المخصصة

تعديل الكود المصدري

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

  1. قم بتثبيت Ultralytics في وضع التطوير (development mode) باستخدام طريقة استنساخ Git الموضحة في دليل البدء السريع.

  2. عرّف وحدتك البرمجية في ultralytics/nn/modules/block.py:

    class CustomBlock(nn.Module):
        """Custom block with Conv-BatchNorm-ReLU sequence."""
    
        def __init__(self, c1, c2):
            """Initialize CustomBlock with input and output channels."""
            super().__init__()
            self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU())
    
        def forward(self, x):
            """Forward pass through the block."""
            return self.layers(x)
  3. اكشف عن وحدتك على مستوى الحزمة (package level) في ultralytics/nn/modules/__init__.py:

    from .block import CustomBlock  # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
  4. أضفها إلى عمليات الاستيراد في ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. تعامل مع الوسائط الخاصة (إذا لزم الأمر) داخل parse_model() في ملف ultralytics/nn/tasks.py:

    # Add this condition in the parse_model() function
    if m is CustomBlock:
        c1, c2 = ch[f], args[0]  # input channels, output channels
        args = [c1, c2, *args[1:]]
  6. استخدم الوحدة في نموذج YAML الخاص بك:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
  7. تحقق من عدد عمليات FLOPs للتأكد من أن مسار التمرير الأمامي (forward pass) يعمل:

    from ultralytics import YOLO
    
    model = YOLO("custom_model.yaml", task="classify")
    model.info()  # should print non-zero FLOPs if working

أمثلة على التكوينات

نموذج اكتشاف أساسي

# Simple YOLO detection model
nc: 80
scales:
    n: [0.33, 0.25, 1024]

backbone:
    - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
    - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
    - [-1, 3, C2f, [128, True]] # 2
    - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
    - [-1, 6, C2f, [256, True]] # 4
    - [-1, 1, SPPF, [256, 5]] # 5

head:
    - [-1, 1, Conv, [256, 3, 1]] # 6
    - [[6], 1, Detect, [nc]] # 7

نموذج عمود فقري (Backbone) من TorchVision

# ConvNeXt backbone with YOLO head
nc: 80

backbone:
    - [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]]

head:
    - [0, 1, Index, [192, 4]] # P3 features
    - [0, 1, Index, [384, 6]] # P4 features
    - [0, 1, Index, [768, 8]] # P5 features
    - [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detection

نموذج تصنيف

# Simple classification model
nc: 1000

backbone:
    - [-1, 1, Conv, [64, 7, 2, 3]]
    - [-1, 1, nn.MaxPool2d, [3, 2, 1]]
    - [-1, 4, C2f, [64, True]]
    - [-1, 1, Conv, [128, 3, 2]]
    - [-1, 8, C2f, [128, True]]
    - [-1, 1, nn.AdaptiveAvgPool2d, [1]]

head:
    - [-1, 1, Classify, [nc]]

أفضل الممارسات

نصائح لتصميم البنية المعمارية

ابدأ ببساطة: ابدأ ببنيات معمارية مثبتة قبل التخصيص. استخدم تكوينات YOLO الحالية كقوالب وقم بالتعديل عليها تدريجياً بدلاً من البناء من الصفر.

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

راقب القنوات: تأكد من توافق أبعاد القنوات بين الطبقات المتصلة. يجب أن تتطابق قنوات الإخراج (c2) لطبقة ما مع قنوات الإدخال (c1) للطبقة التالية في التسلسل.

استخدم وصلات التخطي (Skip Connections): استفد من إعادة استخدام الميزات باستخدام أنماط [[-1, N], 1, Concat, [1]]. تساعد هذه الوصلات في تدفق التدرج وتسمح للنموذج بدمج الميزات من مستويات مختلفة.

قم بالتحجيم بشكل مناسب: اختر أحجام النموذج بناءً على قيودك الحسابية. استخدم النوع الصغير جداً (n) للأجهزة الطرفية (edge devices)، والصغير (s) لتحقيق توازن في الأداء، والأحجام الأكبر (m, l, x) للحصول على أقصى دقة.

اعتبارات الأداء

العمق مقابل العرض: تلتقط الشبكات العميقة ميزات هرمية معقدة من خلال طبقات تحويل متعددة، بينما تعالج الشبكات العريضة المزيد من المعلومات بالتوازي في كل طبقة. وازن بينهما بناءً على تعقيد مهمتك.

وصلات التخطي (Skip Connections): تحسن تدفق التدرج أثناء التدريب وتمكن من إعادة استخدام الميزات في جميع أنحاء الشبكة. إنها مهمة بشكل خاص في البنيات الأعمق لمنع تلاشي التدرجات (vanishing gradients).

وحدات الاختناق (Bottleneck Blocks): تقلل من التكلفة الحسابية مع الحفاظ على قدرة النموذج التعبيرية. تستخدم وحدات مثل C2f معلمات أقل من عمليات الالتفاف (convolutions) القياسية مع الحفاظ على قدرة تعلم الميزات.

الميزات متعددة النطاقات: ضرورية لاكتشاف الكائنات بأحجام مختلفة في نفس الصورة. استخدم أنماط شبكة هرم الميزات (FPN) مع رؤوس اكتشاف متعددة على مستويات مختلفة.

استكشاف الأخطاء وإصلاحها

مشكلات شائعة

المشكلةالسببالحل
KeyError: 'ModuleName'الوحدة غير مستوردةأضفها إلى عمليات استيراد tasks.py
عدم تطابق أبعاد القناةتحديد غير صحيح للوسائط (args)تحقق من توافق قنوات الإدخال/الإخراج
AttributeError: 'int' object has no attributeنوع وسيط خاطئتحقق من وثائق الوحدة لمعرفة أنواع الوسائط الصحيحة
فشل بناء النموذجمرجع from غير صالحتأكد من وجود الطبقات المشار إليها

نصائح لتصحيح الأخطاء

عند تطوير بنيات معمارية مخصصة، يساعد تصحيح الأخطاء المنهجي في تحديد المشكلات مبكراً:

استخدم رأس الهوية (Identity Head) للاختبار

استبدل الرؤوس المعقدة بـ nn.Identity لعزل مشكلات العمود الفقري (backbone):

nc: 1
backbone:
    - [-1, 1, CustomBlock, [64]]
head:
    - [-1, 1, nn.Identity, []] # Pass-through for debugging

يسمح هذا بالفحص المباشر لمخرجات العمود الفقري:

import torch

from ultralytics import YOLO

model = YOLO("debug_model.yaml")
output = model.model(torch.randn(1, 3, 640, 640))
print(f"Output shape: {output.shape}")  # Should match expected dimensions

فحص بنية النموذج

يمكن أن يساعد التحقق من عدد عمليات FLOPs وطباعة كل طبقة في تصحيح المشكلات المتعلقة بتكوين النموذج المخصص الخاص بك. يجب أن يكون عدد FLOPs غير صفري ليكون النموذج صالحاً. إذا كان صفراً، فمن المحتمل أن تكون هناك مشكلة في مسار التمرير الأمامي (forward pass). تشغيل تمرير أمامي بسيط يجب أن يظهر الخطأ الدقيق الذي تمت مواجهته.

from ultralytics import YOLO

# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", verbose=True)

# Check model FLOPs. Failed forward pass causes 0 FLOPs.
model.info()

# Inspect individual layers
for i, layer in enumerate(model.model.model):
    print(f"Layer {i}: {layer}")

التحقق من الصحة خطوة بخطوة

  1. ابدأ بالحد الأدنى: اختبر بأبسط بنية معمارية ممكنة أولاً
  2. أضف تدريجياً: ابْنِ التعقيد طبقة تلو الأخرى
  3. تحقق من الأبعاد: تأكد من توافق القناة والحجم المكاني
  4. تحقق من التحجيم: اختبر بأحجام نماذج مختلفة (n, s, m)

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

كيف يمكنني تغيير عدد الفئات (classes) في نموذجي؟

قم بتعيين المعلمة nc في الجزء العلوي من ملف YAML الخاص بك لتتوافق مع عدد الفئات في مجموعة البيانات الخاصة بك.

nc: 5 # 5 classes

هل يمكنني استخدام عمود فقري (backbone) مخصص في نموذج YAML الخاص بي؟

نعم. يمكنك استخدام أي وحدة مدعومة، بما في ذلك الأعمدة الفقرية لـ TorchVision، أو تحديد وحدتك المخصصة واستيرادها كما هو موضح في دمج الوحدات المخصصة.

كيف يمكنني تحجيم نموذجي لأحجام مختلفة (صغير جداً، صغير، متوسط، إلخ)؟

استخدم قسم scales في ملف YAML الخاص بك لتحديد عوامل التحجيم للعمق والعرض والحد الأقصى للقنوات. سيقوم النموذج بتطبيقها تلقائياً عند تحميل ملف YAML الأساسي مع إلحاق الحجم باسم الملف (على سبيل المثال، yolo26n.yaml).

ماذا يعني تنسيق [from, repeats, module, args]؟

يحدد هذا التنسيق كيفية إنشاء كل طبقة:

  • from: مصدر الإدخال (المصادر)
  • repeats: عدد مرات تكرار الوحدة
  • module: نوع الطبقة
  • args: وسائط الوحدة

كيف يمكنني استكشاف أخطاء عدم تطابق القناة وإصلاحها؟

تحقق من أن قنوات الإخراج لطبقة ما تتطابق مع قنوات الإدخال المتوقعة للطبقة التالية. استخدم print(model.model.model) لفحص بنية نموذجك.

أين يمكنني العثور على قائمة بالوحدات المتاحة ووسائطها؟

تحقق من الكود المصدري في دليل ultralytics/nn/modules لمعرفة جميع الوحدات المتاحة ووسائطها.

كيف يمكنني إضافة وحدة مخصصة إلى تكوين YAML الخاص بي؟

حدد وحدتك في الكود المصدري، وقم باستيرادها كما هو موضح في تعديل الكود المصدري، وارجع إليها بالاسم في ملف YAML الخاص بك.

هل يمكنني استخدام أوزان مدربة مسبقاً مع ملف YAML مخصص؟

نعم، يمكنك استخدام model.load("path/to/weights") لتحميل الأوزان من نقطة فحص (checkpoint) مدربة مسبقاً. ومع ذلك، سيتم تحميل أوزان الطبقات المتطابقة فقط بنجاح.

كيف يمكنني التحقق من صحة تكوين نموذجي؟

استخدم model.info() للتحقق مما إذا كان عدد عمليات FLOPs غير صفري. يجب أن يُظهر النموذج الصالح عدداً غير صفري لـ FLOPs. إذا كان صفراً، فاتبع الاقتراحات الموجودة في نصائح تصحيح الأخطاء للعثور على المشكلة.

تعليقات