Hướng dẫn Cấu hình YAML cho Model
Tệp cấu hình YAML của model đóng vai trò như bản thiết kế kiến trúc cho các mạng thần kinh Ultralytics. Nó xác định cách các layer kết nối, các tham số mà mỗi module sử dụng, và cách toàn bộ mạng lưới thay đổi quy mô (scale) theo các kích thước model khác nhau.
Cấu trúc Cấu hình
Các tệp YAML của model được tổ chức thành ba phần chính phối hợp cùng nhau để định nghĩa kiến trúc.
Phần Tham số (Parameters)
Phần parameters chỉ định các đặc tính toàn cục và hành vi mở rộng quy mô của model:
# 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 onlyncthiết lập số lượng lớp (classes) mà model dự đoán.scalesđịnh nghĩa các hệ số mở rộng phức hợp giúp điều chỉnh độ sâu, độ rộng và số kênh tối đa của model để tạo ra các biến thể kích thước khác nhau (từ nano đến extra-large).kpt_shapeáp dụng cho các model pose. Nó có thể là[N, 2]cho các keypoint(x, y)hoặc[N, 3]cho(x, y, visibility).
Tham số scales cho phép bạn tạo nhiều kích thước model từ một YAML cơ sở. Ví dụ, khi bạn load yolo26n.yaml, Ultralytics sẽ đọc tệp yolo26.yaml cơ sở và áp dụng các hệ số scaling n (depth=0.50, width=0.25) để xây dựng biến thể nano.
Nếu tập dữ liệu của bạn chỉ định nc hoặc kpt_shape khác, Ultralytics sẽ tự động ghi đè cấu hình model tại runtime để khớp với YAML của tập dữ liệu.
Kiến trúc Backbone và Head
Kiến trúc model bao gồm các phần backbone (trích xuất đặc trưng) và head (chuyên biệt cho từng tác vụ):
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Định dạng Chỉ định Layer
Mỗi layer tuân theo cấu trúc nhất quán: [from, repeats, module, args]
| Thành phần | Mục đích | Ví dụ |
|---|---|---|
| from | Kết nối đầu vào | -1 (trước đó), 6 (layer 6), [4, 6, 8] (nhiều đầu vào) |
| repeats | Số lần lặp lại | 1 (đơn lẻ), 3 (lặp lại 3 lần) |
| module | Loại module | Conv, C2f, TorchVision, Detect |
| args | Đối số của module | [64, 3, 2] (số kênh, kernel, stride) |
Các Mẫu Kết nối
Trường from tạo ra các mẫu luồng dữ liệu linh hoạt trong toàn bộ mạng lưới của bạn:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerCác layer được đánh chỉ mục bắt đầu từ 0. Các chỉ số âm tham chiếu đến các layer trước đó (-1 = layer trước đó), trong khi chỉ số dương tham chiếu đến các layer cụ thể theo vị trí của chúng.
Lặp lại Module
Tham số repeats tạo ra các phần mạng sâu hơn:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layerSố lần lặp thực tế sẽ được nhân với hệ số scaling độ sâu từ cấu hình kích thước model của bạn.
Các Module Khả dụng
Các module được tổ chức theo chức năng và được định nghĩa trong thư mục module của Ultralytics. Các bảng sau đây hiển thị các module thường được sử dụng theo danh mục, với nhiều module khác có sẵn trong mã nguồn:
Các Thao tác Cơ bản
| Module | Mục đích | Nguồn | Đối số |
|---|---|---|---|
Conv | Convolution + BatchNorm + Activation | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Lấy mẫu không gian (Spatial upsampling) | PyTorch | [size, scale_factor, mode] |
nn.Identity | Thao tác truyền qua (Pass-through) | PyTorch | [] |
Các Khối Tổng hợp
| Module | Mục đích | Nguồn | Đối số |
|---|---|---|---|
C2f | CSP bottleneck với 2 convolution | block.py | [out_ch, shortcut, expansion] |
SPPF | Spatial Pyramid Pooling (nhanh) | block.py | [out_ch, kernel_size] |
Concat | Ghép nối theo kênh | conv.py | [dimension] |
Các Module Chuyên biệt
| Module | Mục đích | Nguồn | Đối số |
|---|---|---|---|
TorchVision | Tải bất kỳ model torchvision nào | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Trích xuất tensor cụ thể từ danh sách | block.py | [out_ch, index] |
Detect | Head phát hiện YOLO | head.py | [nc, anchors, ch] |
Đây là một tập hợp con các module hiện có. Để xem danh sách đầy đủ các module và tham số của chúng, hãy khám phá thư mục module.
Các Tính năng Nâng cao
Tích hợp TorchVision
Module TorchVision cho phép tích hợp liền mạch bất kỳ model TorchVision nào làm backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)Đặt tham số cuối cùng thành True để lấy các bản đồ đặc trưng trung gian cho phát hiện đa quy mô.
Module Index cho Lựa chọn Đặc trưng
Khi sử dụng các model xuất ra nhiều bản đồ đặc trưng, module Index sẽ chọn các đầu ra cụ thể:
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 detectionHệ thống Phân giải Module
Hiểu cách Ultralytics định vị và import các module là rất quan trọng để tùy chỉnh:
Quy trình Tra cứu Module
Ultralytics sử dụng hệ thống ba cấp trong 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]- Các module PyTorch: Tên bắt đầu bằng
'nn.'→ namespacetorch.nn - Các thao tác TorchVision: Tên bắt đầu bằng
'ops.'→ namespacetorchvision.ops - Các module Ultralytics: Tất cả các tên khác → namespace toàn cục thông qua các lệnh import
Chuỗi Import Module
Các module tiêu chuẩn có sẵn thông qua các lệnh import trong tasks.py:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)Tích hợp Module Tùy chỉnh
Sửa đổi Mã nguồn
Sửa đổi mã nguồn là cách linh hoạt nhất để tích hợp các module tùy chỉnh của bạn, nhưng có thể khá phức tạp. Để định nghĩa và sử dụng một module tùy chỉnh, hãy làm theo các bước sau:
-
Cài đặt Ultralytics ở chế độ phát triển (development mode) sử dụng phương thức Git clone từ Hướng dẫn Bắt đầu nhanh.
-
Định nghĩa module của bạn trong
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) -
Hiển thị module của bạn ở cấp độ gói (package level) trong
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
Thêm vào các import trong
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
Xử lý các đối số đặc biệt (nếu cần) bên trong
parse_model()trongultralytics/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:]] -
Sử dụng module trong YAML mô hình của bạn:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
Kiểm tra FLOPs để đảm bảo quá trình forward pass hoạt động bình thường:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Ví dụ về Cấu hình
Mô hình Phát hiện Cơ bản
# 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]] # 7Mô hình 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 detectionMô hình Phân loại
# 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]]Các phương pháp tốt nhất
Mẹo Thiết kế Kiến trúc
Bắt đầu đơn giản: Hãy bắt đầu với các kiến trúc đã được kiểm chứng trước khi tùy chỉnh. Sử dụng các cấu hình YOLO hiện có làm khuôn mẫu và sửa đổi từng bước thay vì xây dựng từ đầu.
Kiểm thử tăng dần: Xác thực từng bước sửa đổi. Thêm một module tùy chỉnh tại một thời điểm và xác minh nó hoạt động trước khi chuyển sang thay đổi tiếp theo.
Theo dõi kênh (channels): Đảm bảo kích thước kênh khớp giữa các lớp được kết nối. Các kênh đầu ra (c2) của một lớp phải khớp với các kênh đầu vào (c1) của lớp tiếp theo trong chuỗi.
Sử dụng Kết nối tắt (Skip Connections): Tận dụng khả năng tái sử dụng đặc trưng với các pattern [[-1, N], 1, Concat, [1]]. Các kết nối này hỗ trợ dòng gradient và cho phép mô hình kết hợp các đặc trưng từ các thang đo khác nhau.
Quy mô phù hợp: Chọn quy mô mô hình dựa trên các ràng buộc tính toán của bạn. Sử dụng nano (n) cho các thiết bị cạnh (edge devices), small (s) cho hiệu suất cân bằng, và các quy mô lớn hơn (m, l, x) để đạt độ chính xác tối đa.
Các xem xét về Hiệu suất
Độ sâu so với Độ rộng: Các mạng sâu nắm bắt các đặc trưng phân cấp phức tạp thông qua nhiều lớp chuyển đổi, trong khi các mạng rộng xử lý nhiều thông tin song song tại mỗi lớp. Cân bằng các yếu tố này dựa trên độ phức tạp nhiệm vụ của bạn.
Kết nối tắt (Skip Connections): Cải thiện dòng gradient trong quá trình huấn luyện và cho phép tái sử dụng đặc trưng trên toàn bộ mạng. Chúng đặc biệt quan trọng trong các kiến trúc sâu hơn để ngăn chặn hiện tượng mất dần gradient (vanishing gradients).
Các khối Bottleneck: Giảm chi phí tính toán trong khi vẫn duy trì khả năng biểu đạt của mô hình. Các module như C2f sử dụng ít tham số hơn so với các tích chập tiêu chuẩn trong khi vẫn bảo tồn khả năng học đặc trưng.
Đặc trưng đa thang đo: Rất cần thiết để phát hiện các đối tượng ở các kích thước khác nhau trong cùng một hình ảnh. Sử dụng các pattern Feature Pyramid Network (FPN) với nhiều đầu phát hiện (detection heads) ở các thang đo khác nhau.
Khắc phục sự cố
Các vấn đề thường gặp
| Vấn đề | Nguyên nhân | Giải pháp |
|---|---|---|
KeyError: 'ModuleName' | Module chưa được import | Thêm vào các import trong tasks.py |
| Kích thước kênh không khớp | Đặc tả args không chính xác | Xác minh tính tương thích của kênh đầu vào/đầu ra |
AttributeError: 'int' object has no attribute | Sai kiểu đối số | Kiểm tra tài liệu module để biết các kiểu đối số chính xác |
| Mô hình không thể xây dựng | Tham chiếu from không hợp lệ | Đảm bảo các lớp được tham chiếu tồn tại |
Mẹo gỡ lỗi (Debugging)
Khi phát triển các kiến trúc tùy chỉnh, việc gỡ lỗi có hệ thống giúp xác định các vấn đề sớm:
Sử dụng Identity Head để Kiểm thử
Thay thế các đầu phát hiện phức tạp bằng nn.Identity để cô lập các vấn đề ở backbone:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debuggingĐiều này cho phép kiểm tra trực tiếp các đầu ra của backbone:
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 dimensionsKiểm tra Kiến trúc Mô hình
Kiểm tra số lượng FLOPs và in ra từng lớp cũng có thể giúp gỡ lỗi các vấn đề với cấu hình mô hình tùy chỉnh của bạn. Số lượng FLOPs phải khác không đối với một mô hình hợp lệ. Nếu nó bằng không, thì có khả năng có vấn đề với quá trình forward pass. Chạy một forward pass đơn giản sẽ hiển thị lỗi chính xác đang gặp phải.
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}")Xác thực Từng bước
- Bắt đầu tối giản: Kiểm thử với kiến trúc đơn giản nhất có thể trước
- Thêm tăng dần: Xây dựng độ phức tạp từng lớp một
- Kiểm tra kích thước: Xác minh tính tương thích của kênh và kích thước không gian
- Xác thực quy mô: Kiểm thử với các quy mô mô hình khác nhau (
n,s,m)
Câu hỏi thường gặp (FAQ)
Làm cách nào để thay đổi số lượng lớp (classes) trong mô hình của tôi?
Thiết lập tham số nc ở đầu tệp YAML của bạn để khớp với số lượng lớp của tập dữ liệu của bạn.
nc: 5 # 5 classesTôi có thể sử dụng một backbone tùy chỉnh trong YAML mô hình của mình không?
Có. Bạn có thể sử dụng bất kỳ module nào được hỗ trợ, bao gồm các backbone TorchVision, hoặc tự định nghĩa module tùy chỉnh của riêng mình và import nó như được mô tả trong Tích hợp Module Tùy chỉnh.
Làm cách nào để điều chỉnh quy mô mô hình cho các kích thước khác nhau (nano, small, medium, v.v.)?
Sử dụng phần scales section trong YAML của bạn để định nghĩa các hệ số tỉ lệ cho độ sâu, độ rộng và các kênh tối đa. Mô hình sẽ tự động áp dụng các hệ số này khi bạn tải tệp YAML cơ sở với quy mô được thêm vào tên tệp (ví dụ: yolo26n.yaml).
Định dạng [from, repeats, module, args] có nghĩa là gì?
Định dạng này chỉ định cách mỗi lớp được xây dựng:
from: (các) nguồn đầu vàorepeats: số lần lặp lại modulemodule: loại lớpargs: các đối số cho module
Làm cách nào để khắc phục lỗi không khớp kênh?
Kiểm tra xem các kênh đầu ra của một lớp có khớp với các kênh đầu vào dự kiến của lớp tiếp theo hay không. Sử dụng print(model.model.model) để kiểm tra kiến trúc mô hình của bạn.
Tôi có thể tìm danh sách các module khả dụng và các đối số của chúng ở đâu?
Kiểm tra mã nguồn trong ultralytics/nn/modules directory để biết tất cả các module khả dụng và đối số của chúng.
Làm cách nào để thêm một module tùy chỉnh vào cấu hình YAML của tôi?
Định nghĩa module của bạn trong mã nguồn, import nó như được hiển thị trong Sửa đổi Mã nguồn, và tham chiếu nó theo tên trong tệp YAML của bạn.
Tôi có thể sử dụng các trọng số (weights) đã huấn luyện trước với một YAML tùy chỉnh không?
Có, bạn có thể sử dụng model.load("path/to/weights") để tải các trọng số từ một checkpoint đã huấn luyện trước. Tuy nhiên, chỉ những trọng số cho các lớp khớp nhau mới được tải thành công.
Làm cách nào để xác thực cấu hình mô hình của tôi?
Sử dụng model.info() để kiểm tra xem số lượng FLOPs có khác không hay không. Một mô hình hợp lệ sẽ hiển thị số lượng FLOPs khác không. Nếu nó bằng không, hãy làm theo các gợi ý trong Mẹo gỡ lỗi để tìm vấn đề.