How to calculate F1 Macro in Keras?

后端 未结 6 1696
逝去的感伤
逝去的感伤 2020-11-28 23:13

i\'ve tried to use the codes given from Keras before they\'re removed. Here\'s the code :

def precision(y_true, y_pred):
    true_positives = K.sum(K.round(K         


        
6条回答
  •  情话喂你
    2020-11-28 23:30

    As @Diesche mentioned the main problem in implementing f1_score this way is that it is called at every batch step and leads to confusing results more than anything else.

    I've been struggling some time with this issue but eventually worked my way around the problem by using a callback: at the end of an epoch the callback predicts on the data (in this case I chose to only apply it to my validation data) with the new model parameters and gives you coherent metrics evaluated on the whole epoch.

    I'm using tensorflow-gpu (1.14.0) on python3

    from tensorflow.python.keras.models import Sequential, Model
    from sklearn.metrics import  f1_score
    from tensorflow.keras.callbacks import Callback
    from tensorflow.python.keras import optimizers
    
    
    
    optimizer = optimizers.SGD(lr=0.0001, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=['accuracy'])
    model.summary()
    
    class Metrics(Callback):
        def __init__(self, model, valid_data, true_outputs):
            super(Callback, self).__init__()
            self.model=model
            self.valid_data=valid_data    #the validation data I'm getting metrics on
            self.true_outputs=true_outputs    #the ground truth of my validation data
            self.steps=len(self.valid_data)
    
    
        def on_epoch_end(self, args,*kwargs):
            gen=generator(self.valid_data)     #generator yielding the validation data
            val_predict = (np.asarray(self.model.predict(gen, batch_size=1, verbose=0, steps=self.steps)))
    
            """
            The function from_proba_to_output is used to transform probabilities  
            into an understandable format by sklearn's f1_score function
            """
            val_predict=from_proba_to_output(val_predict, 0.5)
            _val_f1 = f1_score(self.true_outputs, val_predict)
            print ("val_f1: ", _val_f1, "   val_precision: ", _val_precision, "   _val_recall: ", _val_recall)
    

    The function from_proba_to_output goes as follows:

    def from_proba_to_output(probabilities, threshold):
        outputs = np.copy(probabilities)
        for i in range(len(outputs)):
    
            if (float(outputs[i])) > threshold:
                outputs[i] = int(1)
            else:
                outputs[i] = int(0)
        return np.array(outputs)
    

    I then train my model by referencing this metrics class in the callbacks part of fit_generator. I did not detail the implementation of my train_generator and valid_generator as these data generators are specific to the classification problem at hand and posting them would only bring confusion.

        model.fit_generator(
    train_generator, epochs=nbr_epochs, verbose=1, validation_data=valid_generator, callbacks=[Metrics(model, valid_data)])
    

提交回复
热议问题