Example #1
0
    def __call__(self, y: TensorLike) -> TensorLike:

        self._assert_cut_contains_only_one_tensor(y)

        if len(B.int_shape(y)) == 2:
            return sum([y[:, ch] for ch in self._channels])

        elif len(B.int_shape(y)) == 3:
            return sum([self._agg_fn(y[:, :, ch]) for ch in self._channel])

        elif len(B.int_shape(y)) == 4:
            if self._channel_ax == 1:
                return sum([self._agg_fn(y[:, ch]) for ch in self._channels])

            elif self._channel_ax == 3:
                return sum(
                    [self._agg_fn(y[:, :, :, ch]) for ch in self._channels])

            else:
                raise ValueError(
                    'Unsupported channel axis for convolutional layer: {}'.
                    format(self._channel_ax))

        else:
            raise QoiCutSupportError(
                'Unsupported tensor rank for `InternalChannelQoI`: {}'.format(
                    len(B.int_shape(y))))
Example #2
0
    def test_gaussian(self):
        doi = GaussianDoi(var=1., resolution=10)
        res = doi(self.z)

        self.assertEqual(len(res), 10,
                         'GaussianDoi should return `resolution` points')

        self.assertEqual(B.int_shape(res[0]), B.int_shape(self.z))
Example #3
0
    def __call__(self, x: TensorLike) -> TensorLike:

        self._assert_cut_contains_only_one_tensor(x)

        if self.activation is not None:
            if isinstance(self.activation, str):
                self.activation = self.activation.lower()
                if self.activation in ['sigmoid', 'softmax']:
                    x = getattr(B, self.activation)(x)
                else:
                    raise NotImplementedError(
                        'This activation function is not currently supported '
                        'by the backend')
            else:
                x = self.activation(x)

        # TODO(klas): is the `clone` necessary here? Not sure why it was
        #   included.
        mask = B.sign(B.clone(x) - self.threshold)
        if self.low_minus_high:
            mask = -mask

        non_batch_dimensions = tuple(range(len(B.int_shape(x)))[1:])

        return B.sum(mask * x, axis=non_batch_dimensions)
Example #4
0
    def test_comparative(self):
        qoi = ComparativeQoI(1, 0)
        res = qoi(self.y)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(np.allclose(B.as_array(res), np.array([1., -1.])))
Example #5
0
    def test_class(self):
        qoi = ClassQoI(1)
        res = qoi(self.y)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(np.allclose(B.as_array(res), np.array([2., -1.])))
Example #6
0
    def test_internal_channel_axis3(self):
        qoi = InternalChannelQoI(1, channel_axis=3)
        res = qoi(self.z)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(np.allclose(B.as_array(res), np.array([21., 14.])))
Example #7
0
    def test_internal_channel_1d(self):
        qoi = InternalChannelQoI(2)
        res = qoi(self.y)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(np.allclose(B.as_array(res), np.array([3., -2.])))
Example #8
0
    def test_threshold_low_minus_high(self):
        qoi = ThresholdQoI(1.5, low_minus_high=True)
        res = qoi(self.y)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(np.allclose(B.as_array(res), np.array([-4., -3.])))
Example #9
0
    def test_lambda(self):
        qoi = LambdaQoI(lambda y: y[:, 0] + y[:, 1])
        res = qoi(self.y)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(np.allclose(B.as_array(res), np.array([3., -1.])))
Example #10
0
    def test_gaussian_non_tensor(self):
        doi = GaussianDoi(var=1., resolution=10)
        res = doi(B.as_array(self.z))

        self.assertEqual(len(res), 10,
                         'GaussianDoi should return `resolution` points')

        self.assertEqual(res[0].shape, B.int_shape(self.z))
Example #11
0
    def test_threshold_activation(self):
        qoi = ThresholdQoI(0.75, activation='sigmoid')
        res = qoi(self.y)

        self.assertEqual(B.int_shape(res), (2, ),
                         'Should return one scalar per row in the batch')

        self.assertTrue(
            np.allclose(B.as_array(res), np.array([1.1023126, -0.8881443])))
Example #12
0
    def test_linear(self):
        doi = LinearDoi(baseline=np.ones(B.int_shape(self.z)), resolution=21)
        res = doi(self.z)

        self.assertEqual(len(res), 21,
                         'LinearDoi should return `resolution` points')

        self.assertTrue(np.array_equal(B.as_array(res[0]), B.as_array(self.z)),
                        'First point should be the original point')

        self.assertTrue(np.all(B.as_array(res[-1]) == 1.),
                        'Last point should be baseline')

        self.assertTrue(
            np.allclose(B.as_array(res[-2]),
                        np.array([[1., 1.05, 1.1], [0.95, 0.9, 0.85]])),
            'Intermediate points should interpolate from baseline')