def test_ssim(device, shape, kernel_size, gaussian, use_sample_covariance): y_pred = torch.rand(shape, device=device) y = y_pred * 0.8 sigma = 1.5 data_range = 1.0 ssim = SSIM(data_range=data_range, sigma=sigma, device=device) ssim.update((y_pred, y)) ignite_ssim = ssim.compute() skimg_pred = y_pred.cpu().numpy() skimg_y = skimg_pred * 0.8 skimg_ssim = ski_ssim( skimg_pred, skimg_y, win_size=kernel_size, sigma=sigma, channel_axis=1, gaussian_weights=gaussian, data_range=data_range, use_sample_covariance=use_sample_covariance, ) assert isinstance(ignite_ssim, float) assert np.allclose(ignite_ssim, skimg_ssim, atol=7e-5)
def _test_distrib_accumulator_device(device): metric_devices = [torch.device("cpu")] if torch.device(device).type != "xla": metric_devices.append(idist.device()) for metric_device in metric_devices: ssim = SSIM(data_range=1.0, device=metric_device) for dev in [ssim._device, ssim._kernel.device]: assert dev == metric_device, f"{type(dev)}:{dev} vs {type(metric_device)}:{metric_device}" y_pred = torch.rand(2, 3, 28, 28, dtype=torch.float, device=device) y = y_pred * 0.65 ssim.update((y_pred, y)) dev = ssim._sum_of_batchwise_ssim.device assert dev == metric_device, f"{type(dev)}:{dev} vs {type(metric_device)}:{metric_device}"
def test_ssim(): device = "cuda" if torch.cuda.is_available() else "cpu" ssim = SSIM(data_range=1.0, device=device) y_pred = torch.rand(16, 3, 64, 64, device=device) y = y_pred * 0.65 ssim.update((y_pred, y)) np_pred = y_pred.permute(0, 2, 3, 1).cpu().numpy() np_y = np_pred * 0.65 np_ssim = ski_ssim(np_pred, np_y, win_size=11, multichannel=True, gaussian_weights=True, data_range=1.0) assert isinstance(ssim.compute(), torch.Tensor) assert torch.allclose(ssim.compute(), torch.tensor(np_ssim, dtype=torch.float64, device=device), atol=1e-4) device = "cuda" if torch.cuda.is_available() else "cpu" ssim = SSIM(data_range=1.0, gaussian=False, kernel_size=7, device=device) y_pred = torch.rand(16, 3, 227, 227, device=device) y = y_pred * 0.65 ssim.update((y_pred, y)) np_pred = y_pred.permute(0, 2, 3, 1).cpu().numpy() np_y = np_pred * 0.65 np_ssim = ski_ssim(np_pred, np_y, win_size=7, multichannel=True, gaussian_weights=False, data_range=1.0) assert isinstance(ssim.compute(), torch.Tensor) assert torch.allclose(ssim.compute(), torch.tensor(np_ssim, dtype=torch.float64, device=device), atol=1e-4)
def test_invalid_ssim(): y_pred = torch.rand(16, 1, 32, 32) y = y_pred + 0.125 with pytest.raises( ValueError, match=r"Expected kernel_size to have odd positive number. Got 10." ): ssim = SSIM(data_range=1.0, kernel_size=10) ssim.update((y_pred, y)) ssim.compute() with pytest.raises( ValueError, match=r"Expected kernel_size to have odd positive number. Got -1." ): ssim = SSIM(data_range=1.0, kernel_size=-1) ssim.update((y_pred, y)) ssim.compute() with pytest.raises( ValueError, match= r"Argument kernel_size should be either int or a sequence of int." ): ssim = SSIM(data_range=1.0, kernel_size=1.0) ssim.update((y_pred, y)) ssim.compute() with pytest.raises( ValueError, match= r"Argument sigma should be either float or a sequence of float."): ssim = SSIM(data_range=1.0, sigma=-1) ssim.update((y_pred, y)) ssim.compute() with pytest.raises( ValueError, match= r"Argument sigma should be either float or a sequence of float."): ssim = SSIM(data_range=1.0, sigma=1) ssim.update((y_pred, y)) ssim.compute()
def _test_ssim(y_pred, y, data_range, kernel_size, sigma, gaussian, use_sample_covariance, device): atol = 7e-5 ssim = SSIM(data_range=data_range, sigma=sigma, device=device) ssim.update((y_pred, y)) ignite_ssim = ssim.compute() skimg_pred = y_pred.cpu().numpy() skimg_y = skimg_pred * 0.8 skimg_ssim = ski_ssim( skimg_pred, skimg_y, win_size=kernel_size, sigma=sigma, channel_axis=1, gaussian_weights=gaussian, data_range=data_range, use_sample_covariance=use_sample_covariance, ) assert isinstance(ignite_ssim, torch.Tensor) assert ignite_ssim.dtype == torch.float64 assert ignite_ssim.device == torch.device(device) assert np.allclose(ignite_ssim.cpu().numpy(), skimg_ssim, atol=atol)
def _test_distrib_accumulator_device(device): metric_devices = [torch.device("cpu")] if torch.device(device).type != "xla": metric_devices.append(idist.device()) for metric_device in metric_devices: ssim = SSIM(data_range=1.0, device=metric_device) assert ssim._device == metric_device assert ssim._kernel.device == metric_device, "{}:{} vs {}:{}".format( type(ssim._kernel.device), ssim._kernel.device, type(metric_device), metric_device ) y_pred = torch.rand(2, 3, 28, 28, dtype=torch.float, device=device) y = y_pred * 0.65 ssim.update((y_pred, y)) assert ssim._sum_of_batchwise_ssim.device == metric_device, "{}:{} vs {}:{}".format( type(ssim._sum_of_batchwise_ssim.device), ssim._sum_of_batchwise_ssim.device, type(metric_device), metric_device, )
def test_ssim_variable_batchsize(): # Checks https://github.com/pytorch/ignite/issues/2532 sigma = 1.5 data_range = 1.0 ssim = SSIM(data_range=data_range, sigma=sigma) y_preds = [ torch.rand(12, 3, 28, 28), torch.rand(12, 3, 28, 28), torch.rand(8, 3, 28, 28), torch.rand(16, 3, 28, 28), torch.rand(1, 3, 28, 28), torch.rand(30, 3, 28, 28), ] y_true = [v * 0.8 for v in y_preds] for y_pred, y in zip(y_preds, y_true): ssim.update((y_pred, y)) out = ssim.compute() ssim.reset() ssim.update((torch.cat(y_preds), torch.cat(y_true))) expected = ssim.compute() assert np.allclose(out, expected)
def test_invalid_ssim(): y_pred = torch.rand(1, 1, 4, 4) y = y_pred + 0.125 with pytest.raises(ValueError, match=r"Expected kernel_size to have odd positive number."): ssim = SSIM(data_range=1.0, kernel_size=2) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Expected kernel_size to have odd positive number."): ssim = SSIM(data_range=1.0, kernel_size=-1) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Argument kernel_size should be either int or a sequence of int."): ssim = SSIM(data_range=1.0, kernel_size=1.0) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Argument sigma should be either float or a sequence of float."): ssim = SSIM(data_range=1.0, sigma=-1) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Expected sigma to have positive number."): ssim = SSIM(data_range=1.0, sigma=(-1, -1)) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Argument sigma should be either float or a sequence of float."): ssim = SSIM(data_range=1.0, sigma=1) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Expected y_pred and y to have the same shape."): y = y.squeeze(dim=0) ssim = SSIM(data_range=1.0) ssim.update((y_pred, y)) ssim.compute() with pytest.raises(ValueError, match=r"Expected y_pred and y to have BxCxHxW shape."): y = y.squeeze(dim=0) ssim = SSIM(data_range=1.0) ssim.update((y, y)) ssim.compute() with pytest.raises(TypeError, match=r"Expected y_pred and y to have the same data type."): y = y.double() ssim = SSIM(data_range=1.0) ssim.update((y_pred, y)) ssim.compute()
def SSIM_(y_cap, y): ssim = SSIM(data_range=1.0) ssim.update([y_cap, y]) return ssim.compute().item()