Hướng dẫn Cấu hình Model YAML#
Tệp cấu hình model YAML đóng vai trò là 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 lớp kết nối, các tham số mà mỗi module sử dụng và cách toàn bộ mạng được mở rộng trên các kích thước model khác nhau.
Cấu trúc Cấu hình#
Các tệp model YAML được tổ chức thành ba phần chính phối hợp với nhau để định nghĩa kiến trúc.
Phần Tham số#
Phần parameters chỉ định các đặc tính toàn cục và hành vi mở rộng 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ố tỉ lệ hỗn hợp (compound scaling factors) để điều chỉnh độ sâu, độ rộng và số kênh tối đa của model nhằm 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(x, y)keypoints 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 file YAML cơ sở duy nhất. Ví dụ, khi bạn tải yolo26n.yaml, Ultralytics sẽ đọc file cơ sở yolo26.yaml và áp dụng các hệ số tỉ lệ 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 một nc hoặc kpt_shape khác, Ultralytics sẽ tự động ghi đè cấu hình model tại runtime để khớp với file 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á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 Đặc tả Lớp#
Mỗi lớp tuân theo mô hình 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 (lớp 6), [4, 6, 8] (đa đầu vào) |
| repeats | Số lần lặp lại | 1 (đơn), 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] (channels, kernel, stride) |
Các Mô hình Kết nối#
Trường from tạo ra các luồng dữ liệu linh hoạt trong toàn bộ mạng của bạn:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerCác lớp được đánh chỉ mục bắt đầu từ 0. Chỉ mục âm tham chiếu đến các lớp trước đó (-1 = lớp trước), trong khi chỉ mục dương tham chiếu đến các lớp 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 lại thực tế được nhân với hệ số mở rộng độ 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 tính năng và được định nghĩa trong Ultralytics modules directory. Các bảng sau đây hiển thị các module thường dùng theo danh mục, cùng 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 | Tham số |
|---|---|---|---|
Conv | Convolution + BatchNorm + Activation | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Upsampling không gian | PyTorch | [size, scale_factor, mode] |
nn.Identity | Thao tác truyền qua | PyTorch | [] |
Các Khối Tổng hợp#
| Module | Mục đích | Nguồn | Tham số |
|---|---|---|---|
C2f | CSP bottleneck với 2 convolutions | block.py | [out_ch, shortcut, expansion] |
SPPF | Spatial Pyramid Pooling (nhanh) | block.py | [out_ch, kernel_size] |
Concat | Nối theo kênh | conv.py | [dimension] |
Các Module Chuyên biệt#
| Module | Mục đích | Nguồn | Tham số |
|---|---|---|---|
TorchVision | Load 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 | YOLO detection head | head.py | [nc] |
Điều này đại diện cho một tập hợp con các module có sẵn. Để có danh sách đầy đủ các module và tham số của chúng, hãy khám phá modules directory.
Tính năng Nâng cao#
Tích hợp TorchVision#
Module TorchVision cho phép tích hợp mượt mà bất kỳ TorchVision model 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 để nhận các bản đồ đặc trưng trung gian (intermediate feature maps) cho việc phát hiện đa tỷ lệ (multi-scale detection).
Module Index để 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 tìm kiếm và import các module là rất quan trọng để tùy chỉnh:
Quy trình Tìm kiếm 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[16:])
if "torchvision.ops." in m
else globals()[m]
)- PyTorch modules: Tên bắt đầu bằng
'nn.'→ không gian têntorch.nn - TorchVision operations: Tên bắt đầu bằng
'torchvision.ops.'→ không gian têntorchvision.ops - Các module Ultralytics: Tất cả các tên khác → namespace toàn cục thông qua các import
Chuỗi Import Module#
Các module tiêu chuẩn có sẵn thông qua các câu 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ể sẽ 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) bằng cách sử dụng phương pháp clone Git từ Quickstart guide.
-
Đị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) -
Công khai module của bạn ở cấp độ package 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 câu lệnh 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 lan truyền tiến (forward pass) hoạt động:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Ví dụ 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 hay nhất#
Mẹo Thiết kế Kiến trúc#
Bắt đầu Đơn giản: 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 dần dần thay vì xây dựng từ đầu.
Kiểm tra Từng bước: Xác thực từng sửa đổi theo từng bước. 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 tiếp tục 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. Số kênh đầu ra (c2) của một lớp phải khớp với số 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 việc tái sử dụng đặc trưng với các mẫu [[-1, N], 1, Concat, [1]]. Các kết nối này hỗ trợ dòng truyền gradient và cho phép model kết hợp các đặc trưng từ các tỷ lệ khác nhau.
Tỷ lệ hóa phù hợp (Scale Appropriately): Chọn tỷ lệ model dựa trên các giới hạn tính toán của bạn. Sử dụng nano (n) cho thiết bị biên (edge devices), small (s) cho hiệu suất cân bằng và các tỷ lệ lớn hơn (m, l, x) để đạt độ chính xác tối đa.
Các cân nhắc về Hiệu suất#
Chiều sâu so với Chiều 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 biế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 của tác vụ.
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 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 gradient biến mất.
Khối Bottleneck: Giảm chi phí tính toán trong khi vẫn duy trì khả năng biểu diễn của model. Các module như C2f sử dụng ít tham số hơn so với các phép tích chập (convolutions) tiêu chuẩn trong khi vẫn bảo toàn năng lực học tập đặc trưng.
Đặc trưng Đa quy mô: Cần thiết để phát hiện các đối tượng có kích thước khác nhau trong cùng một hình ảnh. Sử dụng các mô hình Feature Pyramid Network (FPN) với nhiều đầu phát hiện ở các quy mô 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 của tasks.py |
| Kích thước kênh không khớp | Chỉ định 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 loại đối số | Kiểm tra tài liệu module để biết các loại đố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#
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 sớm các vấn đề:
Sử dụng Identity Head để Kiểm tra
Thay thế các head phức tạp bằng nn.Identity để cô lập các vấn đề về 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
Việc 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 xảy ra vấn đề với quá trình lan truyền tiến. Chạy một quá trình lan truyền tiến đơn giản sẽ cho thấy 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 thiểu: Kiểm tra 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 về kênh và kích thước không gian
- Xác thực tỷ lệ: Kiểm tra với các tỷ lệ model khác nhau (
n,s,m)
Câu hỏi thường gặp#
Đặt tham số
ncở đầu file YAML của bạn để khớp với số lượng lớp của tập dữ liệu.nc: 5 # 5 classesCó. Bạn có thể sử dụng bất kỳ module được hỗ trợ nào, bao gồm cả TorchVision backbones, hoặc định nghĩa module tùy chỉnh của riêng bạn và import nó như được mô tả trong Custom Module Integration.
Sử dụng phần
scalestrong file YAML của bạn để định nghĩa các hệ số tỉ lệ cho độ sâu, độ rộng và số kênh tối đa. Model sẽ tự động áp dụng các giá trị này khi bạn tải file YAML cơ sở với tỷ lệ được nối thêm vào tên file (ví dụ:yolo26n.yaml).Định dạng này chỉ định cách mỗi lớp được xây dựng:
from: nguồn đầu vàorepeats: số lần lặp lại modulemodule: loại lớpargs: các đối số cho module
Kiểm tra xem số kênh đầu ra của một lớp có khớp với số kênh đầu vào mong đợi của lớp tiếp theo hay không. Sử dụng
print(model.model.model)để kiểm tra kiến trúc model của bạn.Kiểm tra mã nguồn trong thư mục
ultralytics/nn/modulesđể biết tất cả các module có sẵn và các đối số của chúng.Định nghĩa module của bạn trong mã nguồn, import nó như được minh họa trong Source Code Modification, và tham chiếu nó bằng tên trong file YAML của bạn.
Có, bạn có thể sử dụng
model.load("path/to/weights")để tải 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 mới được tải thành công.Sử dụng
model.info()để kiểm tra xem số lượng FLOPs có khác không hay không. Một model hợp lệ sẽ hiển thị số lượng FLOPs khác không. Nếu bằng không, hãy làm theo các gợi ý trong Debugging Tips để tìm ra vấn đề.