Files
Test_AI/parse_results.py

200 lines
7.8 KiB
Python
Raw Permalink Normal View History

"""
解析验证结果并生成对比报告
"""
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()