Existe alguma maneira de alterar a métrica usada pelo retorno de chamada de parada antecipada em Keras?

13

Ao usar o retorno de chamada de Parada Antecipada no Keras, o treinamento é interrompido quando alguma métrica (geralmente perda de validação) não está aumentando. Existe uma maneira de usar outra métrica (como precisão, recall, f-measure) em vez da perda de validação? Todos os exemplos que eu vi até agora são semelhantes a este: callbacks.EarlyStopping (monitor = 'val_loss', paciência = 5, detalhado = 0, mode = 'auto')

P.Joseph
fonte

Respostas:

11

Você pode usar qualquer função métrica especificada ao compilar o modelo.

Digamos que você tenha a seguinte função métrica:

def my_metric(y_true, y_pred):
     return some_metric_computation(y_true, y_pred)

O único requisito para essa função é que ela aceite o y verdadeiro e o y previsto.

Ao compilar o modelo, você especifica essa métrica, da mesma forma que especifica a construção de métricas como 'precisão':

model.compile(metrics=['accuracy', my_metric], ...)

Observe que estamos usando o nome da função my_metric sem '' (em contraste com a construção em 'precisão').

Então, se você definir seu EarlyStopping, use o nome da função (desta vez com ''):

EarlyStopping(monitor='my_metric', mode='min')

Certifique-se de especificar o modo (min se menor for melhor, max se maior for melhor).

Você pode usá-lo como qualquer métrica incorporada. Provavelmente isso também funciona com outros retornos de chamada como ModelCheckpoint (mas eu não testei isso). Internamente, Keras adiciona a nova métrica à lista de métricas disponíveis para este modelo usando o nome da função.

Se você especificar dados para validação no seu model.fit (...), também poderá usá-los no EarlyStopping usando 'val_my_metric'.

Michael
fonte
3

Claro, basta criar o seu!

class EarlyStopByF1(keras.callbacks.Callback):
    def __init__(self, value = 0, verbose = 0):
        super(keras.callbacks.Callback, self).__init__()
        self.value = value
        self.verbose = verbose


    def on_epoch_end(self, epoch, logs={}):
         predict = np.asarray(self.model.predict(self.validation_data[0]))
         target = self.validation_data[1]
         score = f1_score(target, prediction)
         if score > self.value:
            if self.verbose >0:
                print("Epoch %05d: early stopping Threshold" % epoch)
            self.model.stop_training = True


callbacks = [EarlyStopByF1(value = .90, verbose =1)]
model.fit(X, y, batch_size = 32, nb_epoch=nb_epoch, verbose = 1, 
validation_data(X_val,y_val), callbacks=callbacks)

Eu não testei isso, mas esse deve ser o sabor geral de como você faz isso. Se não funcionar, avise-me e tentarei novamente no fim de semana. Também estou assumindo que você já tem sua própria pontuação de F1 implementada. Se não apenas importe para o sklearn.

Cartola
fonte
+1 Ainda funciona a partir de 11/02/2020 usando o Keras e o Python 3.7 mais recentes
Austin