YOLO Vision 2026:

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.

Model YAML configuration workflow.

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 only
  • nc thiế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).
Giảm dư thừa với `scales`

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.

`nc` và `kpt_shape` phụ thuộc vào tập dữ liệu

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ầnMục đíchVí dụ
fromKết nối đầu vào-1 (trước đó), 6 (lớp 6), [4, 6, 8] (đa đầu vào)
repeatsSố lần lặp lại1 (đơn), 3 (lặp lại 3 lần)
moduleLoại moduleConv, 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 layer
Đánh chỉ số Lớp

Cá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 layer

Số 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#

ModuleMục đíchNguồnTham số
ConvConvolution + BatchNorm + Activationconv.py[out_ch, kernel, stride, pad, groups]
nn.UpsampleUpsampling không gianPyTorch[size, scale_factor, mode]
nn.IdentityThao tác truyền quaPyTorch[]

Các Khối Tổng hợp#

ModuleMục đíchNguồnTham số
C2fCSP bottleneck với 2 convolutionsblock.py[out_ch, shortcut, expansion]
SPPFSpatial Pyramid Pooling (nhanh)block.py[out_ch, kernel_size]
ConcatNối theo kênhconv.py[dimension]

Các Module Chuyên biệt#

ModuleMục đíchNguồnTham số
TorchVisionLoad bất kỳ model torchvision nàoblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexTrích xuất tensor cụ thể từ danh sáchblock.py[out_ch, index]
DetectYOLO detection headhead.py[nc]
Danh sách Module Hoàn chỉnh

Đ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)
Đặc trưng Đa quy mô

Đặ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 detection

Hệ 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]
)
  1. PyTorch modules: Tên bắt đầu bằng 'nn.' → không gian tên torch.nn
  2. TorchVision operations: Tên bắt đầu bằng 'torchvision.ops.' → không gian tên torchvision.ops
  3. 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:

  1. 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.

  2. Đị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)
  3. 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
  4. Thêm vào các câu lệnh import trong ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Xử lý các đối số đặc biệt (nếu cần) bên trong parse_model() trong 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. 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]]
  7. 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]] # 7

Mô 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 detection

Mô 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ânGiải pháp
KeyError: 'ModuleName'Module chưa được importThêm vào các import của tasks.py
Kích thước kênh không khớpChỉ định args không chính xácXác minh tính tương thích của kênh đầu vào/đầu ra
AttributeError: 'int' object has no attributeSai 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ựngTham 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 dimensions

Kiể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

  1. 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
  2. Thêm tăng dần: Xây dựng độ phức tạp từng lớp một
  3. 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
  4. 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 classes
  • Có. 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 scales trong 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ào
    • repeats: số lần lặp lại module
    • module: loại lớp
    • args: 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 đề.

Bình luận