Files
ModelTrainEval/tests/test_target_encoder.py
T
Shaun ZhouandClaude Opus 5 d6adea5b05 test: 单元测试与端到端冒烟
88 个测试覆盖配置继承、注册表、GPU 守卫、YOLO 格式解析、数据集、模型形状、
标签模式、聚类原语与 SimCLR 损失,以及 train.py / eval.py / 聚类脚本的入口接线。

含两条回归测试:
- PCA 白化放大噪声方向导致簇塌陷(默认 whiten=False 的依据)
- classes 写成 data.yaml 路径时 num_classes 必须是类别数而非路径字符串长度

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 17:55:47 +08:00

43 lines
1.4 KiB
Python

import pytest
pytest.importorskip("numpy")
pytest.importorskip("torch")
import numpy as np # noqa: E402
from datasets.target_encoder import CenterTargetEncoder, gaussian_radius # noqa: E402
def test_gaussian_radius_is_positive_and_scales():
assert gaussian_radius(40, 40) > gaussian_radius(10, 10) > 0
def test_encoder_marks_single_center():
encoder = CenterTargetEncoder(num_classes=3, stride=4)
boxes = np.array([[40.0, 40.0, 80.0, 80.0]])
labels = np.array([1])
target = encoder(boxes, labels, (256, 256))
assert target["heatmap"].shape == (3, 64, 64)
assert target["mask"].sum() == 1
# 中心 (60, 60) / stride 4 = (15, 15)
assert target["mask"][15, 15] == 1
assert target["heatmap"][1].max() == pytest.approx(1.0)
assert target["heatmap"][0].max() == 0
assert target["wh"][:, 15, 15].tolist() == pytest.approx([10.0, 10.0])
def test_encoder_skips_invalid_and_out_of_range_boxes():
encoder = CenterTargetEncoder(num_classes=2, stride=4)
boxes = np.array([[10.0, 10.0, 5.0, 5.0], [900.0, 900.0, 950.0, 950.0]])
target = encoder(boxes, np.array([0, 1]), (256, 256))
assert target["mask"].sum() == 0
def test_encoder_respects_max_objects():
encoder = CenterTargetEncoder(num_classes=1, stride=4, max_objects=2)
boxes = np.array([[i * 20.0, 0.0, i * 20.0 + 16, 16.0] for i in range(5)])
target = encoder(boxes, np.zeros(5, dtype=np.int64), (256, 256))
assert target["mask"].sum() == 2