samra irshad
samra irshad

Reputation: 213

Custom metrics for image segmentation in Keras

I am trying to print and log the custom metrics (dice score) for all classes for validation set during training. I want the Keras to calculate custom metrics on validation set after each epoch. My current program is working but I have to use some tricks that ultimately cause memory problems during training.

The issue is to print and log the dice scores of all classes, the calculations are done on tensors which I am unable to print. I cant use eager mode due to some compatibility issues with TensorFlow 2.0 and forced to initialize another session.

My custom metrics class is given below:

class Metrics(tf.keras.callbacks.Callback):

    def on_train_begin(self, logs={}):
        self.val_lv = []
        self.val_rk = []
        self.val_lk = []
        self.val_sp = []

    def on_epoch_end(self, batch, logs={}):

        layer_name = 'loss6'
        self.intermediate_layer_model = tf.keras.models.Model(inputs=self.model.input,
                                                              outputs=self.model.get_layer(layer_name).output)
        for batch_index in range(0, len(self.validation_data)):
            temp_targ = self.validation_data[batch_index][1][0]

            temp_targ=temp_targ.astype('float32')

            temp_predict = (np.asarray( self.intermediate_layer_model.predict(
                self.validation_data[batch_index][0]))).round()

            val_lvs = tf.reduce_mean((dice_coef(temp_targ[:,1, :, :], temp_predict[:,1, :, :])))
            val_rks = tf.reduce_mean(dice_coef(temp_targ[:, 2, :, :], temp_predict[:, 2, :, :]))
            val_lks = tf.reduce_mean(dice_coef(temp_targ[:, 3, :, :], temp_predict[:, 3, :, :]))
            val_sps = tf.reduce_mean(dice_coef(temp_targ[:, 4, :, :], temp_predict[:, 4, :, :]))


            self.val_lv.append(val_lvs)
            self.val_rk.append(val_rks)
            self.val_lk.append(val_lks)
            self.val_sp.append(val_sps)
        sess = tf.Session()
        print('liver-score:', sess.run(tf.reduce_mean(self.val_lv)))
        print('rk-score:', sess.run(tf.reduce_mean(self.val_rk)))
        print('lk-score:', sess.run(tf.reduce_mean(self.val_lk)))
        print('sp-score:', sess.run(tf.reduce_mean(self.val_sp)))

        logs['liver-score'] = sess.run(tf.reduce_mean(self.val_lv))
        logs['rk-score'] = sess.run(tf.reduce_mean(self.val_rk))
        logs['lk-score'] = sess.run(tf.reduce_mean(self.val_lk))
        logs['sp-score'] = sess.run(tf.reduce_mean(self.val_sp))
        sess.close()

        return

Note that the variables lv, rk, lk and sp are abbreviations for my class names.

Any alternative way to print and log the metrics except for using session?

Upvotes: 2

Views: 300

Answers (1)

Srihari Humbarwadi
Srihari Humbarwadi

Reputation: 2642

As far as i understand, temp_predict and temp_predict are numpy arrays. So the only way you can end up with tensors is because you are using tf.reduce_mean. You can replace it with np.mean. This will only work if dice_coef has no tensorflow ops. If it does then you will have to replace them with numpy functions. Once you do that, then you wouldn't have to open new sessions.

And also instead of creating a new model at the end of every epoch (intermediate_layer_model), you can construct a keras function using tf.keras.backend.function more about it here.

Upvotes: 1

Related Questions