Ultralytics YOLO27:

Hướng dẫn cấu hình YAML cho model#

Tệp cấu hình YAML của model đóng vai trò là bản thiết kế kiến trúc cho các mạng neural của Ultralytics. Tệp này xác định cách các layer kết nối với nhau, từng module sử dụng những tham số nào và toàn bộ mạng mở rộng ra sao 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 YAML của model được tổ chức thành ba phần chính, phối hợp với nhau để xác định kiến trúc.

Phần tham số#

Phần parameters chỉ định các đặc tính toàn cục và cơ chế scaling 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 đặt số lớp mà model dự đoán.
  • scales xác định các hệ số compound scaling để điều chỉnh độ sâu, độ rộng và số channel tối đa của model, từ đó tạo ra các biến thể với kích thước khác nhau (từ nano đến extra-large).
  • kpt_shape áp dụng cho các model pose. Giá trị này có thể là [N, 2] cho (x, y) keypoint 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 YAML cơ sở duy nhất. Ví dụ, khi tải yolo26n.yaml, Ultralytics đọc 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.

`nc` và `kpt_shape` phụ thuộc vào dataset

Nếu dataset 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 thời điểm runtime để khớp với YAML của dataset.

Kiến trúc Backbone và Head#

Kiến trúc model gồm các phần backbone (trích xuất đặc trưng) và head (dành riêng cho từng tác vụ):

nc: 80

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]] # 3: Upsample
    - [[-1, 0], 1, Concat, [1]] # 4: Spatially compatible skip connection
    - [-1, 3, C2f, [256]] # 5: Process features
    - [[5], 1, Detect, [nc]] # 6: Detection layer

Các chỉ số layer tiếp tục xuyên suốt backbone và head, đồng thời các feature map được nối phải có cùng kích thước không gian.

Định dạng đặc tả layer#

Mỗi layer tuân theo mẫu nhất quán: [from, repeats, module, args]

Thành phầnMục đíchVí dụ
fromCác kết nối đầu vào-1 (trước đó), 6 (layer 6), [4, 6, 8] (nhiều đầu vào)
repeatsSố lần lặp1 (một lần), 3 (lặp 3 lần)
moduleLoại moduleConv, C2f, TorchVision, Detect
argsCác đối số của module[64, 3, 2] (channel, 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 của bạn:

- [-1, 1, Conv, [64, 3, 2]]    # Takes input from previous layer
Đánh chỉ mục layer

Các layer được đánh chỉ mục bắt đầu từ 0. 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 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 thực tế đượ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à định nghĩa trong thư mục module của Ultralytics. Các bảng sau đây trình bày những module thường dùng theo danh mục; mã nguồn còn cung cấp nhiều module khác:

Các phép toán cơ bản#

ModuleMục đíchNguồnArguments
ConvConvolution + BatchNorm + Activationconv.py[out_ch, kernel, stride, pad, groups]
nn.UpsampleUpsampling không gianPyTorch[size, scale_factor, mode]
nn.IdentityPhép toán truyền quaPyTorch[]

Các block composite#

ModuleMục đíchNguồnArguments
C2fBottleneck CSP với 2 convolutionblock.py[out_ch, shortcut, groups, expansion]
SPPFSpatial Pyramid Pooling (nhanh)block.py[out_ch, kernel_size]
ConcatNối theo channelconv.py[dimension]

Các module chuyên biệt#

ModuleMục đíchNguồnArguments
TorchVisionTải bất kỳ model torchvision nàoblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexTrích xuất tensor cụ thể từ listconv.py[out_ch, index]
DetectHead detection của YOLOhead.py[nc]
Danh sách module đầy đủ

Đây chỉ là một phần các module khả dụng. Để xem danh sách đầy đủ các module và tham số của chúng, hãy khám phá thư mục module.

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="imagenet10", epochs=100)
Đặc trưng đa scale

Đặt tham số cuối cùng thành True để nhận các feature map trung gian cho detection đa scale.

Module Index để chọn feature#

Khi sử dụng các model xuất ra nhiều feature map, module Index sẽ chọn những đầu ra cụ thể:

nc: 80

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 định vị và import module là yếu tố then chốt để tùy chỉnh:

Quy trình tra cứu module#

Ultralytics sử dụng hệ thống ba tầng trong parse_model:

# Core resolution logic
m = (
    getattr(torch.nn, m[3:])
    if m.startswith("nn.")
    else getattr(__import__("torchvision").ops, m[16:])
    if m.startswith("torchvision.ops.")
    else globals()[m]
)  # get module
  1. Các module PyTorch: Tên bắt đầu bằng 'nn.' → namespace torch.nn
  2. Các phép toán TorchVision: Tên bắt đầu bằng 'torchvision.ops.' → namespace torchvision.ops
  3. Các module Ultralytics: Tất cả tên còn lại → namespace global thông qua các import

Chuỗi import module#

Các module tiêu chuẩn trở nên khả dụng thông qua những 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, 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 thực hiện các bước sau:

  1. Cài đặt Ultralytics ở chế độ development bằng phương thức Git clone trong hướng dẫn Quickstart.

  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. Expose module ở 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 import trong ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Thêm module vào base_modules bên trong parse_model(). Các module trong tập hợp này sẽ tự động nhận số channel đầu vào và đầu ra:

    base_modules = frozenset(
        {
            # Existing modules...
            CustomBlock,
        }
    )
  6. Sử dụng module trong YAML của model:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
  7. Kiểm tra FLOPs để đảm bảo 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

Cấu hình ví dụ#

Model detection 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

Model với 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

Model classification#

# 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]]

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

Classify đã thực hiện adaptive average pooling nội bộ.

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: 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 mẫu và sửa đổi từng bước thay vì xây dựng từ đầu.

Kiểm thử từng bước: Xác thực từng sửa đổi theo từng bước. Thêm từng module tùy chỉnh một và xác minh module hoạt động trước khi chuyển sang thay đổi tiếp theo.

Theo dõi các kênh: Đảm bảo số chiều kênh khớp nhau giữa các layer được kết nối. Các kênh đầu ra (c2) của một layer phải khớp với các kênh đầu vào (c1) của layer tiếp theo trong chuỗi.

Sử dụng skip connection: Tận dụng việc 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ợ luồng gradient và cho phép model kết hợp đặc trưng từ các scale khác nhau.

Chọn scale phù hợp: Chọn scale của 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 các thiết bị edge, small (s) để cân bằng hiệu năng và các scale lớn hơn (m, l, x) để đạt độ chính xác tối đa.

Các yếu tố về hiệu năng#

Độ sâu và độ rộng: Các mạng sâu nắm bắt những đặc trưng phân cấp phức tạp thông qua nhiều layer biến đổi, trong khi các mạng rộng xử lý nhiều thông tin hơn song song ở mỗi layer. Hãy cân bằng hai yếu tố này dựa trên độ phức tạp của tác vụ.

Skip connection: Cải thiện luồng gradient trong quá trình huấn luyện và cho phép tái sử dụng đặc trưng trong toàn mạng. Chúng đặc biệt quan trọng trong các kiến trúc sâu để ngăn gradient biến mất.

Block bottleneck: Giảm chi phí tính toán trong khi vẫn duy trì khả năng biểu đạt của model. Các module như C2f sử dụng ít parameter hơn so với phép tích chập tiêu chuẩn nhưng vẫn bảo toàn khả năng học đặc trưng.

Đặc trưng đa scale: 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 ảnh. Sử dụng các pattern của Feature Pyramid Network (FPN) với nhiều detection head ở các scale khác nhau.

Khắc phục sự cố#

Các sự cố thường gặp#

Vấn đềNguyên nhânGiải pháp
KeyError: 'ModuleName'Module chưa được importThêm vào phần import của tasks.py
Không khớp số chiều kênhĐặc tả 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 attributeKiểu đối số không đúngKiểm tra tài liệu của module để biết các kiểu đối số chính xác
Không thể build modelTham chiếu from không hợp lệĐảm bảo các layer được tham chiếu tồn tại

Mẹo debug#

Khi phát triển các kiến trúc tùy chỉnh, việc debug có hệ thống giúp xác định sớm các vấn đề:

Sử dụng Identity Head để kiểm thử

Thay thế các head phức tạp bằng nn.Identity để cô lập các vấn đề của 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 đầu ra của backbone:

import torch

from ultralytics import YOLO

model = YOLO("debug_model.yaml", task="detect")
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 model

Kiểm tra số FLOPs và in từng layer cũng có thể giúp debug các vấn đề với cấu hình model tùy chỉnh. Số FLOPs phải khác 0 đối với một model hợp lệ. Nếu bằng 0, nhiều khả năng đã xảy ra vấn đề trong forward pass. Chạy một forward pass đơn giản sẽ hiển thị chính xác lỗi đang gặp phải.

from ultralytics import YOLO

# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", task="detect", 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 giản: Trước tiên, kiểm thử với kiến trúc đơn giản nhất có thể
  2. Thêm từng bước: Xây dựng độ phức tạp layer theo layer
  3. Kiểm tra số chiều: Xác minh tính tương thích của kênh và kích thước không gian
  4. Xác thực scaling: Kiểm thử với các scale model khác nhau (n, s, m)

FAQ#

  • Đặt parameter nc ở đầu file YAML sao cho khớp với số lớp của dataset.

    nc: 5 # 5 classes
  • Có. Bạn có thể sử dụng bất kỳ module nào được hỗ trợ, bao gồm backbone TorchVision, hoặc tự định nghĩa module tùy chỉnh và import module đó như mô tả trong Tích hợp module tùy chỉnh.

  • Sử dụng section scales trong YAML để xác định các hệ số scaling cho độ sâu, độ rộng và số kênh tối đa. Model sẽ tự động áp dụng các hệ số này khi bạn tải file YAML cơ sở với scale được thêm vào tên file (ví dụ: yolo26n.yaml).

  • Định dạng này chỉ rõ cách xây dựng từng layer:

    • from: (các) nguồn đầu vào
    • repeats: số lần lặp lại module
    • module: loại layer
    • args: các đối số của module
  • Kiểm tra để bảo đảm các kênh đầu ra của một layer khớp với các kênh đầu vào dự kiến của layer tiếp theo. 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 để xem tất cả module hiện có và các đối số của chúng.

  • Định nghĩa module trong mã nguồn, import module như hướng dẫn trong Sửa đổi mã nguồn, rồi tham chiếu module bằng tên trong file YAML.

  • Có, bạn có thể sử dụng model.load("path/to/weights") để tải weights từ một pretrained checkpoint. Tuy nhiên, chỉ các weights của những layer tương ứng mới được tải thành công.

  • Sử dụng model.info() để kiểm tra xem số FLOPs có khác 0 hay không. Một model hợp lệ phải có số FLOPs khác 0. Nếu bằng 0, hãy làm theo các đề xuất trong Mẹo debug để tìm vấn đề.

Bình luận