在Keras中创建自定义宏以计算召回率

我试图创建一个自定义宏来计算recall = (class1的召回率 + class2的召回率)/2。我写了以下代码,但我不确定如何计算类0的真正阳性。

def unweightedRecall():    def recall(y_true, y_pred):        # 类1的召回率        true_positives1 = K.sum(K.round(K.clip(y_pred * y_true, 0, 1)))        possible_positives1 = K.sum(K.round(K.clip(y_true, 0, 1)))        recall1 = true_positives1 / (possible_positives1 + K.epsilon())        # --- 在这里获取类0的真正阳性到true_positives0 ---        # 还有,是否有更简洁的方法获取possible_positives0        possible_positives0 = K.int_shape(y_true)[0] - possible_positives1        recall0 = true_positives0 / (possible_positives0 + K.epsilon())        return (recall0 + recall1)/2    return recall

看起来我需要使用Keras.backend.equal(x, y),但我如何创建一个形状为K.int_shape(y_true)[0]且所有值为x的张量呢?


编辑1

根据Marcin的评论,我想要基于Keras的回调函数创建一个自定义指标。在浏览Keras的问题时,我发现了以下用于f1指标的代码:

class Metrics(keras.callbacks.Callback):    def on_epoch_end(self, batch, logs={}):        predict = np.asarray(self.model.predict(self.validation_data[0]))        targ = self.validation_data[1]        self.f1s=f1(targ, predict)        returnmetrics = Metrics()model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=[X_test,y_test],        verbose=1, callbacks=[metrics])

但回调函数是如何返回准确率的呢?我想要实现unweighted recall = (class1的召回率 + class2的召回率)/2。我想到以下代码,但希望能得到帮助来完成它

from sklearn.metrics import recall_scoreclass Metrics(keras.callbacks.Callback):    def on_epoch_end(self, batch, logs={}):        predict = np.asarray(self.model.predict(self.validation_data[0]))        targ = self.validation_data[1]        # --- 将结果存储在哪里? ---        self.XXXX=recall_score(targ, predict, average='macro')        # 我们真的不需要返回任何东西吗?        returnmetrics = Metrics()model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=[X_test,y_test],        verbose=1, callbacks=[metrics])

编辑2:模型:

def createModelHelper(numNeurons=40, optimizer='adam'):    inputLayer = Input(shape=(data.shape[1],))    denseLayer1 = Dense(numNeurons)(inputLayer)    outputLayer = Dense(1, activation='sigmoid')(denseLayer1)    model = Model(input=inputLayer, output=outputLayer)    model.compile(loss=unweightedRecall, optimizer=optimizer)    return model

回答:

keras版本(带有平均问题)。

你的两个类实际上只是一个维度的输出(0或1)吗?

如果是这样的情况:

def recall(y_true, y_pred):    # 类1的召回率    # 如果你要用作损失函数,不要在这里使用"round"    true_positives = K.sum(K.round(y_pred) * y_true)    possible_positives = K.sum(y_true)    return true_positives / (possible_positives + K.epsilon())def unweightedRecall(y_true, y_pred):    return (recall(y_true,y_pred) + recall(1-y_true,1-y_pred))/2.

现在,如果你的两个类实际上是2个元素的输出:

def unweightedRecall(y_true, y_pred):    return (recall(y_true[:,0],y_pred[:,0]) + recall(y_true[:,1],y_pred[:,1]))/2.

回调版本

对于回调,你可以使用LambdaCallback,并手动打印或存储结果:

myCallBack = LambdaCallback(on_epoch_end=unweightedRecall)stored_metrics = []def unweightedRecall(epoch,logs):    predict = model.predict(self.validation_data[0])    targ = self.validation_data[1]    result = (recall(targ,predict) + recall(1-targ,1-predict))/2.     print("epoch " + str(epoch) + "的召回率: " + str(result))    stored_metrics.append(result)

其中recall是一个使用np而不是K的函数。并且epsilon = np.finfo(float).epsepsilon = np.finfo(np.float32).eps)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注