Chuyển đến nội dung

Hướng dẫn Cấu hình YAML Mô hình

Tệp cấu hình YAML mô hình đóng vai trò là bản thiết kế kiến trúc cho các mạng nơ-ron Ultralytics. Nó xác định cách các lớp kết nối, những tham số mà mỗi module sử dụng và cách toàn bộ mạng mở rộng trên các kích thước mô hình khác nhau.

Cấu trúc Cấu hình

Các tệp YAML mô hình đượ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 chung và hành vi mở rộng của mô hình:

# 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ượng lớp (class) mà mô hình dự đoán.
  • scales xác định các hệ số mở rộng hỗn hợp để điều chỉnh độ sâu, chiều rộng và số lượng kênh tối đa của mô hình để 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 mô hình pose. Nó có thể là [N, 2] cho (x, y) các điểm chính hoặc [N, 3] cho (x, y, visibility).

Giảm thiểu sự trùng lặp với scales

Hàm scales tham số cho phép bạn tạo nhiều kích cỡ mô hình từ một tệp YAML cơ sở duy nhất. Ví dụ: khi bạn tải yolo11n.yaml, Ultralytics sẽ đọc tệp yolo11.yaml và áp dụng các n hệ số tỷ lệ (depth=0.50, width=0.25) để xây dựng biến thể nano.

nckpt_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, Ultralytics sẽ tự động ghi đè cấu hình mô hình tại thời điểm chạy để khớp với YAML của tập dữ liệu.

Kiến trúc Backbone và Head

Kiến trúc mô hình bao gồm các phần backbone (trích xuất đặc trưng) và head (dành riêng 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ả Layer

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

Thành phần Mục đích Ví dụ
từ Kết nối đầu vào -1 (trước đó), 6 (layer 6), [4, 6, 8] (đa đầu vào)
số lần lặp lại 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ẫu Kết nối

Hàm 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
- [[-1, 6], 1, Concat, [1]]    # Combines current layer with layer 6
- [[4, 6, 8], 1, Detect, [nc]] # Detection head using 3 feature scales

Lập Chỉ Mục Lớp

Các lớp được lập 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 Mô-đun

Hàm repeats tham số 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ố tỷ lệ độ sâu từ cấu hình kích thước mô hình của bạn.

Các Mô-đun Có sẵn

Các mô-đun được sắp xếp theo chức năng và được xác định trong thư mục mô-đun Ultralytics. Các bảng sau đây hiển thị các mô-đun thường được sử dụng theo danh mục, với nhiều mô-đun khác có sẵn trong mã nguồn:

Các Thao tác Cơ bản

Mô-đun Mục đích Nguồn Các đối số
Conv Convolution + BatchNorm + Activation conv.py [out_ch, kernel, stride, pad, groups]
nn.Upsample Lấy mẫu tăng không gian PyTorch [size, scale_factor, mode]
nn.Identity Hoạt động chuyển tiếp PyTorch []

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

Mô-đun Mục đích Nguồn Các đố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 kênh theo chiều conv.py [dimension]

Các Mô-đun Chuyên dụng

Mô-đun Mục đích Nguồn Các đối số
TorchVision Tải bất kỳ mô hình 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 Đầu dò tìm YOLO head.py [nc, anchors, ch]

Danh Sách Mô-đun Đầy Đủ

Đây là một tập hợp con của các mô-đun có sẵn. Để có danh sách đầy đủ các mô-đun và tham số của chúng, hãy khám phá thư mục mô-đun.

Các Tính năng Nâng cao

Tích hợp TorchVision

Mô-đun TorchVision cho phép tích hợp liền mạch bất kỳ mô hình TorchVision nào làm xương sống:

from ultralytics import YOLO

# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)
backbone:
  - [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, False]]
head:
  - [-1, 1, Classify, [nc]]

Phân Tích Chi Tiết Tham Số:

  • 768: Số lượng kênh đầu ra dự kiến
  • convnext_tiny: Kiến trúc mô hình (các mô hình có sẵn)
  • DEFAULT: Sử dụng các trọng số đã được huấn luyện trước
  • True: Loại bỏ lớp phân loại
  • 2: Cắt bớt 2 lớp cuối cùng
  • False: Trả về một tensor duy nhất (không phải danh sách)

Các Đặc Trưng Đa Tỷ Lệ

Đặt tham số cuối cùng thành True để lấy các bản đồ đặc trưng trung gian cho việc phát hiện đa tỷ lệ.

Mô-đun Index để Lựa chọn Tính năng

Khi sử dụng các mô hình xuất ra nhiều bản đồ đặc trưng, mô-đun 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 Mô-đun

Hiểu cách Ultralytics định vị và nhập các mô-đun là rất quan trọng để tùy chỉnh:

Quy trình Tra cứu Mô-đun

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]
  1. các mô-đun PyTorch: Các tên bắt đầu bằng 'nn.'torch.nn namespace
  2. Các hoạt động của TorchVision: Các tên bắt đầu bằng 'ops.'torchvision.ops namespace
  3. Các mô-đun Ultralytics: Tất cả các tên khác → namespace toàn cục thông qua nhập

Chuỗi Nhập Mô-đun

Các mô-đun tiêu chuẩn trở nên khả dụng thông qua nhập trong tasks.py:

from ultralytics.nn.modules import (  # noqa: F401, E501
    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 mô-đun tùy chỉnh của bạn, nhưng nó có thể phức tạp. Để xác định và sử dụng một mô-đun tùy chỉnh, hãy làm theo các bước sau:

  1. Cài đặt Ultralytics ở chế độ phát triển bằng phương pháp Git clone từ hướng dẫn Bắt đầu nhanh.

  2. Định nghĩa mô-đun 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 mô-đun của bạn ở cấp gói trong ultralytics/nn/modules/__init__.py:

    from .block import CustomBlock  # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
    
  4. Thêm vào nhập 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 mô-đun trong tệp 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 chuyển tiếp 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ụ

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 chứng minh 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 dần thay vì xây dựng từ đầu.

Kiểm tra tăng dần: Xác thực từng bước sửa đổi. Thêm một mô-đun 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.

Giám sát các kênh: Đả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: Tận dụng khả năng sử dụng lại tính năng với [[-1, N], 1, Concat, [1]] các mẫu. Các kết nối này giúp ích cho luồng gradient và cho phép mô hình kết hợp các tính năng từ các tỷ lệ khác nhau.

Điều chỉnh tỷ lệ phù hợp: Chọn tỷ lệ 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ị biên, small (s) để có hiệu suất cân bằng và các tỷ lệ lớn hơn (m, l, x) để có độ chính xác tối đa.

Cân nhắc về hiệu suất

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

Kết nối tắt: Cải thiện luồng gradient trong quá trình huấn luyện và cho phép sử dụng lại tính năng trong 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 gradient biến mất.

Khối thắt nút cổ chai: 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 mô-đun 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 duy trì khả năng học các đặc trưng.

Các đặc trưng đa tỷ lệ: 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 mẫu Mạng kim tự tháp đặc trưng (FPN) với nhiều đầu dò tìm ở các tỷ lệ 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 tasks.py imports
Kích thước kênh không khớp Thông số args không chính xác Kiểm tra tính tương thích của kênh đầu vào/đầu ra
AttributeError: 'int' object has no attribute Sai kiểu dữ liệu của tham số Kiểm tra tài liệu của module để biết kiểu dữ liệu tham số chính xác
Mô hình không xây dựng được Tham chiếu from không hợp lệ Đảm bảo các layer đượ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, 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

Kiểm tra số lượng FLOPs và in ra từng layer 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ó thể 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

  1. Bắt đầu tối giản: 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 layer một
  3. Kiểm tra kích thước: Xác minh tính tương thích về kích thước kênh và không gian
  4. Xác thực tỷ lệ: Kiểm tra với các tỷ lệ mô hình khác nhau (n, s, m)

Câu hỏi thường gặp

Làm cách nào để thay đổi số lượng lớp (class) trong mô hình của tôi?

Đặt thông số nc ở đầu tệp YAML của bạn để khớp với số lượng lớp của bộ dữ liệu.

nc: 5 # 5 classes

Tôi có thể sử dụng backbone tùy chỉnh trong tệp YAML mô hình của mình không?

Có. Bạn có thể sử dụng bất kỳ mô-đun nào được hỗ trợ, bao gồm cả backbone TorchVision, hoặc xác định mô-đun tùy chỉnh của riêng bạn và nhập nó như được mô tả trong Tích hợp Mô-đun Tùy chỉnh.

Làm cách nào để điều chỉnh mô hình của tôi cho các kích thước khác nhau (nano, small, medium, v.v.)?

Sử dụng scales phần trong YAML của bạn để xác định các hệ số tỷ lệ cho độ sâu, chiều rộng và số 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 tỷ lệ được thêm vào tên tệp (ví dụ: yolo11n.yaml).

Định dạng [from, repeats, module, args] có nghĩa là gì?

Định dạng này chỉ định cách mỗi layer được xây dựng:

  • from: (các) nguồn đầu vào
  • repeats: số lần lặp lại mô-đun
  • module: loại lớp
  • args: các đối số cho mô-đun

Làm cách nào để khắc phục lỗi không khớp kênh (channel mismatch)?

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 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 có sẵn và các đối số của chúng ở đâu?

Kiểm tra mã nguồn trong ultralytics/nn/modules thư mục cho tất cả các mô-đun có sẵn và các đố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?

Xác định mô-đun của bạn trong mã nguồn, nhập nó như được hiển thị trong Sửa đổi Mã nguồn, và tham chiếu nó bằng tên trong tệp YAML của bạn.

Tôi có thể sử dụng các trọng số (weight) đã được huấn luyện trước với YAML tùy chỉnh không?

Có, bạn có thể sử dụng model.load("path/to/weights") để tải trọng số từ một checkpoint đã được huấn luyện trước. Tuy nhiên, chỉ những trọng số cho các lớp phù hợp mới 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. 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 đề xuất trong Mẹo gỡ lỗi để tìm ra vấn đề.



📅 Được tạo cách đây 21 ngày ✏️ Đã cập nhật cách đây 8 ngày

Bình luận