Skip to content

Set DaD's subpixel_temp default to 0.15 - #21

Open
f-dy wants to merge 1 commit into
Parskatt:mainfrom
f-dy:fix/subpixel-temperature-default
Open

f-dy wants to merge 1 commit into
Parskatt:mainfrom
f-dy:fix/subpixel-temperature-default

Conversation

@f-dy

@f-dy f-dy commented Sep 29, 2026

Copy link
Copy Markdown

The change

Closes #20.

 class DaD(DeDoDeDetector):
     ...
-        subpixel_temp=0.5,
+        subpixel_temp=0.15,

 def load_DaD(
     ...
-    subpixel_temp=0.5,
+    subpixel_temp=0.15,

dad/detectors/dedode_detector.py, the DaD class default and load_DaD. Inference-only: loss.py:141,153
pass subpixel=False, so no retraining, no weight change, and it reverts by editing one number.
load_DaDLight and load_DaDDark are left at 0.5, since I have only measured the default weights.

Evidence

T = 0.15, where T is the soft-argmax temperature subpixel_temp, was chosen by sweeping T: every value from
T = 0.1 to T = 0.2 beat T = 0.5 on HPatches, and a sweep
on MegaDepth scene 0015 picked T = 0.15, which was also the best on the held-out scene 0022.

It was then checked with a paired comparison: each pair matched once, both temperatures scored on that
warp with identical RANSAC permutations. The harness first reproduces your Tables 2–6 at 512 keypoints
under RoMa v1 (58.07 / 64.82 / 50.70 / 26.23 / 19.01 against 58.2 / 64.9 / 50.6 / 25.7 / 18.3).

RoMa v1 is loaded as your benchmarks load it; RoMa v2 (RoMaV2(), default precise setting) is passed to
the same benchmark code in its place. Both use the same match_keypoints, which only pairs keypoints and
returns the detector's own coordinates, so v2 raises the absolute AUC without moving any keypoint, and
each change below is measured within one matcher.

matcher benchmark 512 1024 2048
RoMa v1 HPatches 58.73 (+0.48) 60.40 (+0.00) 60.98 (+0.02)
MegaDepth E 65.66 (+0.73) 68.43 (+0.48) 69.45 (+0.27)
MegaDepth F 50.98 (+0.39) 55.53 (+0.31) 58.05 (+0.58)
RoMa v2 HPatches 59.48 (+0.31) 61.71 (+0.08) 62.06 (+0.19)
MegaDepth E 65.20 (+0.34) 68.59 (+0.43) 69.27 (+0.12)
MegaDepth F 52.48 (+0.53) 56.33 (+0.13) 58.42 (−0.31)
ScanNet E 29.85 (+0.32) 31.94 (+0.04) 32.90 (−0.09)
ScanNet F 22.28 (+0.28) 25.63 (−0.34) 27.41 (−0.28)

Each cell is the AUC at T = 0.15, with the change from T = 0.5 in brackets. Bold marks a change clearly
larger than the benchmark's noise, which is roughly ±0.3 to ±0.5 AUC here; the rest are within it.

Ahead at 512 on all eight rows; no row clearly worse at any budget.

Why T = 0.15

Modelling the logits around a peak as l(x) = c − (x − d)² / (2s²), with s the peak width in scoremap
pixels, the soft-argmax's best temperature is T = 0.342/s². That equals T = 0.342·|D2|, where
D2 = l(−1) − 2l(0) + l(1) is the second difference at the peak, and DaD's median |D2|, measured over
147k keypoints on 36 HPatches, MegaDepth and ScanNet images, is 0.49 (so s = 1/√0.49 ≈ 1.43 px), giving T = 0.166; the per-keypoint residual against HPatches' true homographies, with no
matcher or RANSAC, is minimised at T = 0.171. The benchmarks can't separate values between about T = 0.1 and T = 0.2;
none of them prefers T = 0.5.

Not included

A clamped separable parabola, a clamped 2D quadratic fit and a per-keypoint temperature were tested on the
same harness. They tie T = 0.15 at 512 keypoints, and each regresses at 1024 where T = 0.15 does not: the per-keypoint
temperature and the 2D fit on ScanNet F, the separable fit on HPatches. So they are not worth the code.

Also adjacent: sample_keypoints divides by the temperature without subtracting the patch max
(dad/utils.py:179). Harmless in float32 at T = 0.15, but a one-line robustness fix if you want it.

@f-dy
f-dy marked this pull request as ready for review September 29, 2026 07:09
@Parskatt

Copy link
Copy Markdown
Owner

Seems to still be a few negative results. Keeping default for now.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subpixel_temp=0.5 looks too high: T = 0.15 is better at 512 keypoints and no worse up to 2048

2 participants