دليل إعداد نموذج YAML
يعمل ملف إعداد نموذج YAML كمخطط معماري للشبكات العصبية الخاصة بـ Ultralytics. فهو يحدد كيفية اتصال الطبقات، والمعلمات التي يستخدمها كل نموذج، وكيفية توسيع نطاق الشبكة بالكامل عبر أحجام النماذج المختلفة.
هيكل الإعداد
يتم تنظيم ملفات نموذج 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 onlyncتحدد عدد الفئات التي يتنبأ بها النموذج.scalesتحدد عوامل التوسع المركبة التي تضبط عمق النموذج وعرضه وأقصى عدد للقنوات لإنتاج متغيرات مختلفة الأحجام (من النانو إلى الحجم الكبير جداً).kpt_shapeتنطبق على نماذج الوضعية. يمكن أن تكون[N, 2]لنقاط رئيسية من نوع(x, y)أو[N, 3]لنوع(x, y, visibility).
يسمح لك معامل scales بإنشاء أحجام نماذج متعددة من نموذج YAML أساسي واحد. على سبيل المثال، عند تحميل yolo26n.yaml، تقرأ Ultralytics نموذج yolo26.yaml الأساسي وتطبق عوامل التوسع n (أي depth=0.50 و width=0.25) لبناء متغير النانو.
إذا كانت مجموعة البيانات الخاصة بك تحدد 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 | تحميل أي نموذج من torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | استخراج موتر معين من القائمة | block.py | [out_ch, index] |
Detect | رأس الكشف YOLO | head.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]- وحدات PyTorch: الأسماء التي تبدأ بـ
'nn.'← مساحة اسمtorch.nn - عمليات TorchVision: الأسماء التي تبدأ بـ
'ops.'← مساحة اسمtorchvision.ops - وحدات Ultralytics البرمجية: يتم توجيه جميع الأسماء الأخرى → إلى مساحة الاسم العالمية (global namespace) عبر عمليات الاستيراد (imports).
سلسلة استيراد الوحدات
تصبح الوحدات القياسية متاحة من خلال عمليات الاستيراد في tasks.py:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)دمج الوحدات المخصصة
تعديل الكود المصدري
يعد تعديل الكود المصدري الطريقة الأكثر مرونة لدمج وحداتك المخصصة، ولكنها قد تكون معقدة. لتعريف وحدة مخصصة واستخدامها، اتبع الخطوات التالية:
-
قم بتثبيت Ultralytics في وضع التطوير (development mode) باستخدام طريقة استنساخ Git الموضحة في دليل البدء السريع.
-
عرّف وحدتك البرمجية في
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) -
اكشف عن وحدتك على مستوى الحزمة (package level) في
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
أضفها إلى عمليات الاستيراد في
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
تعامل مع الوسائط الخاصة (إذا لزم الأمر) داخل
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:]] -
استخدم الوحدة في نموذج YAML الخاص بك:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
تحقق من عدد عمليات 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}")التحقق من الصحة خطوة بخطوة
- ابدأ بالحد الأدنى: اختبر بأبسط بنية معمارية ممكنة أولاً
- أضف تدريجياً: ابْنِ التعقيد طبقة تلو الأخرى
- تحقق من الأبعاد: تأكد من توافق القناة والحجم المكاني
- تحقق من التحجيم: اختبر بأحجام نماذج مختلفة (
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. إذا كان صفراً، فاتبع الاقتراحات الموجودة في نصائح تصحيح الأخطاء للعثور على المشكلة.