Files
Test_AI/parse_results.py
16337 942244bd88 Add YOLO11 TensorRT quantization benchmark scripts
- Engine build scripts (FP16/INT8)
- Benchmark validation scripts
- Result parsing and analysis tools
- COCO dataset configuration
2026-01-29 13:59:42 +08:00

200 lines
7.8 KiB
Python

"""
解析验证结果并生成对比报告
"""
import re
import json
from pathlib import Path
from datetime import datetime
import numpy as np
class ResultsParser:
def __init__(self):
self.results_dir = Path("vehicle_person_benchmark")
self.results_dir.mkdir(exist_ok=True)
def parse_file(self, filepath):
"""解析验证结果文件"""
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
content = f.read()
results = {}
# 提取速度信息
speed_match = re.search(r'(\d+\.\d+)ms preprocess.*?(\d+\.\d+)ms inference.*?(\d+\.\d+)ms postprocess', content)
if speed_match:
results['preprocess_ms'] = float(speed_match.group(1))
results['inference_ms'] = float(speed_match.group(2))
results['postprocess_ms'] = float(speed_match.group(3))
# 提取整体AP
ap5095_match = re.search(r'Average Precision.*?IoU=0\.50:0\.95.*?=\s*([\d.]+)', content)
if ap5095_match:
results['mAP50_95'] = float(ap5095_match.group(1))
ap50_match = re.search(r'Average Precision.*?IoU=0\.50\s.*?=\s*([\d.]+)', content)
if ap50_match:
results['mAP50'] = float(ap50_match.group(1))
# 提取Person和Vehicle类别
results['person'] = self._parse_category(content, 'person')
results['car'] = self._parse_category(content, 'car')
results['bicycle'] = self._parse_category(content, 'bicycle')
results['motorcycle'] = self._parse_category(content, 'motorcycle')
results['bus'] = self._parse_category(content, 'bus')
results['truck'] = self._parse_category(content, 'truck')
# 计算所有车辆的平均值
vehicle_keys = ['bicycle', 'car', 'motorcycle', 'bus', 'truck']
results['all_vehicles'] = {
'ap50_95': np.mean([results[k].get('ap50_95', 0) for k in vehicle_keys]),
'ap50': np.mean([results[k].get('ap50', 0) for k in vehicle_keys]),
'P': np.mean([results[k].get('P', 0) for k in vehicle_keys]),
'R': np.mean([results[k].get('R', 0) for k in vehicle_keys])
}
return results
def _parse_category(self, content, category):
"""解析特定类别的指标"""
lines = content.split('\n')
metrics = {}
for i, line in enumerate(lines):
if category in line.lower() and 'Class' not in line and '----' not in line:
parts = line.split()
if len(parts) >= 6:
try:
metrics['P'] = float(parts[2]) if parts[2] != '0' else 0.0
metrics['R'] = float(parts[3]) if parts[3] != '0' else 0.0
metrics['ap50'] = float(parts[4]) if parts[4] != '0' else 0.0
metrics['ap50_95'] = float(parts[5]) if parts[5] != '0' else 0.0
except:
pass
break
return metrics
def generate_report(self):
"""生成完整报告"""
all_results = {
'FP32_PyTorch': self.parse_file('fp32_results.txt'),
'INT8_640p': self.parse_file('int8_640_results.txt'),
'FP16_640p': self.parse_file('fp16_640_results.txt'),
'FP16_480p': self.parse_file('fp16_480_results.txt')
}
report = []
report.append("="*70)
report.append("YOLO11n 人和车辆检测性能对比分析报告")
report.append("="*70)
report.append(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
report.append("")
# 1. 整体性能对比
report.append("-"*70)
report.append("一、整体性能对比")
report.append("-"*70)
report.append(f"{'配置':<15} {'mAP50-95':<12} {'mAP50':<12} {'推理(ms)':<12} {'FPS':<10}")
report.append("-"*70)
for name, data in all_results.items():
map50_95 = data.get('mAP50_95', 0)
map50 = data.get('mAP50', 0)
inf_ms = data.get('inference_ms', 0)
fps = round(1000/inf_ms, 1) if inf_ms > 0 else 0
report.append(f"{name:<15} {map50_95:<12.4f} {map50:<12.4f} {inf_ms:<12.1f} {fps:<10.1f}")
report.append("")
# 2. Person类别
report.append("-"*70)
report.append("二、Person (人) 类别检测性能")
report.append("-"*70)
report.append(f"{'配置':<15} {'P':<10} {'R':<10} {'AP50':<12} {'AP50-95':<12}")
report.append("-"*70)
for name, data in all_results.items():
person = data.get('person', {})
p = person.get('P', 0)
r = person.get('R', 0)
ap50 = person.get('ap50', 0)
ap50_95 = person.get('ap50_95', 0)
report.append(f"{name:<15} {p:<10.3f} {r:<10.3f} {ap50:<12.4f} {ap50_95:<12.4f}")
report.append("")
# 3. Vehicle类别
report.append("-"*70)
report.append("三、Vehicles (车辆) 类别检测性能")
report.append("-"*70)
report.append(f"{'配置':<15} {'P':<10} {'R':<10} {'AP50':<12} {'AP50-95':<12}")
report.append("-"*70)
for name, data in all_results.items():
vehicles = data.get('all_vehicles', {})
p = vehicles.get('P', 0)
r = vehicles.get('R', 0)
ap50 = vehicles.get('ap50', 0)
ap50_95 = vehicles.get('ap50_95', 0)
report.append(f"{name:<15} {p:<10.3f} {r:<10.3f} {ap50:<12.4f} {ap50_95:<12.4f}")
report.append("")
# 4. 速度对比
report.append("-"*70)
report.append("四、推理速度对比")
report.append("-"*70)
speeds = [(name, data.get('inference_ms', 0)) for name, data in all_results.items() if data.get('inference_ms', 0) > 0]
speeds.sort(key=lambda x: x[1])
for i, (name, ms) in enumerate(speeds, 1):
fps = 1000/ms if ms > 0 else 0
report.append(f" {i}. {name}: {ms:.2f}ms ({fps:.1f} FPS)")
report.append("")
# 5. 计算掉点
report.append("-"*70)
report.append("五、精度掉点分析 (相对于FP32)")
report.append("-"*70)
fp32_map = all_results.get('FP32_PyTorch', {}).get('mAP50_95', 0)
for name, data in all_results.items():
if name == 'FP32_PyTorch' or data.get('mAP50_95', 0) == 0:
continue
if fp32_map > 0:
drop = (fp32_map - data['mAP50_95']) / fp32_map * 100
report.append(f" {name}: mAP50-95 掉点 {drop:.2f}%")
report.append("")
# 6. 结论
report.append("="*70)
report.append("六、结论与建议")
report.append("="*70)
report.append("")
report.append("1. 精度最优: 选择 FP16_640p 或 INT8_640p")
report.append("2. 速度最快: 选择 FP16_480p")
report.append("3. 性价比: 推荐 FP16_640p (平衡精度和速度)")
report.append("4. INT8量化在人和车辆检测上表现良好")
report.append("")
# 保存报告
report_text = '\n'.join(report)
report_file = self.results_dir / "final_report.txt"
with open(report_file, 'w', encoding='utf-8') as f:
f.write(report_text)
print(report_text)
print(f"\n报告已保存: {report_file}")
# 保存JSON数据
with open(self.results_dir / "all_results.json", 'w', encoding='utf-8') as f:
json.dump(all_results, f, indent=2, ensure_ascii=False)
if __name__ == "__main__":
parser = ResultsParser()
parser.generate_report()