YOLOv7 : Túi quà tặng có thể huấn luyện
YOLOv7 là một thiết bị phát hiện vật thể thời gian thực tiên tiến, vượt trội hơn tất cả các thiết bị phát hiện vật thể đã biết về cả tốc độ và độ chính xác trong phạm vi từ 5 FPS đến 160 FPS. Thiết bị này có độ chính xác cao nhất (56,8% AP ) trong số tất cả các máy dò vật thể thời gian thực đã biết có 30 FPS trở lên GPU V100. Hơn nữa, YOLOv7 vượt trội hơn các bộ phát hiện đối tượng khác như YOLOR, YOLOX, Scaled-YOLOv4, YOLOv5 và nhiều tính năng khác về tốc độ và độ chính xác. Mô hình được đào tạo trên MS COCO tập dữ liệu từ đầu mà không sử dụng bất kỳ tập dữ liệu nào khác hoặc trọng số được đào tạo trước. Mã nguồn cho YOLOv7 có sẵn trên GitHub.

So sánh các công cụ phát hiện đối tượng SOTA
Từ những kết quả trong YOLO bảng so sánh chúng ta biết rằng phương pháp đề xuất có sự cân bằng tốt nhất về tốc độ và độ chính xác một cách toàn diện. Nếu chúng ta so sánh YOLOv7 -tiny-SiLU với YOLOv5 -N (r6.1), phương pháp của chúng tôi nhanh hơn 127 fps và chính xác hơn 10,7% trên AP . Ngoài ra, YOLOv7 có 51,4% AP ở tốc độ khung hình 161 fps, trong khi PPYOLOE-L có cùng tốc độ AP chỉ có tốc độ khung hình 78 fps. Về mặt sử dụng tham số, YOLOv7 ít hơn 41% so với PPYOLOE-L.
Nếu chúng ta so sánh YOLOv7 -X với tốc độ suy luận 114 fps YOLOv5 -L (r6.1) với tốc độ suy luận 99 fps, YOLOv7 -X có thể cải thiện AP bằng 3,9%. Nếu YOLOv7 -X được so sánh với YOLOv5 -X (r6.1) có quy mô tương tự, tốc độ suy luận của YOLOv7 -X nhanh hơn 31 khung hình/giây. Ngoài ra, xét về số lượng tham số và khả năng tính toán, YOLOv7 -X giảm 22% tham số và 8% tính toán so với YOLOv5 -X (r6.1), nhưng cải thiện AP tăng 2,2% ( Nguồn ).
Hiệu suất
| Mô hình | Tham Số (M) | FLOPs (G) | Kích thước (pixels) | FPS | AP kiểm tra / đánh giá 50-95 | AP Bài kiểm tra 50 | AP Bài kiểm tra 75 | AP Bài kiểm tra S | AP Bài kiểm tra M | AP Bài kiểm tra L |
|---|---|---|---|---|---|---|---|---|---|---|
| YOLOX-S | 9.0 | 26.8 | 640 | 102 | 40.5% / 40.5% | - | - | - | - | - |
| YOLOX-M | 25.3 | 73.8 | 640 | 81 | 47.2% / 46.9% | - | - | - | - | - |
| YOLOX-L | 54.2 | 155.6 | 640 | 69 | 50.1% / 49.7% | - | - | - | - | - |
| YOLOX-X | 99.1 | 281.9 | 640 | 58 | 51.5% / 51.1% | - | - | - | - | - |
| PPYOLOE-S | 7.9 | 17.4 | 640 | 208 | 43.1% / 42.7% | 60.5% | 46.6% | 23.2% | 46.4% | 56.9% |
| PPYOLOE-M | 23.4 | 49.9 | 640 | 123 | 48.9% / 48.6% | 66.5% | 53.0% | 28.6% | 52.9% | 63.8% |
| PPYOLOE-L | 52.2 | 110.1 | 640 | 78 | 51.4% / 50.9% | 68.9% | 55.6% | 31.4% | 55.3% | 66.1% |
| PPYOLOE-X | 98.4 | 206.6 | 640 | 45 | 52.2% / 51.9% | 69.9% | 56.5% | 33.3% | 56.3% | 66.4% |
| YOLOv5-N (r6.1) | 1.9 | 4.5 | 640 | 159 | - / 28.0% | - | - | - | - | - |
| YOLOv5-S (r6.1) | 7.2 | 16.5 | 640 | 156 | - / 37.4% | - | - | - | - | - |
| YOLOv5-M (r6.1) | 21.2 | 49.0 | 640 | 122 | - / 45.4% | - | - | - | - | - |
| YOLOv5-L (r6.1) | 46.5 | 109.1 | 640 | 99 | - / 49.0% | - | - | - | - | - |
| YOLOv5-X (r6.1) | 86.7 | 205.7 | 640 | 83 | - / 50.7% | - | - | - | - | - |
| YOLOR-CSP | 52.9 | 120.4 | 640 | 106 | 51.1% / 50.8% | 69.6% | 55.7% | 31.7% | 55.3% | 64.7% |
| YOLOR-CSP-X | 96.9 | 226.8 | 640 | 87 | 53.0% / 52.7% | 71.4% | 57.9% | 33.7% | 57.1% | 66.8% |
| YOLOv7 -nhỏ-SiLU | 6.2 | 13.8 | 640 | 286 | 38.7% / 38.7% | 56.7% | 41.7% | 18.8% | 42.4% | 51.9% |
| YOLOv7 | 36.9 | 104.7 | 640 | 161 | 51.4% / 51.2% | 69.7% | 55.9% | 31.8% | 55.5% | 65.0% |
| YOLOv7 -X | 71.3 | 189.9 | 640 | 114 | 53.1% / 52.9% | 71.2% | 57.8% | 33.8% | 57.1% | 67.4% |
| YOLOv5-N6 (r6.1) | 3.2 | 18.4 | 1280 | 123 | - / 36.0% | - | - | - | - | - |
| YOLOv5-S6 (r6.1) | 12.6 | 67.2 | 1280 | 122 | - / 44.8% | - | - | - | - | - |
| YOLOv5-M6 (r6.1) | 35.7 | 200.0 | 1280 | 90 | - / 51.3% | - | - | - | - | - |
| YOLOv5-L6 (r6.1) | 76.8 | 445.6 | 1280 | 63 | - / 53.7% | - | - | - | - | - |
| YOLOv5-X6 (r6.1) | 140.7 | 839.2 | 1280 | 38 | - / 55.0% | - | - | - | - | - |
| YOLOR-P6 | 37.2 | 325.6 | 1280 | 76 | 53.9% / 53.5% | 71.4% | 58.9% | 36.1% | 57.7% | 65.6% |
| YOLOR-W6 | 79.8 | 453.2 | 1280 | 66 | 55.2% / 54.8% | 72.7% | 60.5% | 37.7% | 59.1% | 67.1% |
| YOLOR-E6 | 115.8 | 683.2 | 1280 | 45 | 55.8% / 55.7% | 73.4% | 61.1% | 38.4% | 59.7% | 67.7% |
| YOLOR-D6 | 151.7 | 935.6 | 1280 | 34 | 56.5% / 56.1% | 74.1% | 61.9% | 38.9% | 60.4% | 68.7% |
| YOLOv7 -W6 | 70.4 | 360.0 | 1280 | 84 | 54.9% / 54.6% | 72.6% | 60.1% | 37.3% | 58.7% | 67.1% |
| YOLOv7 -E6 | 97.2 | 515.2 | 1280 | 56 | 56.0% / 55.9% | 73.5% | 61.2% | 38.0% | 59.9% | 68.4% |
| YOLOv7 -D6 | 154.7 | 806.8 | 1280 | 44 | 56.6% / 56.3% | 74.0% | 61.8% | 38.8% | 60.1% | 69.5% |
| YOLOv7 -E6E | 151.7 | 843.2 | 1280 | 36 | 56.8% / 56.8% | 74.4% | 62.1% | 39.3% | 60.5% | 69.0% |
Tổng quan
Phát hiện đối tượng thời gian thực là một thành phần quan trọng trong nhiều hệ thống thị giác máy tính , bao gồm theo dõi đa đối tượng , lái xe tự động, robot và phân tích hình ảnh y tế . Trong những năm gần đây, việc phát triển phát hiện đối tượng thời gian thực đã tập trung vào việc thiết kế các kiến trúc hiệu quả và cải thiện tốc độ suy luận của nhiều loại CPU, GPU và bộ xử lý thần kinh (NPU). YOLOv7 hỗ trợ cả điện thoại di động GPU Và GPU các thiết bị, từ biên giới đến đám mây.
Không giống như các bộ phát hiện đối tượng thời gian thực truyền thống tập trung vào tối ưu hóa kiến trúc, YOLOv7 Giới thiệu trọng tâm về việc tối ưu hóa quy trình đào tạo. Điều này bao gồm các mô-đun và phương pháp tối ưu hóa được thiết kế để cải thiện độ chính xác của việc phát hiện đối tượng mà không làm tăng chi phí suy luận, một khái niệm được gọi là "túi quà tặng có thể đào tạo".
Các tính năng chính
YOLOv7 giới thiệu một số tính năng chính:
Tham số hóa lại mô hình : YOLOv7 đề xuất một mô hình tham số hóa lại theo kế hoạch, đây là chiến lược áp dụng cho các lớp trong các mạng khác nhau với khái niệm đường truyền lan truyền theo độ dốc.
Gán nhãn động : Việc đào tạo mô hình với nhiều lớp đầu ra đặt ra một vấn đề mới: "Làm thế nào để gán các mục tiêu động cho đầu ra của các nhánh khác nhau?" Để giải quyết vấn đề này, YOLOv7 giới thiệu phương pháp gán nhãn mới gọi là gán nhãn hướng dẫn từ thô đến tinh.
Mở rộng và hợp chất : YOLOv7 đề xuất các phương pháp "mở rộng" và "phối hợp mở rộng" cho bộ phát hiện đối tượng thời gian thực có thể sử dụng hiệu quả các tham số và phép tính.
Hiệu quả : Phương pháp được đề xuất bởi YOLOv7 có thể giảm hiệu quả khoảng 40% tham số và 50% phép tính của máy dò đối tượng thời gian thực hiện đại, có tốc độ suy luận nhanh hơn và độ chính xác phát hiện cao hơn.
Ví dụ sử dụng
Tính đến thời điểm viết bài này, Ultralytics chỉ hỗ trợ ONNX Và TensorRT suy luận cho YOLOv7 .
Xuất ONNX
Để sử dụng YOLOv7 ONNX mô hình với Ultralytics :
(Tùy chọn) Cài đặt Ultralytics và xuất một mô hình ONNX để tự động cài đặt các phụ thuộc cần thiết:
pip install ultralytics yolo export model=yolo11n.pt format=onnxXuất khẩu mong muốn YOLOv7 mô hình bằng cách sử dụng trình xuất trong kho lưu trữ YOLOv7 :
git clone https://github.com/WongKinYiu/yolov7 cd yolov7 python export.py --weights yolov7-tiny.pt --grid --end2end --simplify --topk-all 100 --iou-thres 0.65 --conf-thres 0.35 --img-size 640 640 --max-wh 640Sửa đổi đồ thị mô hình ONNX để tương thích với Ultralytics bằng script sau:
import numpy as np import onnx from onnx import helper, numpy_helper # Load the ONNX model model_path = "yolov7/yolov7-tiny.onnx" # Replace with your model path model = onnx.load(model_path) graph = model.graph # Fix input shape to batch size 1 input_shape = graph.input[0].type.tensor_type.shape input_shape.dim[0].dim_value = 1 # Define the output of the original model original_output_name = graph.output[0].name # Create slicing nodes sliced_output_name = f"{original_output_name}_sliced" # Define initializers for slicing (remove the first value) start = numpy_helper.from_array(np.array([1], dtype=np.int64), name="slice_start") end = numpy_helper.from_array(np.array([7], dtype=np.int64), name="slice_end") axes = numpy_helper.from_array(np.array([1], dtype=np.int64), name="slice_axes") steps = numpy_helper.from_array(np.array([1], dtype=np.int64), name="slice_steps") graph.initializer.extend([start, end, axes, steps]) slice_node = helper.make_node( "Slice", inputs=[original_output_name, "slice_start", "slice_end", "slice_axes", "slice_steps"], outputs=[sliced_output_name], name="SliceNode", ) graph.node.append(slice_node) # Define segment slicing seg1_start = numpy_helper.from_array(np.array([0], dtype=np.int64), name="seg1_start") seg1_end = numpy_helper.from_array(np.array([4], dtype=np.int64), name="seg1_end") seg2_start = numpy_helper.from_array(np.array([4], dtype=np.int64), name="seg2_start") seg2_end = numpy_helper.from_array(np.array([5], dtype=np.int64), name="seg2_end") seg3_start = numpy_helper.from_array(np.array([5], dtype=np.int64), name="seg3_start") seg3_end = numpy_helper.from_array(np.array([6], dtype=np.int64), name="seg3_end") graph.initializer.extend([seg1_start, seg1_end, seg2_start, seg2_end, seg3_start, seg3_end]) # Create intermediate tensors for segments segment_1_name = f"{sliced_output_name}_segment1" segment_2_name = f"{sliced_output_name}_segment2" segment_3_name = f"{sliced_output_name}_segment3" # Add segment slicing nodes graph.node.extend( [ helper.make_node( "Slice", inputs=[sliced_output_name, "seg1_start", "seg1_end", "slice_axes", "slice_steps"], outputs=[segment_1_name], name="SliceSegment1", ), helper.make_node( "Slice", inputs=[sliced_output_name, "seg2_start", "seg2_end", "slice_axes", "slice_steps"], outputs=[segment_2_name], name="SliceSegment2", ), helper.make_node( "Slice", inputs=[sliced_output_name, "seg3_start", "seg3_end", "slice_axes", "slice_steps"], outputs=[segment_3_name], name="SliceSegment3", ), ] ) # Concatenate the segments concat_output_name = f"{sliced_output_name}_concat" concat_node = helper.make_node( "Concat", inputs=[segment_1_name, segment_3_name, segment_2_name], outputs=[concat_output_name], axis=1, name="ConcatSwapped", ) graph.node.append(concat_node) # Reshape to [1, -1, 6] reshape_shape = numpy_helper.from_array(np.array([1, -1, 6], dtype=np.int64), name="reshape_shape") graph.initializer.append(reshape_shape) final_output_name = f"{concat_output_name}_batched" reshape_node = helper.make_node( "Reshape", inputs=[concat_output_name, "reshape_shape"], outputs=[final_output_name], name="AddBatchDimension", ) graph.node.append(reshape_node) # Get the shape of the reshaped tensor shape_node_name = f"{final_output_name}_shape" shape_node = helper.make_node( "Shape", inputs=[final_output_name], outputs=[shape_node_name], name="GetShapeDim", ) graph.node.append(shape_node) # Extract the second dimension dim_1_index = numpy_helper.from_array(np.array([1], dtype=np.int64), name="dim_1_index") graph.initializer.append(dim_1_index) second_dim_name = f"{final_output_name}_dim1" gather_node = helper.make_node( "Gather", inputs=[shape_node_name, "dim_1_index"], outputs=[second_dim_name], name="GatherSecondDim", ) graph.node.append(gather_node) # Subtract from 100 to determine how many values to pad target_size = numpy_helper.from_array(np.array([100], dtype=np.int64), name="target_size") graph.initializer.append(target_size) pad_size_name = f"{second_dim_name}_padsize" sub_node = helper.make_node( "Sub", inputs=["target_size", second_dim_name], outputs=[pad_size_name], name="CalculatePadSize", ) graph.node.append(sub_node) # Build the [2, 3] pad array: # 1st row -> [0, 0, 0] (no padding at the start of any dim) # 2nd row -> [0, pad_size, 0] (pad only at the end of the second dim) pad_starts = numpy_helper.from_array(np.array([0, 0, 0], dtype=np.int64), name="pad_starts") graph.initializer.append(pad_starts) zero_scalar = numpy_helper.from_array(np.array([0], dtype=np.int64), name="zero_scalar") graph.initializer.append(zero_scalar) pad_ends_name = "pad_ends" concat_pad_ends_node = helper.make_node( "Concat", inputs=["zero_scalar", pad_size_name, "zero_scalar"], outputs=[pad_ends_name], axis=0, name="ConcatPadEnds", ) graph.node.append(concat_pad_ends_node) pad_values_name = "pad_values" concat_pad_node = helper.make_node( "Concat", inputs=["pad_starts", pad_ends_name], outputs=[pad_values_name], axis=0, name="ConcatPadStartsEnds", ) graph.node.append(concat_pad_node) # Create Pad operator to pad with zeros pad_output_name = f"{final_output_name}_padded" pad_constant_value = numpy_helper.from_array( np.array([0.0], dtype=np.float32), name="pad_constant_value", ) graph.initializer.append(pad_constant_value) pad_node = helper.make_node( "Pad", inputs=[final_output_name, pad_values_name, "pad_constant_value"], outputs=[pad_output_name], mode="constant", name="PadToFixedSize", ) graph.node.append(pad_node) # Update the graph's final output to [1, 100, 6] new_output_type = onnx.helper.make_tensor_type_proto( elem_type=graph.output[0].type.tensor_type.elem_type, shape=[1, 100, 6] ) new_output = onnx.helper.make_value_info(name=pad_output_name, type_proto=new_output_type) # Replace the old output with the new one graph.output.pop() graph.output.extend([new_output]) # Save the modified model onnx.save(model, "yolov7-ultralytics.onnx")Sau đó, bạn có thể tải mô hình ONNX đã sửa đổi và chạy suy luận với nó trong Ultralytics một cách bình thường:
from ultralytics import ASSETS, YOLO model = YOLO("yolov7-ultralytics.onnx", task="detect") results = model(ASSETS / "bus.jpg")
Xuất TensorRT
Thực hiện theo các bước 1-2 trong phần Xuất ONNX.
Cài đặt
TensorRTGói Python:pip install tensorrtChạy script sau để chuyển đổi mô hình ONNX đã sửa đổi sang TensorRT engine:
from ultralytics.utils.export import export_engine export_engine("yolov7-ultralytics.onnx", half=True)Tải và chạy mô hình trong Ultralytics:
from ultralytics import ASSETS, YOLO model = YOLO("yolov7-ultralytics.engine", task="detect") results = model(ASSETS / "bus.jpg")
Trích dẫn và Lời cảm ơn
Chúng tôi muốn ghi nhận YOLOv7 các tác giả vì những đóng góp quan trọng của họ trong lĩnh vực phát hiện đối tượng thời gian thực:
@article{wang2022yolov7,
title={YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors},
author={Wang, Chien-Yao and Bochkovskiy, Alexey and Liao, Hong-Yuan Mark},
journal={arXiv preprint arXiv:2207.02696},
year={2022}
}
Bản gốc YOLOv7 Bài báo có thể được tìm thấy trên arXiv . Các tác giả đã công bố công trình của họ và có thể truy cập cơ sở mã nguồn trên GitHub . Chúng tôi đánh giá cao những nỗ lực của họ trong việc thúc đẩy lĩnh vực này và giúp công trình của họ được cộng đồng rộng rãi tiếp cận.
Câu hỏi thường gặp
Là gì YOLOv7 và tại sao nó được coi là bước đột phá trong việc phát hiện vật thể theo thời gian thực?
YOLOv7 là một mô hình phát hiện đối tượng thời gian thực tiên tiến, đạt được tốc độ và độ chính xác vượt trội. Nó vượt trội hơn các mô hình khác, chẳng hạn như YOLOX, YOLOv5 và PPYOLOE, về cả cách sử dụng tham số và tốc độ suy luận. YOLOv7 Các tính năng nổi bật của YOLOv7 .
Làm thế nào YOLOv7 cải thiện trước đó YOLO các mô hình như YOLOv4 và YOLOv5 ?
YOLOv7 giới thiệu một số cải tiến, bao gồm tham số hóa lại mô hình và gán nhãn động, giúp tăng cường quá trình đào tạo và cải thiện độ chính xác suy luận. So với YOLOv5 , YOLOv7 tăng đáng kể tốc độ và độ chính xác. Ví dụ, YOLOv7 -X cải thiện độ chính xác thêm 2,2% và giảm các tham số xuống 22% so với YOLOv5 -X. Có thể tìm thấy những so sánh chi tiết trong bảng hiệu suất so sánh YOLOv7 với các bộ phát hiện đối tượng SOTA .
Tôi có thể sử dụng YOLOv7 với Ultralytics công cụ và nền tảng?
Tính đến thời điểm hiện tại, Ultralytics chỉ hỗ trợ YOLOv7 ONNX Và TensorRT suy luận. Để chạy ONNX Và TensorRT phiên bản xuất khẩu của YOLOv7 với Ultralytics , hãy kiểm tra phần Ví dụ sử dụng .
Làm thế nào để tôi đào tạo một tùy chỉnh YOLOv7 mô hình sử dụng tập dữ liệu của tôi?
Để cài đặt và đào tạo một tùy chỉnh YOLOv7 mô hình, hãy làm theo các bước sau:
- Nhân bản YOLOv7 kho lưu trữ:
git clone https://github.com/WongKinYiu/yolov7 - Điều hướng đến thư mục đã sao chép và cài đặt các зависимость:
cd yolov7 pip install -r requirements.txt Chuẩn bị tập dữ liệu của bạn và cấu hình các tham số mô hình theo hướng dẫn sử dụng được cung cấp trong kho lưu trữ. Để biết thêm hướng dẫn, hãy truy cập YOLOv7 Kho lưu trữ GitHub để biết thông tin và cập nhật mới nhất.
Sau khi huấn luyện, bạn có thể xuất mô hình sang ONNX hoặc TensorRT để sử dụng trong Ultralytics như được hiển thị trong Ví dụ Sử dụng.
Những tính năng và tối ưu hóa chính nào được giới thiệu trong YOLOv7 ?
YOLOv7 cung cấp một số tính năng chính giúp cách mạng hóa việc phát hiện đối tượng theo thời gian thực:
- Tái Tham Số Hóa Mô Hình (Model Re-parameterization): Nâng cao hiệu suất của mô hình bằng cách tối ưu hóa các đường dẫn lan truyền gradient.
- Gán Nhãn Động (Dynamic Label Assignment): Sử dụng phương pháp dẫn dắt từ thô đến tinh để gán các mục tiêu động cho các đầu ra trên các nhánh khác nhau, cải thiện độ chính xác.
- Mở Rộng và Tỉ Lệ Hợp Chất (Extended and Compound Scaling): Sử dụng hiệu quả các tham số và tính toán để масштабирование mô hình cho các ứng dụng thời gian thực khác nhau.
- Hiệu quả: Giảm 40% số lượng tham số và 50% tính toán so với các mô hình hiện đại khác đồng thời đạt được tốc độ suy luận nhanh hơn.
Để biết thêm chi tiết về các tính năng này, hãy xem phần Tổng quan về YOLOv7 .