| |
| """ |
| 测试脚本:验证V2数据准备流程 |
| 包括DAD整合和annotation enhancement |
| """ |
|
|
| import json |
| import pickle |
| from pathlib import Path |
| from collections import Counter |
| import sys |
|
|
|
|
| def test_annotation_enhancement(): |
| """测试annotation enhancement结果""" |
| print("=" * 70) |
| print("1. 测试 Annotation Enhancement") |
| print("=" * 70) |
| |
| enhanced_count = 0 |
| total_count = 0 |
| |
| |
| dada_root = Path("PROJECT_ROOT/data/dataset/pretrain/DADA-2000") |
| if dada_root.exists(): |
| for anno_file in list(dada_root.rglob("annotation.json"))[:10]: |
| with open(anno_file) as f: |
| data = json.load(f) |
| |
| total_count += 1 |
| if data.get("annotation_enhanced", False): |
| enhanced_count += 1 |
| print(f"\n✓ 已增强案例:") |
| print(f" 原始: {data.get('accident_type_original', 'N/A')}") |
| print(f" 增强: {data.get('accident_type', 'N/A')[:80]}...") |
| |
| if total_count > 0: |
| print(f"\n抽查结果: {enhanced_count}/{total_count} 被增强 ({enhanced_count/total_count*100:.1f}%)") |
| else: |
| print("\n⚠️ 未找到DADA-2000数据或annotation未增强") |
| |
| return total_count > 0 |
|
|
|
|
| def test_dad_extraction(): |
| """测试DAD帧提取""" |
| print("\n" + "=" * 70) |
| print("2. 测试 DAD数据提取") |
| print("=" * 70) |
| |
| dad_frames_dir = Path("PROJECT_ROOT/data/dataset/pretrain/dad_frames") |
| |
| if not dad_frames_dir.exists(): |
| print("❌ DAD frames目录不存在") |
| print("请运行: python prepare_pretrain_data_v2.py") |
| return False |
| |
| |
| dad_cases = list(dad_frames_dir.iterdir()) |
| positive = [c for c in dad_cases if "positive" in c.name] |
| negative = [c for c in dad_cases if "negative" in c.name] |
| |
| print(f"\n✓ DAD cases总数: {len(dad_cases)}") |
| print(f" Positive: {len(positive)}") |
| print(f" Negative: {len(negative)}") |
| |
| |
| if len(dad_cases) > 0: |
| sample_case = dad_cases[0] |
| frames = list(sample_case.glob("*.jpg")) |
| anno_file = sample_case / "annotation.json" |
| |
| print(f"\n示例case: {sample_case.name}") |
| print(f" 帧数: {len(frames)}") |
| |
| if anno_file.exists(): |
| with open(anno_file) as f: |
| anno = json.load(f) |
| print(f" 标注:") |
| print(f" accident: {anno.get('accident')}") |
| print(f" accident_type: {anno.get('accident_type')}") |
| print(f" fps: {anno.get('fps')}") |
| else: |
| print(" ⚠️ annotation.json不存在") |
| |
| return len(dad_cases) > 0 |
|
|
|
|
| def test_data_preparation(): |
| """测试完整数据准备""" |
| print("\n" + "=" * 70) |
| print("3. 测试 完整数据准备") |
| print("=" * 70) |
| |
| data_file = Path("PROJECT_ROOT/data/dataset/pretrain/train/pretrain_data_v2.pkl") |
| summary_file = Path("PROJECT_ROOT/data/dataset/pretrain/train/pretrain_summary_v2.json") |
| |
| |
| if not data_file.exists(): |
| print(f"❌ 数据文件不存在: {data_file}") |
| print("请运行: python prepare_pretrain_data_v2.py") |
| return False |
| |
| print(f"✓ 数据文件: {data_file}") |
| |
| |
| with open(data_file, "rb") as f: |
| data = pickle.load(f) |
| |
| |
| required_splits = ["train", "val", "test"] |
| for split in required_splits: |
| if split not in data: |
| print(f"❌ 缺少split: {split}") |
| return False |
| |
| print("✓ 数据结构正确") |
| |
| |
| print("\n" + "-" * 70) |
| print("数据统计:") |
| print("-" * 70) |
| |
| for split in required_splits: |
| split_data = data[split] |
| |
| n_cases = split_data.get("total_cases", 0) |
| n_task1 = len(split_data.get("task1_scene_understanding", [])) |
| n_task2 = len(split_data.get("task2_binary_detection", [])) |
| n_task3 = len(split_data.get("task3_accident_description", [])) |
| n_task4 = len(split_data.get("task4_sequence_prediction", [])) |
| |
| print(f"\n{split.upper()}: {n_cases} cases") |
| print(f" 任务1 (场景理解): {n_task1}") |
| print(f" 任务2 (二分类): {n_task2}") |
| print(f" 任务3 (事故描述): {n_task3}") |
| print(f" 任务4 (序列预测): {n_task4}") |
| print(f" ─────────────────────") |
| print(f" 总样本: {n_task1 + n_task2 + n_task3 + n_task4}") |
| |
| |
| print("\n" + "-" * 70) |
| print("数据集来源分布 (训练集):") |
| print("-" * 70) |
| |
| dataset_counts = Counter() |
| for task_name in ["task1_scene_understanding", "task2_binary_detection", |
| "task3_accident_description", "task4_sequence_prediction"]: |
| for sample in data["train"].get(task_name, []): |
| dataset_counts[sample["metadata"]["dataset"]] += 1 |
| |
| for dataset, count in dataset_counts.items(): |
| print(f" {dataset}: {count} 样本") |
| |
| |
| if "dad" in dataset_counts: |
| total = sum(dataset_counts.values()) |
| dad_ratio = dataset_counts["dad"] / total * 100 |
| print(f"\n✓ DAD数据占比: {dad_ratio:.1f}%") |
| else: |
| print("\n⚠️ 未检测到DAD数据") |
| |
| |
| print("\n" + "-" * 70) |
| print("难度分布 (训练集):") |
| print("-" * 70) |
| |
| difficulty_counts = Counter() |
| for task_name in ["task1_scene_understanding", "task2_binary_detection", |
| "task3_accident_description", "task4_sequence_prediction"]: |
| for sample in data["train"].get(task_name, []): |
| difficulty_counts[sample.get("difficulty", "unknown")] += 1 |
| |
| for diff, count in difficulty_counts.items(): |
| total = sum(difficulty_counts.values()) |
| print(f" {diff}: {count} ({count/total*100:.1f}%)") |
| |
| |
| print("\n" + "-" * 70) |
| print("样本示例:") |
| print("-" * 70) |
| |
| |
| task1_samples = data["train"]["task1_scene_understanding"][:2] |
| print("\n任务1 - 场景理解:") |
| for i, s in enumerate(task1_samples, 1): |
| print(f" 样本{i}:") |
| print(f" 难度: {s['difficulty']}") |
| print(f" 标签: {s['label']}") |
| |
| |
| task2_samples = data["train"]["task2_binary_detection"][:2] |
| print("\n任务2 - 二分类:") |
| for i, s in enumerate(task2_samples, 1): |
| print(f" 样本{i}:") |
| print(f" 难度: {s['difficulty']}") |
| print(f" 标签: {s['label']}") |
| print(f" 正样本: {s['metadata']['is_positive']}") |
| |
| |
| task3_samples = data["train"]["task3_accident_description"][:1] |
| if task3_samples: |
| print("\n任务3 - 事故描述:") |
| s = task3_samples[0] |
| print(f" 难度: {s['difficulty']}") |
| print(f" 标签: {s['label'][:80]}...") |
| print(f" 增强标注: {s['metadata'].get('was_enhanced', False)}") |
| |
| |
| task4_samples = data["train"]["task4_sequence_prediction"][:1] |
| if task4_samples: |
| print("\n任务4 - 序列预测:") |
| s = task4_samples[0] |
| print(f" 难度: {s['difficulty']}") |
| print(f" 序列长度: {s['metadata']['sequence_length']}") |
| print(f" 标签: {s['label'][:80]}...") |
| |
| return True |
|
|
|
|
| def main(): |
| """主测试流程""" |
| print("\n" + "=" * 70) |
| print("LKAlert预训练数据准备 - 测试脚本 V2") |
| print("=" * 70) |
| |
| results = {} |
| |
| |
| results["annotation"] = test_annotation_enhancement() |
| |
| |
| results["dad"] = test_dad_extraction() |
| |
| |
| results["data_prep"] = test_data_preparation() |
| |
| |
| print("\n" + "=" * 70) |
| print("测试总结") |
| print("=" * 70) |
| |
| all_passed = all(results.values()) |
| |
| if all_passed: |
| print("✅ 所有测试通过!") |
| print("\n准备就绪,可以开始训练:") |
| print(" bash run_pretrain_v2.sh qwen2.5-vl-3b") |
| else: |
| print("❌ 部分测试失败:") |
| for test_name, passed in results.items(): |
| status = "✓" if passed else "✗" |
| print(f" {status} {test_name}") |
| |
| print("\n请按照提示修复问题") |
| |
| return all_passed |
|
|
|
|
| if __name__ == "__main__": |
| success = main() |
| sys.exit(0 if success else 1) |
|
|