16031aae96
CPU tests Workflow / Testing (ubuntu-latest, 3.12) (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.13) (push) Failing after 0s
Mypy Type Check / Type Check (push) Failing after 0s
Docs/Test WorkFlow / Test docs build (push) Failing after 1s
PR Conflict Labeler / labeling (push) Failing after 1s
Dependency resolution / Resolve [tflite] extra — Python 3.12 (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.10) (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.13) (push) Failing after 1s
CPU tests Workflow / build-pkg (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.10) (push) Failing after 0s
CPU tests Workflow / Testing (ubuntu-latest, 3.11) (push) Failing after 0s
Smoke Tests / try-all-models (macos-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (macos-latest, 3.13) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / testing-guardian (push) Has been cancelled
GPU tests Workflow / Testing (push) Has been cancelled
113 lines
4.7 KiB
Python
113 lines
4.7 KiB
Python
# ------------------------------------------------------------------------
|
|
# RF-DETR
|
|
# Copyright (c) 2025 Roboflow. All Rights Reserved.
|
|
# Licensed under the Apache License, Version 2.0 [see LICENSE for details]
|
|
# ------------------------------------------------------------------------
|
|
"""Regression tests for keypoint config defaults and namespace forwarding."""
|
|
|
|
import pytest
|
|
|
|
from rfdetr._namespace import _namespace_from_configs
|
|
from rfdetr.config import (
|
|
KeypointTrainConfig,
|
|
RFDETRBaseConfig,
|
|
RFDETRKeypointPreviewConfig,
|
|
SegmentationTrainConfig,
|
|
)
|
|
|
|
|
|
def test_keypoint_config_defaults() -> None:
|
|
"""Default model/train keypoint configuration values should match the preview contract."""
|
|
model = RFDETRKeypointPreviewConfig()
|
|
train = KeypointTrainConfig(dataset_dir="/tmp")
|
|
|
|
assert model.use_grouppose_keypoints is True
|
|
assert model.dual_projector is True
|
|
assert model.dual_projector_kp_only is True
|
|
assert model.num_keypoints_per_class == [17]
|
|
assert model.positional_encoding_size == 576 // 12
|
|
|
|
assert train.keypoint_l1_loss_coef == pytest.approx(1.0)
|
|
assert train.keypoint_findable_loss_coef == pytest.approx(1.0)
|
|
assert train.keypoint_visible_loss_coef == pytest.approx(1.0)
|
|
assert train.keypoint_nll_loss_coef == pytest.approx(1.0)
|
|
assert train.cls_loss_coef == pytest.approx(2.0)
|
|
|
|
|
|
def test_keypoint_preview_config_person_schema() -> None:
|
|
"""Person-keypoint preview config must expose a person-only schema."""
|
|
model = RFDETRKeypointPreviewConfig()
|
|
|
|
assert model.num_keypoints_per_class == [17]
|
|
assert sum(model.num_keypoints_per_class) == 17
|
|
assert model.out_feature_indexes == [3, 6, 9, 12]
|
|
assert model.num_windows == 2
|
|
assert model.dec_layers == 4
|
|
assert model.patch_size == 12
|
|
assert model.resolution == 576
|
|
assert model.pretrain_weights == "rf-detr-keypoint-preview-xlarge.pth"
|
|
|
|
|
|
def test_keypoint_fields_propagate_to_namespace(tmp_path) -> None:
|
|
"""All keypoint config fields are forwarded through _namespace_from_configs."""
|
|
model = RFDETRKeypointPreviewConfig()
|
|
train = KeypointTrainConfig(
|
|
dataset_dir=str(tmp_path),
|
|
keypoint_flip_pairs=[0, 1, 2, 3],
|
|
keypoint_l1_loss_coef=1.5,
|
|
keypoint_findable_loss_coef=2.5,
|
|
keypoint_visible_loss_coef=3.5,
|
|
keypoint_nll_loss_coef=4.5,
|
|
)
|
|
|
|
namespace = _namespace_from_configs(model, train)
|
|
|
|
assert namespace.use_grouppose_keypoints is True
|
|
assert namespace.keypoint_cross_attn is True
|
|
assert namespace.inter_instance_kp_attn is False
|
|
assert namespace.grouppose_keypoint_dim_downscale == 1
|
|
assert namespace.dual_projector is True
|
|
assert namespace.dual_projector_kp_only is True
|
|
assert namespace.num_keypoints_per_class == [17]
|
|
assert namespace.keypoint_flip_pairs == [0, 1, 2, 3]
|
|
assert namespace.keypoint_l1_loss_coef == pytest.approx(1.5)
|
|
assert namespace.keypoint_findable_loss_coef == pytest.approx(2.5)
|
|
assert namespace.keypoint_visible_loss_coef == pytest.approx(3.5)
|
|
assert namespace.keypoint_nll_loss_coef == pytest.approx(4.5)
|
|
|
|
|
|
def test_keypoint_nll_loss_coef_default_restored_to_1_0() -> None:
|
|
"""keypoint_nll_loss_coef must default to 1.0 after the 0.5 revert.
|
|
|
|
The 0.5 default was introduced to dampen OKS@75 oscillation. It was later reverted to 1.0 to align with all other
|
|
keypoint loss terms (l1, findable, visible). This test guards against silent regressions.
|
|
"""
|
|
train = KeypointTrainConfig(dataset_dir="/tmp")
|
|
assert train.keypoint_nll_loss_coef == pytest.approx(1.0)
|
|
|
|
|
|
def test_segmentation_train_config_cls_loss_coef_default() -> None:
|
|
"""SegmentationTrainConfig.cls_loss_coef must default to 1.0, not the erroneous 5.0.
|
|
|
|
The 5.0 value was always present in SegmentationTrainConfig but was dead code pre-v1.7 (namespace builder read from
|
|
ModelConfig=1.0). The v1.7 TrainConfig ownership migration silently activated it. This test guards against re-
|
|
introducing that regression.
|
|
"""
|
|
tc = SegmentationTrainConfig(dataset_dir="/tmp")
|
|
assert tc.cls_loss_coef == pytest.approx(1.0)
|
|
|
|
|
|
def test_unknown_keypoint_fields_are_not_public_config_fields() -> None:
|
|
"""Private keypoint implementation fields are not accepted as public model config."""
|
|
with pytest.raises(ValueError, match="Unknown parameter"):
|
|
RFDETRBaseConfig(num_classes=1, keypoint_private_hidden_dim=256)
|
|
|
|
# KeypointTrainConfig (a TrainConfig subclass) uses extra="forbid", so unknown
|
|
# kwargs raise with a helpful message rather than being silently dropped.
|
|
with pytest.raises(ValueError, match="Unknown parameter"):
|
|
KeypointTrainConfig(
|
|
dataset_dir="/tmp",
|
|
keypoint_private_hidden_dim=256,
|
|
keypoint_private_loss_coef=1.0,
|
|
)
|