Search code examples
pythonnumpytensorflowkerasloss-function

AttributeError: 'Tensor' object has no attribute 'numpy' when using a Keras-based custom loss function


I read the publication entitled "IMPROVED TRAINABLE CALIBRATION METHOD FOR NEURAL NETWORKS ON MEDICAL IMAGING CLASSIFICATION" available at https://arxiv.org/pdf/2009.04057.pdf. In this study, they have proposed a custom loss function that incorporates calibration into the model training process. They included the calibration component to the categorical cross entropy loss to create this custom function. I have created a Keras version of this function as shown below:

def dca_loss(y_true, y_pred, beta=1):
    # y_true: one-hot encoding
    # y_pred: predicted probability (i.e., softmax(logits))
 
    ## calculating cross-entropy loss ##
    loss_ce = K.mean(keras.losses.categorical_crossentropy(y_true, y_pred)) 
    
    ## calculating the DCA term ##
    # get gt labels
    gt_labels = tf.argmax(y_true, axis=1).numpy()
    # get pred labels
    pred_labels = tf.argmax(y_pred, axis=1).numpy()
    # get accuracy 
    acc = np.sum(gt_labels==pred_labels)/len(gt_labels)
    # get pred mean prob
    temp_prop = 0
    for i in range(len(y_true)):
      temp_prop+=y_pred[i, pred_labels[i]]
    prob = temp_prop/len(y_true)
    # calculating dca
    dca = np.abs(acc-prob)

    loss = loss_ce + beta*dca
    
    return loss

I compile the model as shown below:

model.compile(optimizer='sgd', 
                    loss=[dca_loss],  
                    metrics=['accuracy']) 

An error is thrown as shown below:

c:\users\appdata\local\continuum\anaconda3\envs\tf_2.4\lib\site-packages\tensorflow\python\keras\engine\training.py:805 train_function  *
        return step_function(self, iterator)
    C:\Users\codes\custom_loss_final.py:560 dca_loss  *
        gt_labels = tf.argmax(y_true, axis=1).numpy()

    AttributeError: 'Tensor' object has no attribute 'numpy'

I understand that numpy should not be used in the custom function declaration. I need assistance in using tf functions or Keras backend functions as replacement.


Solution

  • You have two choices:

    a) Use Tensorflow ufuncs for your loss function, for instance not using .numpy() and replacing np.sum() by tf.reduce_sum()

    b) Use NumPy ufuncs, but train eagerly, by passing run_eagerly=True in model.compile()