首页 > 解决方案 > keras 中的自定义指标转到 NaN

问题描述

我正在尝试在 Keras 中创建一个自定义指标,用于在训练和验证时评估平衡的准确度得分。准确度是每个类别准确度的平均值。

假设我们有 4 个类别,每个类别的准确度为 [1,1,0.5,0.5],那么平衡准确度 = (1+1+0.5+0.5)/4 = 0.75

我在像 model.compile(..., metrics = [balanced_acc]) 这样的模型编译中使用它,并且在训练前几个时期很好。但它总是NaN在一个时期内经过几次迭代后变成。但它之前从未超过 1 NaN。也就是说,我认为这不是数字错误。而当一个新的时代到来时,它会在一段时间内变得理性,然后NaN再次受到打击。

部分记录如下:

5700/43200 [==>...........................] - ETA: 28s - loss: 3.8991 - accuracy: 0.9254 - f1_m: 0.8699 - balanced_acc: 0.9279

5900/43200 [===>..........................] - ETA: 27s - loss: 4.0909 - accuracy: 0.9258 - f1_m: 0.8718 - balanced_acc: 0.9271

6100/43200 [===>..........................] - ETA: 27s - loss: 4.1779 - accuracy: 0.9274 - f1_m: 0.8737 - balanced_acc: 0.9279

6200/43200 [===>..........................] - ETA: 26s - loss: 4.3051 - accuracy: 0.9268 - f1_m: 0.8746 - balanced_acc: 0.9278

6400/43200 [===>..........................] - ETA: 26s - loss: 4.4368 - accuracy: 0.9266 - f1_m: 0.8763 - balanced_acc: 0.9284

6600/43200 [===>..........................] - ETA: 26s - loss: 4.5449 - accuracy: 0.9267 - f1_m: 0.8779 - balanced_acc: nan   

6700/43200 [===>..........................] - ETA: 25s - loss: 4.5420 - accuracy: 0.9273 - f1_m: 0.8786 - balanced_acc: nan

6900/43200 [===>..........................] - ETA: 25s - loss: 4.6166 - accuracy: 0.9265 - f1_m: 0.8801 - balanced_acc: nan

自定义指标函数的代码是:

def balanced_acc(y_true, y_pred):
    y_true = K.argmax(y_true, axis = 1)
    y_pred = K.argmax(y_pred, axis = 1)

    # now working under ordinary label instead of one-hot representation
    # datatype should be int for both now.

    acc_sum = K.cast(0, dtype='float32')  #initialize sum of accuracies for each batch
    for class_label in [0,1,2]:  # this code is for 3 classes
        shape = K.shape(y_true)[0]   
        empty_index = K.arange(0, shape)   # make an indices tensor like [0 1 2 3 4 ... shape-1]

        indices = empty_index[tf.math.equal(y_true, class_label)]    #get the indices where y_true == the individual class

        y_true_class_label = tf.keras.backend.gather(y_true, indices)   #gather the elements of that class_label, here just repeating that specific label
        y_pred_corresponds = tf.keras.backend.gather(y_pred, indices)  #gather the corresponding predictions

        acc_sum = acc_sum + tf.contrib.metrics.accuracy(y_true_class_label, y_pred_corresponds)

    return acc_sum/3.0

标签: tensorflowmachine-learningkerasdeep-learningnan

解决方案


推荐阅读