def test_missing_class(self):
        with self.test_session():
            predicted = tf.constant([[0, 0, 1], [1, 0, 0]],
                                    dtype=tf.float32,
                                    name='predicted')
            labels = tf.constant([2, 0], dtype=tf.int32)

            predicted, labels = [
                tf.expand_dims(x, axis=0) for x in (predicted, labels)
            ]

            for loss_func in ('Dice', 'Dice_NS', 'Dice_Dense',
                              'Dice_Dense_NS'):

                test_loss_func = LossFunction(3,
                                              loss_type=loss_func,
                                              softmax=False)
                if 'Dense' in loss_func:
                    loss_value = test_loss_func(predicted,
                                                tf.one_hot(labels, 3))
                else:
                    loss_value = test_loss_func(predicted, labels)

                # softmax of zero, Dice loss of -1, so sum \approx -1
                self.assertAllClose(loss_value.eval(), 0.0, atol=1e-4)
Example #2
0
 def test_wrong_prediction(self):
     with self.test_session():
         predicted = tf.constant([[0, 100]],
                                 dtype=tf.float32,
                                 name='predicted')
         labels = tf.constant([0], dtype=tf.int64, name='labels')
         test_loss_func = LossFunction(2, loss_type='Dice')
         one_minus_dice_score = test_loss_func(predicted, labels)
         self.assertAlmostEqual(one_minus_dice_score.eval(), 1.0)
Example #3
0
 def test_dice_score(self):
     with self.test_session():
         predicted = tf.constant([[0, 10], [10, 0], [10, 0], [10, 0]],
                                 dtype=tf.float32,
                                 name='predicted')
         labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')
         test_loss_func = LossFunction(2, loss_type='Dice')
         one_minus_dice_score = test_loss_func(predicted, labels)
         self.assertAllClose(one_minus_dice_score.eval(), 0.0, atol=1e-5)
Example #4
0
 def test_sens_spec_loss_by_regression(self):
     with self.test_session():
         predicted = tf.constant([[0, 10], [10, 0], [10, 0], [10, 0]],
                                 dtype=tf.float32,
                                 name='predicted')
         labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')
         test_loss_func = LossFunction(2, loss_type='SensSpec')
         test_loss = test_loss_func(predicted, labels)
         self.assertAlmostEqual(test_loss.eval(), 2.06106e-9)
    def test_dense_dice_nosquare_vs_sparse(self):
        # regression test vs dense version
        with self.cached_session():
            predicted = tf.constant(
                [[2, 3], [9, 8], [0, 0], [1, 0]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')

            predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]

            sparse_loss_func = LossFunction(2, loss_type='Dice_NS')
            sparse_dice = sparse_loss_func(predicted, labels)

            one_hot = tf.one_hot(labels, axis=-1, depth=2)
            dense_loss_func = LossFunction(2, loss_type='Dice_Dense_NS')
            dense_dice = dense_loss_func(predicted, one_hot)

            self.assertAllEqual(sparse_dice.eval(), dense_dice.eval())
    def test_volume_enforcement_nonexist(self):
        with self.cached_session():
            predicted = tf.constant([[1000, -1000], [1000, -1000], [1000, -1000], [1000, -1000]],
                                    dtype=tf.float32, name='predicted')
            labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')

            predicted, labels = [tf.expand_dims(x, axis=0) for x in
                                 (predicted, labels)]
            venf_loss_func = LossFunction(2, loss_type='VolEnforcement')
            venf_loss = venf_loss_func(predicted, labels)
            self.assertAllClose(venf_loss.eval(), 500.75, atol=0.1)
    def test_wrong_prediction(self):
        with self.cached_session():
            predicted = tf.constant(
                [[0, 100]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([0], dtype=tf.int64, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]

            test_loss_func = LossFunction(2, loss_type='Dice_NS')
            one_minus_dice_score = test_loss_func(predicted, labels)
            self.assertAllClose(one_minus_dice_score.eval(), 1.0, atol=1e-4)
 def test_dice_plus_weighted(self):
     with self.cached_session():
         predicted = tf.constant(
             [[0, 9999, 9999], [9999, 0, 0], [0, 9999, 9999], [9999, 0, 0]],
             dtype=tf.float32, name='predicted')
         labels = tf.constant([2, 0, 1, 0], dtype=tf.int16, name='labels')
         weights = tf.expand_dims(tf.constant([0, 1, 0, 0], dtype=tf.float32), axis=0)
         predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]
         test_loss_func = LossFunction(3, loss_type='DicePlusXEnt', softmax=True)
         loss_value = test_loss_func(predicted, labels, weight_map=weights)
         self.assertAllClose(loss_value.eval(), -1.)
Example #9
0
    def test_wrong_prediction(self):
        with self.test_session():
            predicted = tf.constant(
                [[0, 100]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([0], dtype=tf.int64, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]
            one_hot = tf.one_hot(labels, axis=-1, depth=2)

            test_loss_func = LossFunction(2, loss_type='Dice_Dense')
            one_minus_dice_score = test_loss_func(predicted, one_hot)
            self.assertAlmostEqual(one_minus_dice_score.eval(), 1.0)
    def test_dice_plus_multilabel(self):
        with self.cached_session():
            predicted = tf.constant(
                [[0, 0, 9999], [9999, 0, 0], [0, 9999, 0], [9999, 0, 0]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([2, 0, 1, 0], dtype=tf.int16, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]
            test_loss_func = LossFunction(3, loss_type='DicePlusXEnt', softmax=False)
            loss_value = test_loss_func(predicted, labels)

            # cross-ent of zero, Dice loss of -1, so sum \approx -1
            self.assertAllClose(loss_value.eval(), -1.0, atol=1e-3)
Example #11
0
 def test_generalised_dice_score_regression(self):
     with self.test_session():
         predicted = tf.constant([[0, 10], [10, 0], [10, 0], [10, 0]],
                                 dtype=tf.float32,
                                 name='predicted')
         labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')
         weights = tf.cast(labels, tf.float32)
         test_loss_func = LossFunction(2, loss_type='GDSC')
         one_minus_generalised_dice_score = test_loss_func(
             predicted, labels, weights)
         self.assertAlmostEqual(one_minus_generalised_dice_score.eval(),
                                0.92424583)
Example #12
0
 def test_multi_label_sens_spec(self):
     with self.test_session():
         # answer calculated by hand -
         predicted = tf.constant([[0, 1, 0], [0, 0, 1]],
                                 dtype=tf.float32,
                                 name='predicted')
         labels = tf.constant([1, 2], dtype=tf.int64, name='labels')
         test_loss_func = LossFunction(3,
                                       loss_type='SensSpec',
                                       loss_func_params={'r': 0.05})
         test_loss = test_loss_func(predicted, labels)
         self.assertAlmostEqual(test_loss.eval(), 0.14598623)
Example #13
0
 def test_cross_entropy_value(self):
     # test value is -0.5 * [1 * log(e / (1+e)) + 1 * log(e^2 / (e^2 + 1))]
     with self.test_session():
         predicted = tf.constant([[0, 1], [2, 0]],
                                 dtype=tf.float32,
                                 name='predicted')
         labels = tf.constant([1, 0], dtype=tf.int64, name='labels')
         test_loss_func = LossFunction(2, loss_type='CrossEntropy')
         computed_cross_entropy = test_loss_func(predicted, labels)
         self.assertAlmostEqual(
             computed_cross_entropy.eval(), -.5 *
             (np.log(np.e / (1 + np.e)) + np.log(np.e**2 / (1 + np.e**2))))
 def test_dice_plus_wrong_softmax(self):
     with self.cached_session():
         predicted = tf.constant(
             [[0, 9999, 9999], [9999, 0, 0], [0, 9999, 9999], [9999, 0, 0]],
             dtype=tf.float32, name='predicted')
         labels = tf.constant([2, 0, 1, 0], dtype=tf.int16, name='labels')
         predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]
         test_loss_func = LossFunction(3, loss_type='DicePlusXEnt', softmax=True)
         loss_value = test_loss_func(predicted, labels)
         # cross-ent of mean(ln(2), 0, 0, ln(2)) = .5*ln(2)
         # Dice loss of -mean(1, .5, .5)=-2/3
         self.assertAllClose(loss_value.eval(), .5 * np.log(2) - 2. / 3., atol=1e-3)
    def test_wrong_prediction(self):
        with self.cached_session():
            predicted = tf.constant(
                [[0, 100]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([0], dtype=tf.int64, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0)
                                 for x in (predicted, labels)]

            test_loss_func = LossFunction(2, loss_type='Tversky')
            one_minus_tversky_index = test_loss_func(predicted, labels)
            self.assertAlmostEqual(one_minus_tversky_index.eval(), 1.0)
    def test_dice_dense_score(self):
        with self.cached_session():
            predicted = tf.constant(
                [[0, 10], [10, 0], [10, 0], [10, 0]],
                dtype=tf.float32, name='predicted')
            one_hot = tf.constant([[1, 0], [0, 1], [0, 1], [0, 1]],
                                  dtype=tf.int64, name='one_hot')
            predicted, one_hot = [tf.expand_dims(x, axis=0) for x in (predicted, one_hot)]

            test_loss_func = LossFunction(2, loss_type='Dice_Dense')
            one_minus_dice_score = test_loss_func(predicted, one_hot)
            self.assertAllClose(one_minus_dice_score.eval(), 1.0, atol=1e-4)
    def test_tversky_index(self):
        with self.cached_session():
            predicted = tf.constant(
                [[0, 10], [10, 0], [10, 0], [10, 0]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0)
                                 for x in (predicted, labels)]

            test_loss_func = LossFunction(2, loss_type='Tversky')
            one_minus_tversky_index = test_loss_func(predicted, labels)
            self.assertAllClose(one_minus_tversky_index.eval(), 0.0, atol=1e-4)
    def test_generalised_dice_score_regression(self):
        with self.cached_session():
            predicted = tf.constant(
                [[0, 10], [10, 0], [10, 0], [10, 0]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([1, 0, 0, 0], dtype=tf.int64, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]

            test_loss_func = LossFunction(2, loss_type='GDSC')
            one_minus_generalised_dice_score = test_loss_func(
                predicted, labels)
            self.assertAllClose(
                one_minus_generalised_dice_score.eval(), 0.0, atol=1e-4)
Example #19
0
    def connect_data_and_network(self,
                                 outputs_collector=None,
                                 gradients_collector=None):
        data_dict = self.get_sampler()[0][0].pop_batch_op()
        image = tf.cast(data_dict['image'], tf.float32)
        net_out = self.net(image, self.is_training)

        if self.is_training:
            with tf.name_scope('Optimiser'):
                self.learning_rate = tf.placeholder(tf.float64, shape=[])
                optimiser_class = OptimiserFactory.create(
                    name=self.action_param.optimiser)
                self.optimiser = optimiser_class.get_instance(
                    learning_rate=self.learning_rate)
            loss_func = LossFunction(
                n_class=self.segmentation_param.num_classes,
                loss_type=self.action_param.loss_type)
            data_loss = loss_func(prediction=net_out,
                                  ground_truth=data_dict.get('label', None),
                                  weight_map=data_dict.get('weight', None))

            self.current_loss = data_loss
            loss = data_loss
            reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)

            if self.net_param.decay > 0.0 and reg_losses:
                reg_loss = tf.reduce_mean(
                    [tf.reduce_mean(reg_loss) for reg_loss in reg_losses])
                loss = data_loss + reg_loss
            grads = self.optimiser.compute_gradients(loss)
            # collecting gradients variables
            gradients_collector.add_to_collection([grads])
            # collecting output variables
            outputs_collector.add_to_collection(var=self.current_loss,
                                                name='loss',
                                                average_over_devices=False,
                                                collection=CONSOLE)
            outputs_collector.add_to_collection(var=self.learning_rate,
                                                name='lr',
                                                average_over_devices=False,
                                                collection=CONSOLE)
            outputs_collector.add_to_collection(var=data_loss,
                                                name='dice_loss',
                                                average_over_devices=True,
                                                summary_type='scalar',
                                                collection=TF_SUMMARIES)
        else:
            # converting logits into final output for
            # classification probabilities or argmax classification labels
            SegmentationApplication.connect_data_and_network(
                self, outputs_collector, gradients_collector)
    def test_cross_entropy_value(self):
        # test value is -0.5 * [1 * log(e / (1+e)) + 1 * log(e^2 / (e^2 + 1))]
        with self.cached_session():
            predicted = tf.constant(
                [[0, 1], [2, 0]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([1, 0], dtype=tf.int64, name='labels')
            predicted, labels = [tf.expand_dims(x, axis=0) for x in (predicted, labels)]

            test_loss_func = LossFunction(2, loss_type='CrossEntropy')
            computed_cross_entropy = test_loss_func(predicted, labels)
            self.assertAlmostEqual(
                computed_cross_entropy.eval(),
                -.5 * (np.log(np.e / (1 + np.e)) + np.log(
                    np.e ** 2 / (1 + np.e ** 2))))

            test_dense_loss = LossFunction(2, loss_type='CrossEntropy_Dense')
            labels = tf.sparse_tensor_to_dense(labels_to_one_hot(labels, 2))
            computed_cross_entropy = test_loss_func(predicted, tf.to_int32(labels))
            self.assertAlmostEqual(
                computed_cross_entropy.eval(),
                -.5 * (np.log(np.e / (1 + np.e)) + np.log(
                    np.e ** 2 / (1 + np.e ** 2))))
    def test_dice_score_weights(self):
        with self.cached_session():
            weights = tf.constant([[1, 1, 0, 0]], dtype=tf.float32,
                                  name='weights')
            predicted = tf.constant(
                [[0, 10], [10, 0], [10, 0], [10, 0]],
                dtype=tf.float32, name='predicted')
            labels = tf.constant([[1, 0, 0, 0]], dtype=tf.int64, name='labels')
            predicted, labels, weights = [tf.expand_dims(x, axis=0) for x in (predicted, labels, weights)]

            test_loss_func = LossFunction(2, loss_type='Dice')
            one_minus_dice_score = test_loss_func(predicted, labels,
                                                  weight_map=weights)
            self.assertAllClose(one_minus_dice_score.eval(), 0.0, atol=1e-4)
Example #22
0
 def test_gdsc_incorrect_type_weight_error(self):
     with self.test_session():
         with self.assertRaises(ValueError) as cm:
             predicted = tf.constant([[0, 10], [10, 0], [10, 0], [10, 0]],
                                     dtype=tf.float32,
                                     name='predicted')
             labels = tf.constant([1, 0, 0, 0],
                                  dtype=tf.int64,
                                  name='labels')
             test_loss_func = LossFunction(
                 2,
                 loss_type='GDSC',
                 loss_func_params={'type_weight': 'unknown'})
             one_minus_generalised_dice_score = test_loss_func(
                 predicted, labels)
    def test_cross_entropy_value_weight(self):
        with self.test_session():
            weights = tf.constant([[1], [2]], dtype=tf.float32, name='weights')
            predicted = tf.constant([[0, 1], [2, 0]],
                                    dtype=tf.float32,
                                    name='predicted')
            labels = tf.constant([[1], [0]], dtype=tf.int64, name='labels')
            predicted, labels, weights = \
                [tf.expand_dims(x, axis=0) for x in (predicted, labels, weights)]

            test_loss_func = LossFunction(2, loss_type='CrossEntropy')
            computed_cross_entropy = test_loss_func(predicted, labels, weights)
            self.assertAlmostEqual(
                computed_cross_entropy.eval(),
                -.5 * (2.0 / 3.0 * np.log(np.e / (1 + np.e)) +
                       4.0 / 3.0 * np.log(np.e**2 / (1 + np.e**2))))
    def test_dice_batch_size_greater_than_one(self):
        # test for Github issue #22: need to take mean per-image before
        # averaging Dice of ~1 and ~0.16, should get dice ~ 1 - 0.5816
        with self.cached_session():
            # predictions ~ [1, 0, 0]; [0, 0, 1]; [0, .5, .5]; [.333, .333, .333]
            predictions_numpy = np.array([[[10., 0, 0], [0, 0, 10]],
                                          [[-10, 0, 0], [0, 0, 0]]]).reshape([2, 2, 1, 1, 3])
            labels_numpy = np.array([[[0, 2]], [[0, 1]]]).reshape([2, 2, 1, 1, 1])

            predicted = tf.constant(predictions_numpy, dtype=tf.float32, name='predicted')
            labels = tf.constant(labels_numpy, dtype=tf.int64, name='labels')

            test_loss_func = LossFunction(3, loss_type='Dice')
            one_minus_dice_score = test_loss_func(predicted, labels)

            self.assertAllClose(one_minus_dice_score.eval(), 1 - 0.5816, atol=1e-4)
    def test_generalised_dice_score_uniform_regression(self):
        with self.cached_session():
            predicted = tf.constant([[0, 10], [10, 0], [10, 0], [10, 0]],
                                    dtype=tf.float32, name='predicted')

            labels = tf.constant([[1, 0, 0, 0]], dtype=tf.int64, name='labels')
            weights = tf.cast(labels, tf.float32)
            predicted, labels, weights = [tf.expand_dims(x, axis=0) for x in
                                          (predicted, labels, weights)]

            test_loss_func = LossFunction(
                2, loss_type='GDSC',
                loss_func_params={'type_weight': 'Uniform'})
            one_minus_generalised_dice_score = test_loss_func(
                predicted, labels, weights)
            self.assertAllClose(one_minus_generalised_dice_score.eval(),
                                0.3333, atol=1e-4)
Example #26
0
def train(config_file):
    # 1, load configuration parameters
    config = parse_config(config_file)
    config_data = config['data']
    config_net = config['network']
    config_train = config['training']

    random.seed(config_train.get('random_seed', 1))
    assert (config_data['with_ground_truth'])

    net_type = config_net['net_type']
    net_name = config_net['net_name']
    class_num = config_net['class_num']
    batch_size = config_data.get('batch_size', 5)

    # 2, construct graph
    full_data_shape = [batch_size] + config_data['data_shape']
    full_label_shape = [batch_size] + config_data['label_shape']
    x = tf.placeholder(tf.float32, shape=full_data_shape)
    w = tf.placeholder(tf.float32, shape=full_label_shape)
    y = tf.placeholder(tf.int64, shape=full_label_shape)

    w_regularizer = regularizers.l2_regularizer(config_train.get(
        'decay', 1e-7))
    b_regularizer = regularizers.l2_regularizer(config_train.get(
        'decay', 1e-7))
    net_class = NetFactory.create(net_type)
    net = net_class(num_classes=class_num,
                    w_regularizer=w_regularizer,
                    b_regularizer=b_regularizer,
                    name=net_name)
    net.set_params(config_net)
    predicty = net(x, is_training=True)
    proby = tf.nn.softmax(predicty)

    loss_func = LossFunction(n_class=class_num)
    loss = loss_func(predicty, y, weight_map=w)
    print('size of predicty:', predicty)

    # 3, initialize session and saver
    lr = config_train.get('learning_rate', 1e-3)
    opt_step = tf.train.AdamOptimizer(lr).minimize(loss)
    tf.summary.FileWriter("./graphs/" + config_net['net_name'],
                          tf.get_default_graph()).close()
Example #27
0
def adv_image_dynamic_shape(temp_imgs, data_shape, label_shape, data_channel,
                                  class_num, batch_size, sess, net):
    '''
    Create one adversarial image with sub regions along z-axis
    The height and width of input tensor is adapted to those of the input image
    '''
    # construct graph
    [D, H, W] = temp_imgs[0].shape
    Hx = max(int((H+3)/4)*4, data_shape[1])
    Wx = max(int((W+3)/4)*4, data_shape[2])
    data_slice = data_shape[0]
    label_slice = label_shape[0]
    full_data_shape = [batch_size, data_slice, Hx, Wx, data_channel]
    x = tf.placeholder(tf.float32, full_data_shape)
    predicty = net(x, is_training = True)
    proby = tf.nn.softmax(predicty)

    preds_max = reduce_max(predicty, 1, keepdims=True)
    y = tf.to_float(tf.equal(predicty, preds_max))
    y = tf.stop_gradient(y)
    y = y / reduce_sum(y, 1, keepdims=True)

    # Create adversarial attack
    loss_func = LossFunction(n_class=class_num)
    loss = loss_func(predicty, y)
    fgsm = FastGradientMethod(net)
    adv_steps = 2
    fgsm_params = {'eps': 0.4/adv_steps, 'loss_func': loss}
    adv_x = fgsm.generate(x, **fgsm_params)

    new_data_shape = [data_slice, Hx, Wx]
    new_label_shape = [label_slice, Hx, Wx]

    print("Running adversarial attack with %d steps" % adv_steps)
    for i in range(adv_steps):
        temp_imgs = volume_probability_prediction(temp_imgs, new_data_shape, new_label_shape, data_channel,
                                              class_num, batch_size, sess, adv_x, x)
    return temp_imgs
 def test_suggestion_for_dice_typo(self):
     with self.cached_session():
         with self.assertRaisesRegexp(ValueError, 'Dice'):
             LossFunction(1, loss_type='dice')
 def test_suggestion_for_gdsc_typo(self):
     with self.cached_session():
         with self.assertRaisesRegexp(ValueError, 'GDSC'):
             LossFunction(1, loss_type='GSDC')
 def test_value_error_for_bad_loss_function(self):
     with self.cached_session():
         with self.assertRaises(ValueError):
             LossFunction(1, loss_type='wrong answer')