| | """ |
| | 对比YOLOv11 backbone和原始YOLOP backbone的差异 |
| | """ |
| | import sys |
| | import os |
| | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| | sys.path.append(BASE_DIR) |
| |
|
| | import torch |
| | from lib.models.YOLOP_YOLOv11 import YOLOPWithYOLOv11, YOLOv11Backbone |
| | from lib.models.YOLOP import get_net |
| | from lib.config import cfg |
| | from lib.config import update_config |
| |
|
| |
|
| | def count_parameters(model): |
| | """统计参数数量""" |
| | total = sum(p.numel() for p in model.parameters()) |
| | trainable = sum(p.numel() for p in model.parameters() if p.requires_grad) |
| | return total, trainable |
| |
|
| |
|
| | def get_model_size(model): |
| | """估算模型大小(MB)""" |
| | param_size = sum(p.numel() * p.element_size() for p in model.parameters()) |
| | buffer_size = sum(b.numel() * b.element_size() for b in model.buffers()) |
| | size_mb = (param_size + buffer_size) / (1024 ** 2) |
| | return size_mb |
| |
|
| |
|
| | def test_inference_speed(model, input_size=(1, 3, 640, 640), num_runs=100, warmup=10): |
| | """测试推理速度""" |
| | import time |
| | model.eval() |
| | device = next(model.parameters()).device |
| | |
| | |
| | dummy_input = torch.randn(input_size).to(device) |
| | |
| | |
| | with torch.no_grad(): |
| | for _ in range(warmup): |
| | _ = model(dummy_input) |
| | |
| | |
| | torch.cuda.synchronize() if device.type == 'cuda' else None |
| | start_time = time.time() |
| | |
| | with torch.no_grad(): |
| | for _ in range(num_runs): |
| | _ = model(dummy_input) |
| | torch.cuda.synchronize() if device.type == 'cuda' else None |
| | |
| | end_time = time.time() |
| | avg_time = (end_time - start_time) / num_runs * 1000 |
| | fps = 1000 / avg_time |
| | |
| | return avg_time, fps |
| |
|
| |
|
| | def main(): |
| | print("="*80) |
| | print("Backbone Comparison: YOLOv11 vs Original YOLOP") |
| | print("="*80) |
| | |
| | |
| | print("\n1. Creating models...") |
| | |
| | print(" Creating YOLOv11-based YOLOP...") |
| | model_yolov11 = YOLOPWithYOLOv11(num_seg_class=2) |
| | |
| | print(" Creating original YOLOP...") |
| | try: |
| | model_original = get_net(cfg) |
| | except Exception as e: |
| | print(f" Failed to create original YOLOP: {e}") |
| | model_original = None |
| | |
| | print("✓ Models created") |
| | |
| | |
| | print("\n" + "="*80) |
| | print("Parameter Comparison") |
| | print("="*80) |
| | |
| | |
| | yolov11_backbone_params, _ = count_parameters(model_yolov11.backbone) |
| | yolov11_total_params, _ = count_parameters(model_yolov11) |
| | yolov11_size = get_model_size(model_yolov11) |
| | |
| | print("\nYOLOv11-based YOLOP:") |
| | print(f" Backbone parameters: {yolov11_backbone_params:,}") |
| | print(f" Total parameters: {yolov11_total_params:,}") |
| | print(f" Model size: {yolov11_size:.2f} MB") |
| | |
| | if model_original: |
| | original_total_params, _ = count_parameters(model_original) |
| | original_size = get_model_size(model_original) |
| | |
| | print("\nOriginal YOLOP:") |
| | print(f" Total parameters: {original_total_params:,}") |
| | print(f" Model size: {original_size:.2f} MB") |
| | |
| | print("\nDifference:") |
| | param_diff = yolov11_total_params - original_total_params |
| | size_diff = yolov11_size - original_size |
| | print(f" Parameters: {param_diff:+,} ({param_diff/original_total_params*100:+.2f}%)") |
| | print(f" Size: {size_diff:+.2f} MB ({size_diff/original_size*100:+.2f}%)") |
| | |
| | |
| | print("\n" + "="*80) |
| | print("Output Shape Comparison") |
| | print("="*80) |
| | |
| | test_input = torch.randn(1, 3, 640, 640) |
| | |
| | print("\nYOLOv11-based YOLOP:") |
| | with torch.no_grad(): |
| | det_out, da_out, ll_out = model_yolov11(test_input) |
| | print(f" Detection output: {type(det_out)}") |
| | if isinstance(det_out, tuple): |
| | for i, out in enumerate(det_out): |
| | if isinstance(out, list): |
| | print(f" Element {i}: list with {len(out)} items") |
| | for j, item in enumerate(out): |
| | print(f" [{j}] {item.shape}") |
| | else: |
| | print(f" Element {i}: {out.shape}") |
| | print(f" Drivable area output: {da_out.shape}") |
| | print(f" Lane line output: {ll_out.shape}") |
| | |
| | if model_original: |
| | print("\nOriginal YOLOP:") |
| | with torch.no_grad(): |
| | det_out_orig, da_out_orig, ll_out_orig = model_original(test_input) |
| | print(f" Detection output: {type(det_out_orig)}") |
| | if isinstance(det_out_orig, tuple): |
| | for i, out in enumerate(det_out_orig): |
| | if isinstance(out, list): |
| | print(f" Element {i}: list with {len(out)} items") |
| | for j, item in enumerate(out): |
| | print(f" [{j}] {item.shape}") |
| | else: |
| | print(f" Element {i}: {out.shape}") |
| | print(f" Drivable area output: {da_out_orig.shape}") |
| | print(f" Lane line output: {ll_out_orig.shape}") |
| | |
| | |
| | print("\n" + "="*80) |
| | print("Inference Speed Comparison (CPU)") |
| | print("="*80) |
| | |
| | print("\nTesting YOLOv11-based YOLOP...") |
| | try: |
| | avg_time_yolov11, fps_yolov11 = test_inference_speed(model_yolov11, num_runs=50, warmup=5) |
| | print(f" Average time: {avg_time_yolov11:.2f} ms") |
| | print(f" FPS: {fps_yolov11:.2f}") |
| | except Exception as e: |
| | print(f" Failed: {e}") |
| | avg_time_yolov11, fps_yolov11 = None, None |
| | |
| | if model_original: |
| | print("\nTesting original YOLOP...") |
| | try: |
| | avg_time_original, fps_original = test_inference_speed(model_original, num_runs=50, warmup=5) |
| | print(f" Average time: {avg_time_original:.2f} ms") |
| | print(f" FPS: {fps_original:.2f}") |
| | |
| | if avg_time_yolov11 and avg_time_original: |
| | time_diff = avg_time_yolov11 - avg_time_original |
| | print(f"\nSpeed difference: {time_diff:+.2f} ms ({time_diff/avg_time_original*100:+.2f}%)") |
| | except Exception as e: |
| | print(f" Failed: {e}") |
| | |
| | |
| | print("\n" + "="*80) |
| | print("Backbone Architecture Comparison") |
| | print("="*80) |
| | |
| | print("\nYOLOv11 Backbone:") |
| | print(f" Number of layers: {len(model_yolov11.backbone.layers)}") |
| | print(f" Output feature indices: {model_yolov11.backbone.out_indices}") |
| | print(" Layer types:") |
| | for i, layer in enumerate(model_yolov11.backbone.layers): |
| | print(f" [{i:2d}] {type(layer).__name__}") |
| | |
| | if model_original and hasattr(model_original, 'model'): |
| | print("\nOriginal YOLOP Backbone:") |
| | print(f" Number of layers: {len(model_original.model)}") |
| | print(" Layer types (first 10):") |
| | for i in range(min(10, len(model_original.model))): |
| | layer = model_original.model[i] |
| | print(f" [{i:2d}] {type(layer).__name__}") |
| | |
| | |
| | print("\n" + "="*80) |
| | print("Summary") |
| | print("="*80) |
| | print("\nKey differences:") |
| | print(" ✓ YOLOv11 uses newer modules: C3k2, C2PSA, SPPF") |
| | print(" ✓ Original YOLOP uses: Focus, BottleneckCSP, SPP") |
| | print(" ✓ YOLOv11 backbone can be initialized with pre-trained weights") |
| | print(" ✓ Both models have the same output format (compatible with training code)") |
| | |
| | print("\nRecommendations:") |
| | print(" • Use YOLOv11 backbone with pre-trained weights for better initial performance") |
| | print(" • Consider freezing backbone for faster training of detection/segmentation heads") |
| | print(" • Monitor both training speed and accuracy during experiments") |
| |
|
| |
|
| | if __name__ == '__main__': |
| | main() |
| |
|