예제 #1
0
 def _test_for_multiple_io(self, model):
     cam = Xcam(model)
     result = cam([CategoricalScore(0), CategoricalScore(0)],
                  [dummy_sample(
                      (1, 8, 8, 3)), dummy_sample((1, 10, 10, 3))])
     assert result[0].shape == (1, 8, 8)
     assert result[1].shape == (1, 10, 10)
예제 #2
0
 def test__call__(self, model):
     assert model.get_layer(name='output_1').activation != tf.keras.activations.linear
     if len(model.outputs) > 1:
         assert model.get_layer(name='output_2').activation != tf.keras.activations.linear
     instance = ActivationMaximization(model, model_modifier=ReplaceToLinear())
     assert instance.model != model
     assert instance.model.get_layer(name='output_1').activation == tf.keras.activations.linear
     if len(model.outputs) > 1:
         assert instance.model.get_layer(
             name='output_2').activation == tf.keras.activations.linear
         instance([CategoricalScore(0), CategoricalScore(0)])
     else:
         instance([CategoricalScore(0)])
예제 #3
0
class TestXcamWithMultipleOutputsModel():
    @pytest.mark.parametrize("scores,expected_error", [
        (None, ValueError),
        ([None], ValueError),
        (CategoricalScore(0), ValueError),
        ([CategoricalScore(0)], ValueError),
        ([None, None], ValueError),
        ([CategoricalScore(0), None], ValueError),
        ([None, CategoricalScore(0)], ValueError),
        ([CategoricalScore(0), BinaryScore(0)], NO_ERROR),
        ([score_with_tuple, score_with_tuple], NO_ERROR),
        ([score_with_list, score_with_list], NO_ERROR),
    ])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__if_score_is_(self, scores, expected_error, multiple_outputs_model):
        cam = Xcam(multiple_outputs_model)
        with assert_raises(expected_error):
            result = cam(scores, dummy_sample((1, 8, 8, 3)))
            assert result.shape == (1, 8, 8)

    @pytest.mark.parametrize("seed_input,expected,expected_error", [
        (None, None, ValueError),
        (dummy_sample((8, )), None, ValueError),
        (dummy_sample((8, 8, 3)), (1, 8, 8), NO_ERROR),
        ([dummy_sample((8, 8, 3))], [(1, 8, 8)], NO_ERROR),
        (dummy_sample((1, 8, 8, 3)), (1, 8, 8), NO_ERROR),
        ([dummy_sample((1, 8, 8, 3))], [(1, 8, 8)], NO_ERROR),
    ])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__if_seed_input_is_(self, seed_input, expected, expected_error,
                                      multiple_outputs_model):
        cam = Xcam(multiple_outputs_model)
        with assert_raises(expected_error):
            result = cam([CategoricalScore(0), BinaryScore(0)], seed_input)
            if type(expected) is list:
                assert type(result) is list
                expected = expected[0]
                result = result[0]
            assert result.shape == expected

    @pytest.mark.parametrize("expand_cam", [False, True])
    @pytest.mark.usefixtures("xcam", "mixed_precision")
    def test__call__with_expand_cam(self, expand_cam, multiple_outputs_model):
        cam = Xcam(multiple_outputs_model)
        result = cam([CategoricalScore(0), BinaryScore(0)], [dummy_sample((1, 8, 8, 3))],
                     expand_cam=expand_cam)
        if expand_cam:
            assert result[0].shape == (1, 8, 8)
        else:
            assert result.shape == (1, 6, 6)
예제 #4
0
 def test__call__with_expand_cam(self, expand_cam, conv_model):
     cam = Xcam(conv_model)
     result = cam(CategoricalScore(0), [dummy_sample((1, 8, 8, 3))], expand_cam=expand_cam)
     if expand_cam:
         assert result[0].shape == (1, 8, 8)
     else:
         assert result.shape == (1, 6, 6)
예제 #5
0
 def test__call__without_regularization(self, conv_model):
     activation_maximization = ActivationMaximization(conv_model)
     result = activation_maximization(CategoricalScore(1),
                                      steps=1,
                                      regularizers=None,
                                      callbacks=PrintLogger(1))
     assert result.shape == (1, 8, 8, 3)
예제 #6
0
 def test__call__if_max_N_is_(self, max_N, expected_error, conv_model):
     with assert_raises(expected_error):
         cam = Scorecam(conv_model)
         result = cam(CategoricalScore(0),
                      dummy_sample((2, 8, 8, 3)),
                      max_N=max_N)
         assert result.shape == (2, 8, 8)
예제 #7
0
 def test__call__if_activation_modifier_is_(self, activation_modifier,
                                            conv_model):
     cam = GradcamPlusPlus(conv_model)
     result = cam(CategoricalScore(0),
                  dummy_sample((1, 8, 8, 3)),
                  activation_modifier=activation_modifier)
     assert result.shape == (1, 8, 8)
예제 #8
0
class TestXcamWithMultipleInputsModel():
    @pytest.mark.parametrize("scores,expected_error", [
        (None, ValueError),
        (CategoricalScore(0), NO_ERROR),
        (score_with_tuple, NO_ERROR),
        (score_with_list, NO_ERROR),
        ([None], ValueError),
        ([CategoricalScore(0)], NO_ERROR),
        ([score_with_tuple], NO_ERROR),
        ([score_with_list], NO_ERROR),
    ])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__if_score_is_(self, scores, expected_error, multiple_inputs_model):
        cam = Xcam(multiple_inputs_model)
        with assert_raises(expected_error):
            result = cam(scores, [dummy_sample((1, 8, 8, 3)), dummy_sample((1, 10, 10, 3))])
            assert len(result) == 2
            assert result[0].shape == (1, 8, 8)
            assert result[1].shape == (1, 10, 10)

    @pytest.mark.parametrize("seed_input,expected_error", [
        (None, ValueError),
        (dummy_sample((1, 8, 8, 3)), ValueError),
        ([dummy_sample((1, 8, 8, 3))], ValueError),
        ([dummy_sample((1, 8, 8, 3)), dummy_sample((1, 10, 10, 3))], NO_ERROR),
    ])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__if_seed_input_is_(self, seed_input, expected_error, multiple_inputs_model):
        cam = Xcam(multiple_inputs_model)
        with assert_raises(expected_error):
            result = cam(CategoricalScore(0), seed_input)
            assert result[0].shape == (1, 8, 8)
            assert result[1].shape == (1, 10, 10)

    @pytest.mark.parametrize("expand_cam", [False, True])
    @pytest.mark.usefixtures("xcam", "mixed_precision")
    def test__call__with_expand_cam(self, expand_cam, multiple_inputs_model):
        cam = Xcam(multiple_inputs_model)
        result = cam(CategoricalScore(0),
                     [dummy_sample(
                         (1, 8, 8, 3)), dummy_sample((1, 10, 10, 3))],
                     expand_cam=expand_cam)
        if expand_cam:
            assert result[0].shape == (1, 8, 8)
            assert result[1].shape == (1, 10, 10)
        else:
            assert result.shape == (1, 8, 8)
예제 #9
0
 def test__call__(self, tmpdir, conv_model):
     path = tmpdir.mkdir("tf-keras-vis").join("test.gif")
     activation_maximization = ActivationMaximization(conv_model)
     assert not os.path.isfile(path)
     result = activation_maximization(CategoricalScore(0),
                                      callbacks=GifGenerator2D(str(path)))
     assert os.path.isfile(path)
     assert result.shape == (1, 8, 8, 3)
예제 #10
0
 def test__call__with_expand_cam(self, expand_cam, multiple_outputs_model):
     cam = Xcam(multiple_outputs_model)
     result = cam([CategoricalScore(0), BinaryScore(0)], [dummy_sample((1, 8, 8, 3))],
                  expand_cam=expand_cam)
     if expand_cam:
         assert result[0].shape == (1, 8, 8)
     else:
         assert result.shape == (1, 6, 6)
예제 #11
0
 def test__call__(self, model, layer, expected_error):
     assert model.outputs[0].shape.as_list() == [None, 2]
     with assert_raises(expected_error):
         instance = ActivationMaximization(model,
                                           model_modifier=ExtractIntermediateLayer(layer))
         assert instance.model != model
         assert instance.model.outputs[0].shape.as_list() == [None, 6, 6, 6]
         instance([CategoricalScore(0)])
예제 #12
0
 def test__call__(self, conv_model):
     instance = Saliency(conv_model, model_modifier=GuidedBackpropagation())
     guided_model = instance.model
     assert guided_model != conv_model
     assert guided_model.get_layer('conv_1').activation != conv_model.get_layer(
         'conv_1').activation
     assert guided_model.get_layer('dense_1').activation == conv_model.get_layer(
         'dense_1').activation
     instance(CategoricalScore(0), dummy_sample((1, 8, 8, 3)))
예제 #13
0
 def _test_for_multiple_io(self, model):
     saliency = Saliency(model)
     result = saliency(
         [CategoricalScore(0), BinaryScore(0)],
         [dummy_sample((1, 8, 8, 3)),
          dummy_sample((1, 10, 10, 3))])
     assert len(result) == 2
     assert result[0].shape == (1, 8, 8)
     assert result[1].shape == (1, 10, 10)
예제 #14
0
 def test__call__if_seed_input_is_(self, seed_input, expected, expected_error, conv_model):
     cam = Xcam(conv_model)
     with assert_raises(expected_error):
         result = cam(CategoricalScore(0), seed_input)
         if type(expected) is list:
             assert type(result) is list
             expected = expected[0]
             result = result[0]
         assert result.shape == expected
예제 #15
0
 def test__call__if_penultimate_layer_is(self, penultimate_layer, seek_penultimate_conv_layer,
                                         expected_error, conv_model):
     cam = Xcam(conv_model)
     with assert_raises(expected_error):
         result = cam(CategoricalScore(0),
                      dummy_sample((1, 8, 8, 3)),
                      penultimate_layer=penultimate_layer,
                      seek_penultimate_conv_layer=seek_penultimate_conv_layer)
         assert result.shape == (1, 8, 8)
예제 #16
0
 def test__call__if_seed_input_is_(self, seed_input, expected, expected_error,
                                   multiple_outputs_model):
     cam = Xcam(multiple_outputs_model)
     with assert_raises(expected_error):
         result = cam([CategoricalScore(0), BinaryScore(0)], seed_input)
         if type(expected) is list:
             assert type(result) is list
             expected = expected[0]
             result = result[0]
         assert result.shape == expected
예제 #17
0
 def test__call__if_keepdims_is_(self, keepdims, expected,
                                 multiple_inputs_model):
     saliency = Saliency(multiple_inputs_model)
     result = saliency(
         CategoricalScore(0),
         [dummy_sample((1, 8, 8, 3)),
          dummy_sample((1, 10, 10, 3))],
         keepdims=keepdims)
     assert len(result) == 2
     assert result[0].shape == expected[0]
     assert result[1].shape == expected[1]
예제 #18
0
 def test__call__if_smoothing_is_active(self, smooth_samples,
                                        multiple_inputs_model):
     saliency = Saliency(multiple_inputs_model)
     result = saliency(
         CategoricalScore(0),
         [dummy_sample((1, 8, 8, 3)),
          dummy_sample((1, 10, 10, 3))],
         smooth_samples=smooth_samples)
     assert len(result) == 2
     assert result[0].shape == (1, 8, 8)
     assert result[1].shape == (1, 10, 10)
예제 #19
0
 def test__call__with_expand_cam(self, expand_cam, multiple_inputs_model):
     cam = Xcam(multiple_inputs_model)
     result = cam(CategoricalScore(0),
                  [dummy_sample(
                      (1, 8, 8, 3)), dummy_sample((1, 10, 10, 3))],
                  expand_cam=expand_cam)
     if expand_cam:
         assert result[0].shape == (1, 8, 8)
         assert result[1].shape == (1, 10, 10)
     else:
         assert result.shape == (1, 8, 8)
예제 #20
0
    def run(self):
        """Run Worker Thread."""
        # This is the code executing in the new thread.
        with open("Model_definition.pkl", 'rb') as f:
            model_config = pickle.load(f)

        model = tf.keras.models.Model.from_config(model_config)
        model.load_weights("Model_weights.h5")

        wx.CallAfter(pub.sendMessage, "update", msg="Preparing Image")
        # El callback aun no funciona, pero para cuando este disponible. De momento hay 3 saltos, uno que carga el
        # modelo, otro procesa las imagenes y el ultimo ordena y copia.
        my_call = ProgressBar2()
        img_prep = transform_img_fn(self.file)
        img_prep = np.concatenate([img_prep, img_prep])

        if self.info_type == 'SmoothGrad Saliency':
            wx.CallAfter(pub.sendMessage,
                         "update",
                         msg="Obtaining SmoothGrad Saliency")
            replace2linear = ReplaceToLinear()
            score = CategoricalScore([0, 1])
            saliency = Saliency(model,
                                model_modifier=replace2linear,
                                clone=True)
            self.saliency_maps = saliency(score,
                                          img_prep,
                                          smooth_samples=50,
                                          smooth_noise=0.10)

        else:
            wx.CallAfter(pub.sendMessage, "update", msg="Obtaining GradCAM++")
            replace2linear = ReplaceToLinear()
            score = CategoricalScore([0, 1])
            gradcam = GradcamPlusPlus(model,
                                      model_modifier=replace2linear,
                                      clone=True)
            self.gradcam_maps = gradcam(score, img_prep, penultimate_layer=-1)

        wx.CallAfter(pub.sendMessage, "update", msg="")
예제 #21
0
class TestScorecam():
    @pytest.mark.parametrize("max_N,expected_error", [
        (-100, NO_ERROR),
        (-1, NO_ERROR),
        (0, NO_ERROR),
        (1, NO_ERROR),
        (3, NO_ERROR),
        (100, ValueError),
    ])
    @pytest.mark.usefixtures("mixed_precision")
    def test__call__if_max_N_is_(self, max_N, expected_error, conv_model):
        with assert_raises(expected_error):
            cam = Scorecam(conv_model)
            result = cam(CategoricalScore(0),
                         dummy_sample((2, 8, 8, 3)),
                         max_N=max_N)
            assert result.shape == (2, 8, 8)

    @pytest.mark.parametrize("scores,expected_error", [
        (None, ValueError),
        (CategoricalScore(0), NO_ERROR),
        (score_with_tuple, NO_ERROR),
        (score_with_list, NO_ERROR),
        (score_with_tensor, NO_ERROR),
        (lambda x: np.mean(x), ValueError),
        (lambda x: tf.reshape(x, (-1, )), ValueError),
        ([None], ValueError),
        ([CategoricalScore(0)], NO_ERROR),
        ([score_with_tuple], NO_ERROR),
        ([score_with_list], NO_ERROR),
        ([score_with_tensor], NO_ERROR),
        ([lambda x: np.mean(x)], ValueError),
        ([lambda x: tf.reshape(x, (-1, ))], ValueError),
    ])
    @pytest.mark.usefixtures("mixed_precision")
    def test__call__if_score_is_(self, scores, expected_error, conv_model):
        cam = Scorecam(conv_model)
        with assert_raises(expected_error):
            result = cam(scores, dummy_sample((2, 8, 8, 3)))
            assert result.shape == (2, 8, 8)
예제 #22
0
 def test__init__(self, indices, expected, expected_error):
     with assert_raises(expected_error):
         score = CategoricalScore(indices)
         assert score.indices == expected
예제 #23
0
 def test__call__(self, indices, output_shape, expected_error):
     output = tf.constant(dummy_sample(output_shape), tf.float32)
     score = CategoricalScore(indices)
     with assert_raises(expected_error):
         score_value = score(output)
         assert score_value.shape == output_shape[0:1]
예제 #24
0
 def test__call__without_regularizers(self, conv_model):
     activation_maximization = ActivationMaximization(conv_model)
     result = activation_maximization(CategoricalScore(0),
                                      regularizers=None,
                                      callbacks=Progress())
     assert result.shape == (1, 8, 8, 3)
def saliency(img_path, multiclass_model, name):

    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    import scipy.ndimage as ndimage
    from tensorflow.keras.preprocessing.image import load_img
    from tensorflow.keras.applications.densenet import preprocess_input
    import numpy as np

    # Preparing input data for VGG16
    # X = preprocess_input(images)
    # X = 'https://firebasestorage.googleapis.com/v0/b/intelrad-a680a.appspot.com/o/images%2Fxrayyyy.jpg?alt=media&token=63a8460f-5c79-422c-91d6-c5a2704d2383'
    X = img_path
    X = preprocess_image(X)
    # Rendering
    import matplotlib.pyplot as plt

    from tf_keras_vis.scorecam import Scorecam
    from matplotlib import cm
    from tf_keras_vis.gradcam import Gradcam
    from tf_keras_vis.utils.model_modifiers import ReplaceToLinear

    replace2linear = ReplaceToLinear()

    # Create Gradcam object
    gradcam = Gradcam(multiclass_model,
                      model_modifier=replace2linear,
                      clone=True)
    # Instead of using CategoricalScore object,

    from tf_keras_vis.utils.scores import CategoricalScore

    # 1 is the imagenet index corresponding to Goldfish, 294 to Bear and 413 to Assault Rifle.
    score = CategoricalScore(4)
    from tensorflow.keras import backend as K
    from tf_keras_vis.saliency import Saliency
    # from tf_keras_vis.utils import normalize

    # Create Saliency object.
    saliency = Saliency(multiclass_model,
                        model_modifier=replace2linear,
                        clone=True)

    # Generate saliency map
    X = X.tolist()
    X = np.asarray(X, dtype=np.float)
    # saliency_map = saliency(score, X)
    # Generate saliency map with smoothing that reduce noise by adding noise
    saliency_map = saliency(
        score,
        X,
        smooth_samples=20,  # The number of calculating gradients iterations.
        smooth_noise=0.20)  # noise spread level.

    # Generate saliency map
    saliency_map = saliency(score, X)

    # Render
    # f, ax = plt.subplots(nrows=1, ncols=3, figsize=(12, 4))
    plt.figure(figsize=(8, 8))
    plt.imshow(saliency_map[0], cmap='jet', alpha=0.9)
    plt.axis('off')
    import os
    img_dir = './static/img/saliency'
    if (not os.path.isdir(img_dir)):
        os.mkdir(img_dir)

    plt.tight_layout()
    plt.savefig(f'./static/img/saliency/{name}.svg',
                transparent=True,
                bbox_inches='tight',
                pad_inches=0)
    plt.close()

    return "Done"
예제 #26
0
 def test__call__if_expand_cam_is_False(self, conv_model):
     cam = Xcam(conv_model)
     result = cam(CategoricalScore(0), dummy_sample((1, 8, 8, 3)), expand_cam=False)
     assert result.shape == (1, 6, 6)
예제 #27
0
 def test__call__if_seed_input_is_(self, seed_input, expected_error, multiple_io_model):
     cam = Xcam(multiple_io_model)
     with assert_raises(expected_error):
         result = cam([CategoricalScore(0), BinaryScore(0)], seed_input)
         assert result[0].shape == (1, 8, 8)
         assert result[1].shape == (1, 10, 10)
예제 #28
0
 def test__call__(self, dense_model):
     cam = Xcam(dense_model)
     with assert_raises(ValueError):
         result = cam(CategoricalScore(0), dummy_sample((1, 8, 8, 3)))
         assert result.shape == (1, 8, 8)
예제 #29
0
 def _test_for_single_io(self, model):
     cam = Xcam(model)
     result = cam(CategoricalScore(0), dummy_sample((1, 8, 8, 3)))
     assert result.shape == (1, 8, 8)
예제 #30
0
class TestXcam():
    @pytest.mark.parametrize("scores,expected_error", [
        (None, ValueError),
        (CategoricalScore(0), NO_ERROR),
        (score_with_tuple, NO_ERROR),
        (score_with_list, NO_ERROR),
        (score_with_tensor, NO_ERROR),
        ([None], ValueError),
        ([CategoricalScore(0)], NO_ERROR),
        ([score_with_tuple], NO_ERROR),
        ([score_with_list], NO_ERROR),
        ([score_with_tensor], NO_ERROR),
    ])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__if_score_is_(self, scores, expected_error, conv_model):
        cam = Xcam(conv_model)
        with assert_raises(expected_error):
            result = cam(scores, dummy_sample((1, 8, 8, 3)))
            assert result.shape == (1, 8, 8)

    @pytest.mark.parametrize("seed_input,expected,expected_error", [
        (None, None, ValueError),
        (dummy_sample((8, )), None, ValueError),
        (dummy_sample((8, 8, 3)), (1, 8, 8), NO_ERROR),
        ([dummy_sample((8, 8, 3))], [(1, 8, 8)], NO_ERROR),
        (dummy_sample((1, 8, 8, 3)), (1, 8, 8), NO_ERROR),
        ([dummy_sample((1, 8, 8, 3))], [(1, 8, 8)], NO_ERROR),
    ])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__if_seed_input_is_(self, seed_input, expected, expected_error, conv_model):
        cam = Xcam(conv_model)
        with assert_raises(expected_error):
            result = cam(CategoricalScore(0), seed_input)
            if type(expected) is list:
                assert type(result) is list
                expected = expected[0]
                result = result[0]
            assert result.shape == expected

    @pytest.mark.parametrize("penultimate_layer,seek_penultimate_conv_layer,expected_error", [
        (None, True, NO_ERROR),
        (-1, True, NO_ERROR),
        (-1.0, True, ValueError),
        ('dense_1', True, NO_ERROR),
        ('dense_1', False, ValueError),
        (1, False, NO_ERROR),
        (1, True, NO_ERROR),
        ('conv_1', True, NO_ERROR),
        (0, True, ValueError),
        ('input_1', True, ValueError),
        (CategoricalScore(0), True, ValueError),
        (mock_conv_model().layers[-1], False, ValueError),
    ])
    @pytest.mark.usefixtures("xcam", "mixed_precision")
    def test__call__if_penultimate_layer_is(self, penultimate_layer, seek_penultimate_conv_layer,
                                            expected_error, conv_model):
        cam = Xcam(conv_model)
        with assert_raises(expected_error):
            result = cam(CategoricalScore(0),
                         dummy_sample((1, 8, 8, 3)),
                         penultimate_layer=penultimate_layer,
                         seek_penultimate_conv_layer=seek_penultimate_conv_layer)
            assert result.shape == (1, 8, 8)

    @pytest.mark.usefixtures("xcam", "mixed_precision")
    def test__call__if_expand_cam_is_False(self, conv_model):
        cam = Xcam(conv_model)
        result = cam(CategoricalScore(0), dummy_sample((1, 8, 8, 3)), expand_cam=False)
        assert result.shape == (1, 6, 6)

    @pytest.mark.parametrize("score_class", [BinaryScore, CategoricalScore])
    @pytest.mark.parametrize("modifier_enabled", [False, True])
    @pytest.mark.parametrize("clone_enabled", [False, True])
    @pytest.mark.parametrize("batch_size", [0, 1, 5])
    @pytest.mark.usefixtures("xcam", "saliency", "mixed_precision")
    def test__call__with_categorical_score(self, score_class, modifier_enabled, clone_enabled,
                                           batch_size, conv_model, conv_sigmoid_model):
        # Release v.0.6.0@dev(May 22 2021):
        #   Add this case to test Scorecam with CAM class.
        def model_modifier(model):
            model.layers[-1].activation = tf.keras.activations.linear

        if score_class is BinaryScore:
            model = conv_sigmoid_model
        else:
            model = conv_model

        score_targets = np.random.randint(0, 1, max(batch_size, 1))
        score = score_class(list(score_targets))

        seed_input_shape = (8, 8, 3)
        if batch_size > 0:
            seed_input_shape = (batch_size, ) + seed_input_shape
        seed_input = dummy_sample(seed_input_shape)

        cam = Xcam(model,
                   model_modifier=model_modifier if modifier_enabled else None,
                   clone=clone_enabled)
        result = cam(score, seed_input=seed_input)
        if modifier_enabled and clone_enabled:
            assert model is not cam.model
        else:
            assert model is cam.model
        assert result.shape == (max(batch_size, 1), 8, 8)

    @pytest.mark.parametrize("expand_cam", [False, True])
    @pytest.mark.usefixtures("xcam", "mixed_precision")
    def test__call__with_expand_cam(self, expand_cam, conv_model):
        cam = Xcam(conv_model)
        result = cam(CategoricalScore(0), [dummy_sample((1, 8, 8, 3))], expand_cam=expand_cam)
        if expand_cam:
            assert result[0].shape == (1, 8, 8)
        else:
            assert result.shape == (1, 6, 6)