Подтвердить что ты не робот

Как реализовать пользовательскую метрику в 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)

Возможно ли реализовать пользовательскую метрику, кроме того, чтобы делать цикл по партиям и редактировать исходный код?

4b9b3361

Ответ 1

Этот код не работает, потому что y_pred и y_true не являются массивами numpy, а также тензорами Theano или Tensor Flow. Вот почему вы получили эту ошибку.

Вы можете определить свои собственные показатели, но вы должны помнить, что его аргументами являются те тензоры, а не массивы numpy.

Ответ 2

Здесь я отвечаю на вопрос темы 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])
    

    Но здесь вы должны помнить, как упоминалось в ответе Марцина Могейко, что y_true и y_pred являются тензорами. Поэтому, чтобы правильно рассчитать метрику, вам нужно использовать функциональность keras.backend. Пожалуйста, посмотрите на этот SO вопрос для деталей. Как рассчитать F1 Макро в Керасе?

  2. Или вы можете реализовать это хакерским способом, как упомянуто в выпуске Keras GH. Для этого вам нужно использовать аргумент 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()
    

Ответ 3

вы можете передать model.predict() в своей метрической функции AUC. [это будет итерация на bacthes, поэтому вам может быть лучше использовать model.predict_on_batch(). Предполагая, что у вас есть что-то вроде слоя softmax в качестве вывода (что-то, что выводит вероятности), тогда вы можете использовать это вместе с sklearn.metric для получения AUC.

from sklearn.metrics import roc_curve, auc

из здесь

def sklearnAUC(test_labels,test_prediction):
    n_classes = 2
    # Compute ROC curve and ROC area for each class
    fpr = dict()
    tpr = dict()
    roc_auc = dict()
    for i in range(n_classes):
        # ( actual labels, predicted probabilities )
        fpr[i], tpr[i], _ = roc_curve(test_labels[:, i], test_prediction[:, i])
        roc_auc[i] = auc(fpr[i], tpr[i])

    return round(roc_auc[0],3) , round(roc_auc[1],3)

теперь сделайте свой показатель

# gives a numpy array like so [ [0.3,0.7] , [0.2,0.8] ....]    
Y_pred = model.predict_on_batch ( X_test  ) 
# Y_test looks something like [ [0,1] , [1,0] .... ]
# auc1 and auc2 should be equal
auc1 , auc2 = sklearnAUC(  Y_test ,  Y_pred )