如何在keras中实现自定义指标?

Phi*_*e C 18 python metrics neural-network deep-learning keras

我收到此错误:

sum()得到一个意外的关键字参数'out'

当我运行此代码时:

import pandas as pd, numpy as np
import keras
from keras.layers.core import Dense, Activation
from keras.models import Sequential

def AUC(y_true,y_pred):
    not_y_pred=np.logical_not(y_pred)
    y_int1=y_true*y_pred
    y_int0=np.logical_not(y_true)*not_y_pred
    TP=np.sum(y_pred*y_int1)
    FP=np.sum(y_pred)-TP
    TN=np.sum(not_y_pred*y_int0)
    FN=np.sum(not_y_pred)-TN
    TPR=np.float(TP)/(TP+FN)
    FPR=np.float(FP)/(FP+TN)
    return((1+TPR-FPR)/2)

# Input datasets

train_df = pd.DataFrame(np.random.rand(91,1000))
train_df.iloc[:,-2]=(train_df.iloc[:,-2]>0.8)*1


model = Sequential()
model.add(Dense(output_dim=60, input_dim=91, init="glorot_uniform"))
model.add(Activation("sigmoid"))
model.add(Dense(output_dim=1, input_dim=60, init="glorot_uniform"))
model.add(Activation("sigmoid"))

model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=[AUC])


train_df.iloc[:,-1]=np.ones(train_df.shape[0]) #bias
X=train_df.iloc[:,:-1].values
Y=train_df.iloc[:,-1].values
print X.shape,Y.shape

model.fit(X, Y, batch_size=50,show_accuracy = False, verbose = 1)
Run Code Online (Sandbox Code Playgroud)

除了在批处理上执行循环和编辑源代码之外,是否可以实现自定义指标?

vog*_*gdb 20

在这里,我正在回答OP的主题问题,而不是他的确切问题.我正在这样做,因为当我讨论主题问题时问题出现在顶部.

您可以通过两种方式实现自定义指标.

  1. Keras纪录片中所述.

    import keras.backend as K
    
    def mean_pred(y_true, y_pred):
        return K.mean(y_pred)
    
    model.compile(optimizer='sgd',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])
    
    Run Code Online (Sandbox Code Playgroud)

    但在这里你必须记住MarcinMożejko的回答中提到的y_true并且y_pred是张量.因此,为了正确计算您需要使用keras.backend功能的指标.请看这个SO问题详情如何计算Keras的F1 Macro?

  2. 或者你可以像Keras GH问题中提到的那样以hacky方式实现它.为此你需要使用callbacks参数model.fit.

    import keras as keras
    import numpy as np
    from keras.optimizers import SGD
    from sklearn.metrics import roc_auc_score
    
    model = keras.models.Sequential()
    # ...
    sgd = SGD(lr=0.001, momentum=0.9)
    model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])
    
    
    class Metrics(keras.callbacks.Callback):
        def on_train_begin(self, logs={}):
            self._data = []
    
        def on_epoch_end(self, batch, logs={}):
            X_val, y_val = self.validation_data[0], self.validation_data[1]
            y_predict = np.asarray(model.predict(X_val))
    
            y_val = np.argmax(y_val, axis=1)
            y_predict = np.argmax(y_predict, axis=1)
    
            self._data.append({
                'val_rocauc': roc_auc_score(y_val, y_predict),
            })
            return
    
        def get_data(self):
            return self._data
    
    metrics = Metrics()
    history = model.fit(X_train, y_train, epochs=100, validation_data=(X_val, y_val), callbacks=[metrics])
    metrics.get_data()
    
    Run Code Online (Sandbox Code Playgroud)

  • @对于使用大型验证数据集的人来说,您将面临两倍的验证时间。一项验证由 keras 完成,另一项验证由您的指标通过调用预测完成。另一个问题是现在你的指标使用 GPU 进行预测,CPU 使用 numpy 计算指标,因此 GPU 和 CPU 是串行的。如果指标的计算成本很高,您将面临更差的 GPU 利用率,并且必须进行 keras 中已经完成的优化。 (7认同)

Mar*_*jko 9

此代码不起作用,因为y_pred并且y_true不是numpy数组,而是Theano或Tensor Flow张量.这就是你得到这个错误的原因.

您可以定义自定义指标,但必须记住它的参数是那些Tensors - 而不是numpy数组.

  • 我不想将numpy数组转换为张量,反之亦然.如果我们采用OP的函数,我试过:`def AUC(y_true,y_pred):numpy_y_true = y_true.eval()... return ...`但它没有用.你会如何解决OP的问题? (3认同)
  • 您能否详细说明如何解决此问题?如何将Tensor转换为numpy数组? (2认同)
  • 您需要将张量视为代数变量。您无法将 numpy 数组转换为张量。您只能将 numpy 数组指定为张量的值。 (2认同)
  • 自定义指标不能是典型的数字返回函数。即使“def auc(y_true, y_pred): return 1.0”也不起作用。在看到任何训练示例之前,度量函数在编译时被调用一次。 (2认同)