def test_gmi(): """ Testing computed global mutual information between images using image.global_mutual_information by comparing to precomputed. """ # fixed non trival value t1 = np.array(range(108)).reshape((4, 3, 3, 3, 1)) / 108.0 t1 = tf.convert_to_tensor(t1, dtype=tf.float32) t2 = t1 + 0.05 get = image.global_mutual_information(t1, t2) expect = tf.constant( [0.84280217, 0.84347117, 0.8441777, 0.8128618], dtype=tf.float32 ) assert is_equal_tf(get, expect) # zero values t1 = tf.zeros((4, 3, 3, 3, 1), dtype=tf.float32) t2 = t1 get = image.global_mutual_information(t1, t2) expect = tf.constant([0, 0, 0, 0], dtype=tf.float32) assert is_equal_tf(get, expect) # zero value and negative value t1 = tf.zeros((4, 3, 3, 3, 1), dtype=tf.float32) t2 = t1 - 1.0 # will be clipped to zero get = image.global_mutual_information(t1, t2) expect = tf.constant([0, 0, 0, 0], dtype=tf.float32) assert is_equal_tf(get, expect) # one values t1 = tf.ones((4, 3, 3, 3, 1), dtype=tf.float32) t2 = t1 get = image.global_mutual_information(t1, t2) expect = tf.constant([0, 0, 0, 0], dtype=tf.float32) assert is_equal_tf(get, expect)
def test_init_GlobalNet(): """ Testing init of GlobalNet is built as expected. """ # Initialising GlobalNet instance global_test = g.GlobalNet( image_size=[1, 2, 3], out_channels=3, num_channel_initial=3, extract_levels=[1, 2, 3], out_kernel_initializer="softmax", out_activation="softmax", ) # Asserting initialised var for extract_levels is the same - Pass assert global_test._extract_levels == [1, 2, 3] # Asserting initialised var for extract_max_level is the same - Pass assert global_test._extract_max_level == 3 # self reference grid # assert global_test.reference_grid correct shape, Pass assert global_test.reference_grid.shape == [1, 2, 3, 3] # assert correct reference grid returned, Pass expected_ref_grid = tf.convert_to_tensor( [[ [[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 0.0, 2.0]], [[0.0, 1.0, 0.0], [0.0, 1.0, 1.0], [0.0, 1.0, 2.0]], ]], dtype=tf.float32, ) assert is_equal_tf(global_test.reference_grid, expected_ref_grid) # Testing constant initializer # We initialize the expected tensor and initialise another from the # class variable using tf.Variable test_tensor_return = tf.convert_to_tensor( [[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [0.0, 0.0], [0.0, 0.0], [1.0, 0.0]], dtype=tf.float32, ) global_return = tf.Variable( global_test.transform_initial(shape=[6, 2], dtype=tf.float32)) # Asserting they are equal - Pass assert is_equal_tf(test_tensor_return, tf.convert_to_tensor(global_return, dtype=tf.float32)) # Assert downsample blocks type is correct, Pass assert all( isinstance(item, layer.DownSampleResnetBlock) for item in global_test._downsample_blocks) # Assert number of downsample blocks is correct (== max level), Pass assert len(global_test._downsample_blocks) == 3 # Assert conv3dBlock type is correct, Pass assert isinstance(global_test._conv3d_block, layer.Conv3dBlock) # Asserting type is dense_layer, Pass assert isinstance(global_test._dense_layer, layer.Dense)
def test_call(self, y_true, y_pred, binary, scales, expected): expected = np.array([expected] * self.shape[0]) # call returns (batch, ) got = label.JaccardIndex(binary=binary, scales=scales).call(y_true=y_true, y_pred=y_pred) assert is_equal_tf(got, expected) got = label.JaccardLoss(binary=binary, scales=scales).call(y_true=y_true, y_pred=y_pred) assert is_equal_tf(got, -expected)
def test_call(self, y_true, y_pred, binary, neg_weight, scales, expected): expected = np.array([expected] * self.shape[0]) # call returns (batch, ) got = label.DiceScore(binary=binary, neg_weight=neg_weight, scales=scales).call(y_true=y_true, y_pred=y_pred) assert is_equal_tf(got, expected) got = label.DiceLoss(binary=binary, neg_weight=neg_weight, scales=scales).call(y_true=y_true, y_pred=y_pred) assert is_equal_tf(got, -expected)
def test_pyramid_combinations(): """ Test pyramid_combinations by confirming that it generates appropriate solutions for simple 1D and 2D cases. """ # Check numerical outputs are correct for a simple 1D pair of weights, values - Pass weights = tf.constant(np.array([[0.2]], dtype=np.float32)) values = tf.constant(np.array([[1], [2]], dtype=np.float32)) # expected = 1 * 0.2 + 2 * 2 expected = tf.constant(np.array([1.8], dtype=np.float32)) got = layer_util.pyramid_combination(values=values, weights=weights) assert is_equal_tf(got, expected) # Check numerical outputs are correct for a 2D pair of weights, values - Pass weights = tf.constant(np.array([[0.2], [0.3]], dtype=np.float32)) values = tf.constant( np.array( [ [1], # value at corner (0, 0), weight = 0.2 * 0.3 [2], # value at corner (0, 1), weight = 0.2 * 0.7 [3], # value at corner (1, 0), weight = 0.8 * 0.3 [4], # value at corner (1, 1), weight = 0.8 * 0.7 ], dtype=np.float32, ) ) # expected = 1 * 0.2 * 0.3 # + 2 * 0.2 * 0.7 # + 3 * 0.8 * 0.3 # + 4 * 0.8 * 0.7 expected = tf.constant(np.array([3.3], dtype=np.float32)) got = layer_util.pyramid_combination(values=values, weights=weights) assert is_equal_tf(got, expected) # Check input lengths match - Fail weights = tf.constant(np.array([[[0.2]], [[0.2]]], dtype=np.float32)) values = tf.constant(np.array([[1], [2]], dtype=np.float32)) with pytest.raises(ValueError) as err_info: layer_util.pyramid_combination(values=values, weights=weights) assert ( "In pyramid_combination, elements of values and weights should have same dimension" in str(err_info.value) ) # Check input lengths match - Fail weights = tf.constant(np.array([[0.2]], dtype=np.float32)) values = tf.constant(np.array([[1]], dtype=np.float32)) with pytest.raises(ValueError) as err_info: layer_util.pyramid_combination(values=values, weights=weights) assert ( "In pyramid_combination, num_dim = len(weights), len(values) must be 2 ** num_dim" in str(err_info.value) )
def test_dissimilarity_fn(): """ Testing computed dissimilarity function by comparing to precomputed, the dissimilarity function can be either normalized cross correlation or sum square error function. """ # lncc diff images tensor_true = np.array(range(12)).reshape((2, 1, 2, 3)) tensor_pred = 0.6 * np.ones((2, 1, 2, 3)) tensor_true = tf.convert_to_tensor(tensor_true, dtype=tf.float32) tensor_pred = tf.convert_to_tensor(tensor_pred, dtype=tf.float32) name_ncc = "lncc" get_ncc = image.dissimilarity_fn(tensor_true, tensor_pred, name_ncc) expect_ncc = [-0.68002254, -0.9608879] assert is_equal_tf(get_ncc, expect_ncc) # ssd diff images tensor_true1 = np.zeros((2, 1, 2, 3)) tensor_pred1 = 0.6 * np.ones((2, 1, 2, 3)) tensor_true1 = tf.convert_to_tensor(tensor_true1, dtype=tf.float32) tensor_pred1 = tf.convert_to_tensor(tensor_pred1, dtype=tf.float32) name_ssd = "ssd" get_ssd = image.dissimilarity_fn(tensor_true1, tensor_pred1, name_ssd) expect_ssd = [0.36, 0.36] assert is_equal_tf(get_ssd, expect_ssd) # TODO gmi diff images # lncc same image get_zero_similarity_ncc = image.dissimilarity_fn( tensor_pred1, tensor_pred1, name_ncc ) assert is_equal_tf(get_zero_similarity_ncc, [-1, -1]) # ssd same image get_zero_similarity_ssd = image.dissimilarity_fn( tensor_true1, tensor_true1, name_ssd ) assert is_equal_tf(get_zero_similarity_ssd, [0, 0]) # gmi same image t = tf.ones([4, 3, 3, 3]) get_zero_similarity_gmi = image.dissimilarity_fn(t, t, "gmi") assert is_equal_tf(get_zero_similarity_gmi, [0, 0, 0, 0]) # unknown func name with pytest.raises(AssertionError): image.dissimilarity_fn( tensor_true1, tensor_pred1, "some random string that isn't ssd or lncc" )
def test_compute_gradient_norm(): """test the calculation of l1/l2 norm for image gradients""" # l1 norm tensor = tf.ones([4, 50, 50, 50, 3]) get = deform.compute_gradient_norm(tensor, l1=True) expect = tf.zeros([4]) assert is_equal_tf(get, expect) # l2 norm tensor = tf.ones([4, 50, 50, 50, 3]) get = deform.compute_gradient_norm(tensor) expect = tf.zeros([4]) assert is_equal_tf(get, expect)
def test_non_identical(self): theta = tf.constant( np.array( [ [ [0.86, 0.75, 0.48], [0.07, 0.98, 0.01], [0.72, 0.52, 0.97], [0.12, 0.4, 0.04], ] ], dtype=np.float32, ) ) # shape = (1, 4, 3) expected = tf.constant( np.array( [ [ [ [[0.12, 0.4, 0.04], [0.84, 0.92, 1.01], [1.56, 1.44, 1.98]], [[0.19, 1.38, 0.05], [0.91, 1.9, 1.02], [1.63, 2.42, 1.99]], ] ] ], dtype=np.float32, ) ) # shape = (1, 1, 2, 3, 3) got = layer_util.warp_grid(grid=self.grid, theta=theta) assert is_equal_tf(got, expected)
def test_dice_general(): """ Testing general dice function with non binary features and checking against precomputed tensor. """ array_eye = 0.6 * np.identity(3, dtype=np.float32) tensor_eye = np.zeros((3, 3, 3, 3), dtype=np.float32) tensor_eye[:, :, 0:3, 0:3] = array_eye tensor_eye = tf.convert_to_tensor(tensor_eye, dtype=tf.float32) tensor_pred = np.zeros((3, 3, 3, 3), dtype=np.float32) tensor_pred[:, 0:2, :, :] = array_eye tensor_pred = tf.convert_to_tensor(tensor_pred, dtype=tf.float32) y_prod = np.sum(tensor_eye * tensor_pred, axis=(1, 2, 3)) y_sum = np.sum(tensor_eye, axis=(1, 2, 3)) + np.sum(tensor_pred, axis=(1, 2, 3)) num = 2 * y_prod den = y_sum expect = num / den get = label.dice_score_generalized(tensor_eye, tensor_pred) assert is_equal_tf(get, expect)
def test_random_transform_generator(): """ Test random_transform_generator by confirming that it generates appropriate solutions and output sizes for seeded examples. """ # Check shapes are correct Batch Size = 1 - Pass batch_size = 1 transforms = deepreg.dataset.preprocess.gen_rand_affine_transform( batch_size, 0) assert transforms.shape == (batch_size, 4, 3) # Check numerical outputs are correct for a given seed - Pass batch_size = 1 scale = 0.1 seed = 0 expected = tf.constant( np.array( [[ [9.4661278e-01, -3.8267835e-03, 3.6934228e-03], [5.5613145e-03, 9.8034811e-01, -1.8044969e-02], [1.9651605e-04, 1.4576728e-02, 9.6243286e-01], [-2.5107686e-03, 1.9579126e-02, -1.2195010e-02], ]], dtype=np.float32, )) # shape = (1, 4, 3) got = deepreg.dataset.preprocess.gen_rand_affine_transform( batch_size=batch_size, scale=scale, seed=seed) assert is_equal_tf(got, expected)
def test_warp_grid(): """ Test warp_grid by confirming that it generates appropriate solutions for a simple precomputed case. """ grid = tf.constant( np.array( [[[[0, 0, 0], [0, 0, 1], [0, 0, 2]], [[0, 1, 0], [0, 1, 1], [0, 1, 2]]]], dtype=np.float32, )) # shape = (1, 2, 3, 3) theta = tf.constant( np.array( [[ [0.86, 0.75, 0.48], [0.07, 0.98, 0.01], [0.72, 0.52, 0.97], [0.12, 0.4, 0.04], ]], dtype=np.float32, )) # shape = (1, 4, 3) expected = tf.constant( np.array( [[[ [[0.12, 0.4, 0.04], [0.84, 0.92, 1.01], [1.56, 1.44, 1.98]], [[0.19, 1.38, 0.05], [0.91, 1.9, 1.02], [1.63, 2.42, 1.99]], ]]], dtype=np.float32, )) # shape = (1, 1, 2, 3, 3) got = layer_util.warp_grid(grid=grid, theta=theta) assert is_equal_tf(got, expected)
def test_smooth( self, value: float, smooth_nr: float, smooth_dr: float, expected: float, ): """ Test values in extreme cases where variances are all zero. :param value: value for input. :param smooth_nr: constant for numerator. :param smooth_dr: constant for denominator. :param expected: target value. """ kernel_size = 5 mid = kernel_size // 2 shape = (1, kernel_size, kernel_size, kernel_size, 1) y_true = tf.ones(shape=shape) * value y_pred = tf.ones(shape=shape) * value got = image.LocalNormalizedCrossCorrelation( kernel_size=kernel_size, smooth_nr=smooth_nr, smooth_dr=smooth_dr, ).calc_ncc( y_true, y_pred, ) got = got[0, mid, mid, mid, 0] expected = tf.constant(expected) assert is_equal_tf(got, expected)
def test_output(self, y_true, y_pred, expected): """ Testing computed global mutual information between images using image.global_mutual_information by comparing to precomputed. """ got = image.global_mutual_information(y_true=y_true, y_pred=y_pred) assert is_equal_tf(got, expected, atol=1.0e-6)
def test_call(self, l1): tensor = tf.ones([4, 50, 50, 50, 3]) got = deform.GradientNorm(l1=l1)(tensor) expected = tf.zeros([ 4, ]) assert is_equal_tf(got, expected)
def test_smooth( self, value: float, smooth_nr: float, smooth_dr: float, expected: float, ): """ Test values in extreme cases where numerator/denominator are all zero. :param value: value for input. :param smooth_nr: constant for numerator. :param smooth_dr: constant for denominator. :param expected: target value. """ shape = (1, 10) y_true = tf.ones(shape=shape) * value y_pred = tf.ones(shape=shape) * value got = label.DiceScore(smooth_nr=smooth_nr, smooth_dr=smooth_dr).call( y_true, y_pred, ) expected = tf.constant(expected) assert is_equal_tf(got[0], expected)
def testcall(self, y_true, y_pred, binary, background_weight, expected): expected = np.array([expected] * self.shape[0]) # call returns (batch, ) got = label.CrossEntropy( binary=binary, background_weight=background_weight, ).call(y_true=y_true, y_pred=y_pred) assert is_equal_tf(got, expected)
def test_output(self, y_true, y_pred, kernel_type, expected): """ Testing computed local normalized cross correlation function by comparing the output to expected. """ got = image.local_normalized_cross_correlation( y_true, y_pred, kernel_type=kernel_type ) assert is_equal_tf(got, expected)
def test_bending_energy(): """test the calculation of bending energy""" tensor = tf.ones([4, 50, 50, 50, 3]) got = deform.BendingEnergy()(tensor) expected = tf.zeros([ 4, ]) assert is_equal_tf(got, expected)
def test_output(self, y_true, y_pred, expected): """ Testing ssd function (sum of squared differences) by comparing the output to expected. """ got = image.ssd( y_true, y_pred, ) assert is_equal_tf(got, expected)
def test_zero_info(self, y_true, y_pred, shape, expected): y_true = y_true * np.ones(shape=shape) y_pred = y_pred * np.ones(shape=shape) expected = expected * np.ones(shape=(shape[0], )) got = image.GlobalMutualInformation().call( y_true, y_pred, ) assert is_equal_tf(got, expected)
def test_output(self, y_true, y_pred, shape, expected): y_true = y_true * np.ones(shape=shape) y_pred = y_pred * np.ones(shape=shape) expected = expected * np.ones(shape=(shape[0], )) got = image.SumSquaredDifference().call( y_true, y_pred, ) assert is_equal_tf(got, expected)
def test_rectangular_kernel1d(kernel_size): """ Testing the 1-D rectangular kernel :param kernel_size: int :return: """ expected = tf.ones(shape=(kernel_size, ), dtype=tf.float32) got = rectangular_kernel1d(kernel_size) assert is_equal_tf(got, expected)
def test_ssd(): """ Testing computed sum squared error function between images using image.ssd by comparing to precomputed. """ tensor_true = 0.3 * np.array(range(108)).reshape((2, 3, 3, 3, 2)) tensor_pred = 0.1 * np.ones((2, 3, 3, 3, 2)) tensor_pred[:, :, :, :, :] = 1 get = image.ssd(tensor_true, tensor_pred) expect = [70.165, 557.785] assert is_equal_tf(get, expect)
def test_negative_loss_mixin(): """Test DiceScore and DiceLoss have reversed sign.""" shape = (2, 3, 4, 5) y_true = tf.random.uniform(shape=shape) y_pred = tf.random.uniform(shape=shape) dice_score = DiceScore().call(y_pred=y_pred, y_true=y_true) dice_loss = DiceLoss().call(y_pred=y_pred, y_true=y_true) assert is_equal_tf(dice_score, -dice_loss)
def test_gradient_dxyz(): """test the calculation of gradient of a 3D images along xyz-axis""" # gradient_dx tensor = tf.ones([4, 50, 50, 50, 3]) get = deform.gradient_dxyz(tensor, deform.gradient_dx) expect = tf.zeros([4, 48, 48, 48, 3]) assert is_equal_tf(get, expect) # gradient_dy tensor = tf.ones([4, 50, 50, 50, 3]) get = deform.gradient_dxyz(tensor, deform.gradient_dy) expect = tf.zeros([4, 48, 48, 48, 3]) assert is_equal_tf(get, expect) # gradient_dz tensor = tf.ones([4, 50, 50, 50, 3]) get = deform.gradient_dxyz(tensor, deform.gradient_dz) expect = tf.zeros([4, 48, 48, 48, 3]) assert is_equal_tf(get, expect)
def test_1d(self): weights = tf.constant(np.array([[0.2]], dtype=np.float32)) values = tf.constant(np.array([[1], [2]], dtype=np.float32)) # expected = 1 * 0.2 + 2 * 2 expected = tf.constant(np.array([1.8], dtype=np.float32)) got = layer_util.pyramid_combination(values=values, weight_floor=weights, weight_ceil=1 - weights) assert is_equal_tf(got, expected)
def test_zero_info(self, y_true, y_pred, shape, kernel_type, expected): y_true = y_true * tf.ones(shape=shape) y_pred = y_pred * tf.ones(shape=shape) expected = expected * tf.ones(shape=(shape[0], )) got = image.LocalNormalizedCrossCorrelation( kernel_type=kernel_type).call( y_true, y_pred, ) assert is_equal_tf(got, expected)
def test_cauchy_kernel1d(sigma): """ Testing the 1-D cauchy kernel :param sigma: float :return: """ tail = int(sigma * 5) expected = [1 / ((x / sigma)**2 + 1) for x in range(-tail, tail + 1)] expected = expected / np.sum(expected) got = cauchy_kernel1d(sigma) assert is_equal_tf(got, expected)
def test_local_normalized_cross_correlation(): """ Testing computed local normalized cross correlation function between images using image.local_normalized_cross_correlation by comparing to precomputed. """ tensor_true = np.array(range(24)).reshape((2, 1, 2, 3, 2)) tensor_pred = 0.6 * np.ones((2, 1, 2, 3, 2)) expect = [0.7281439, 0.9847701] get = image.local_normalized_cross_correlation( tensor_true, tensor_pred, kernel_size=9 ) assert is_equal_tf(get, expect)
def test_gaussian_kernel1d_sigma(sigma): """ Testing the 1-D gaussian kernel given sigma as input :param sigma: float :return: """ tail = int(sigma * 3) expected = [np.exp(-0.5 * x**2 / sigma**2) for x in range(-tail, tail + 1)] expected = expected / np.sum(expected) got = gaussian_kernel1d_sigma(sigma) assert is_equal_tf(got, expected)