|
26 | 26 | [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 7, "kernel_type": "rectangular"}, ["pred", "target"]], |
27 | 27 | [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 5, "kernel_type": "triangular"}, ["pred", "target"]], |
28 | 28 | [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 3, "kernel_type": "gaussian"}, ["pred", "target"]], |
| 29 | + [LocalNormalizedCrossCorrelationLoss, {"kernel_size": 7, "kernel_type": "gaussian"}, ["pred", "target"]], |
29 | 30 | [GlobalMutualInformationLoss, {"num_bins": 10}, ["pred", "target"]], |
30 | 31 | [GlobalMutualInformationLoss, {"kernel_type": "b-spline", "num_bins": 10}, ["pred", "target"]], |
31 | 32 | ] |
@@ -98,6 +99,23 @@ def forward(self, x): |
98 | 99 | optimizer.step() |
99 | 100 | self.assertGreater(init_loss, loss_val, "loss did not decrease") |
100 | 101 |
|
| 102 | +def test_lncc_gaussian_kernel_gt3_identical_images(self): |
| 103 | + """ |
| 104 | + Regression test for make_gaussian_kernel truncated parameter bug. |
| 105 | + LNCC on identical inputs must be close to -1.0 for gaussian kernel_size > 3. |
| 106 | + """ |
| 107 | + for kernel_size in [5, 7]: |
| 108 | + with self.subTest(kernel_size=kernel_size): |
| 109 | + loss_fn = LocalNormalizedCrossCorrelationLoss( |
| 110 | + spatial_dims=2, kernel_size=kernel_size, kernel_type="gaussian" |
| 111 | + ).to(self.device) |
| 112 | + x = torch.rand(2, 1, 32, 32, device=self.device) |
| 113 | + y = x.clone() |
| 114 | + loss = loss_fn(x, y) |
| 115 | + self.assertTrue( |
| 116 | + torch.allclose(loss, torch.tensor(-1.0, device=self.device, dtype=loss.dtype), atol=1e-3), |
| 117 | + f"LNCC of identical images should be -1.0, got {loss.item():.6f} (kernel_size={kernel_size})", |
| 118 | + ) |
101 | 119 |
|
102 | 120 | if __name__ == "__main__": |
103 | 121 | unittest.main() |
0 commit comments