Gibt es eine Möglichkeit, die vom Early Stopping-Rückruf in Keras verwendete Metrik zu ändern?

12

Bei Verwendung des Rückrufs zum frühen Stoppen in Keras wird das Training beendet, wenn eine Metrik (normalerweise Validierungsverlust) nicht zunimmt. Gibt es eine Möglichkeit, eine andere Metrik (wie Präzision, Rückruf, f-Maß) anstelle des Validierungsverlusts zu verwenden? Alle Beispiele, die ich bisher gesehen habe, ähneln diesem: callbacks.EarlyStopping (monitor = 'val_loss', geduld = 5, verbose = 0, mode = 'auto')

P. Joseph
quelle

Antworten:

10

Sie können jede Metrikfunktion verwenden, die Sie beim Kompilieren des Modells angegeben haben.

Angenommen, Sie haben die folgende Metrikfunktion:

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

Die einzige Voraussetzung für diese Funktion ist, dass sie das wahre y und das vorhergesagte y akzeptiert.

Wenn Sie das Modell kompilieren, geben Sie diese Metrik an, ähnlich wie Sie eingebaute Metriken wie "Genauigkeit" angeben:

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

Beachten Sie, dass wir den Funktionsnamen my_metric ohne '' verwenden (im Gegensatz zur eingebauten 'Genauigkeit').

Wenn Sie dann Ihr EarlyStopping definieren, verwenden Sie einfach den Namen der Funktion (diesmal mit ''):

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

Stellen Sie sicher, dass Sie den Modus angeben (min, wenn niedriger besser ist, max, wenn höher besser ist).

Sie können es wie jede integrierte Metrik verwenden. Dies funktioniert wahrscheinlich auch mit anderen Rückrufen wie ModelCheckpoint (aber das habe ich nicht getestet). Intern fügt Keras die neue Metrik lediglich unter Verwendung des Funktionsnamens zur Liste der für dieses Modell verfügbaren Metriken hinzu.

Wenn Sie in Ihrem model.fit (...) Daten für die Validierung angeben, können Sie diese auch für EarlyStopping verwenden, indem Sie 'val_my_metric' verwenden.

Michael
quelle
3

Natürlich erstellen Sie einfach Ihre eigenen!

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)

Ich habe das noch nicht getestet, aber das sollte der allgemeine Geschmack dafür sein, wie Sie vorgehen. Wenn es nicht funktioniert, lass es mich wissen und ich werde es über das Wochenende erneut versuchen. Ich gehe auch davon aus, dass Sie bereits Ihren eigenen F1-Score implementiert haben. Wenn nicht nur für sklearn importieren.

Tophat
quelle
+1 Funktioniert immer noch ab dem 11.02.2020 mit den neuesten Keras und Python 3.7
Austin