reduce learning rate when a metric has stopped improving models often benefit from reducing the learning rate by a factor of 210 once learning stagnates this callback monitors a quantity and if no improvement is seen for a patience number of epochs the learning rate is reduced example python reducelr reducelronplateaumonitor valloss factor0 2 patience5 minlr0 001 model fitxtrain ytrain callbacksreducelr args monitor string quantity to be monitored factor float factor by which the learning rate will be reduced newlr lr factor patience integer number of epochs with no improvement after which learning rate will be reduced verbose integer 0 quiet 1 update messages mode string one of auto min max in min mode the learning rate will be reduced when the quantity monitored has stopped decreasing in max mode it will be reduced when the quantity monitored has stopped increasing in auto mode the direction is automatically inferred from the name of the monitored quantity mindelta float threshold for measuring the new optimum to only focus on significant changes cooldown integer number of epochs to wait before resuming normal operation after the learning rate has been reduced minlr float lower bound on the learning rate resets wait counter and cooldown counter if self mode not in auto min max warnings warn flearning rate reduction mode self mode is unknown fallback to auto mode stacklevel2 self mode auto if self mode min or self mode auto and acc not in self monitor self monitorop lambda a b np lessa b self mindelta self best np inf else self monitorop lambda a b np greatera b self mindelta self best np inf self cooldowncounter 0 self wait 0 def ontrainbeginself logsnone self reset def onepochendself epoch logsnone logs logs or logslearningrate float backend converttonumpyself model optimizer learningrate current logs getself monitor if current is none warnings warn learning rate reduction is conditioned on metric fself monitor which is not available available metrics fare joinlistlogs keys stacklevel2 else if self incooldown self cooldowncounter 1 self wait 0 if self monitoropcurrent self best self best current self wait 0 elif not self incooldown self wait 1 if self wait self patience oldlr float backend converttonumpy self model optimizer learningrate if oldlr np float32self minlr newlr oldlr self factor newlr maxnewlr self minlr self model optimizer learningrate newlr if self verbose 0 ioutils printmsg fnepoch epoch 1 reducelronplateau reducing flearning rate to newlr self cooldowncounter self cooldown self wait 0 def incooldownself return self cooldowncounter 0 reduce learning rate when a metric has stopped improving models often benefit from reducing the learning rate by a factor of 2 10 once learning stagnates this callback monitors a quantity and if no improvement is seen for a patience number of epochs the learning rate is reduced example python reduce_lr reducelronplateau monitor val_loss factor 0 2 patience 5 min_lr 0 001 model fit x_train y_train callbacks reduce_lr args monitor string quantity to be monitored factor float factor by which the learning rate will be reduced new_lr lr factor patience integer number of epochs with no improvement after which learning rate will be reduced verbose integer 0 quiet 1 update messages mode string one of auto min max in min mode the learning rate will be reduced when the quantity monitored has stopped decreasing in max mode it will be reduced when the quantity monitored has stopped increasing in auto mode the direction is automatically inferred from the name of the monitored quantity min_delta float threshold for measuring the new optimum to only focus on significant changes cooldown integer number of epochs to wait before resuming normal operation after the learning rate has been reduced min_lr float lower bound on the learning rate cooldown counter resets wait counter and cooldown counter
import warnings

import numpy as np

from keras import backend
from keras.api_export import keras_export
from keras.callbacks.callback import Callback
from keras.utils import io_utils


@keras_export("keras.callbacks.ReduceLROnPlateau")
class ReduceLROnPlateau(Callback):
    

    def __init__(
        self,
        monitor="val_loss",
        factor=0.1,
        patience=10,
        verbose=0,
        mode="auto",
        min_delta=1e-4,
        cooldown=0,
        min_lr=0,
        **kwargs,
    ):
        super().__init__()

        self.monitor = monitor
        if factor >= 1.0:
            raise ValueError(
                "ReduceLROnPlateau does not support a factor >= 1.0. "
                f"Received factor={factor}"
            )

        self.factor = factor
        self.min_lr = min_lr
        self.min_delta = min_delta
        self.patience = patience
        self.verbose = verbose
        self.cooldown = cooldown
        self.cooldown_counter = 0  
        self.wait = 0
        self.best = 0
        self.mode = mode
        self.monitor_op = None
        self._reset()

    def _reset(self):
        
        if self.mode not in {"auto", "min", "max"}:
            warnings.warn(
                f"Learning rate reduction mode {self.mode} is unknown, "
                "fallback to auto mode.",
                stacklevel=2,
            )
            self.mode = "auto"
        if self.mode == "min" or (
            self.mode == "auto" and "acc" not in self.monitor
        ):
            self.monitor_op = lambda a, b: np.less(a, b - self.min_delta)
            self.best = np.Inf
        else:
            self.monitor_op = lambda a, b: np.greater(a, b + self.min_delta)
            self.best = -np.Inf
        self.cooldown_counter = 0
        self.wait = 0

    def on_train_begin(self, logs=None):
        self._reset()

    def on_epoch_end(self, epoch, logs=None):
        logs = logs or {}
        logs["learning_rate"] = float(
            backend.convert_to_numpy(self.model.optimizer.learning_rate)
        )
        current = logs.get(self.monitor)

        if current is None:
            warnings.warn(
                "Learning rate reduction is conditioned on metric "
                f"`{self.monitor}` which is not available. Available metrics "
                f"are: {','.join(list(logs.keys()))}.",
                stacklevel=2,
            )
        else:
            if self.in_cooldown():
                self.cooldown_counter -= 1
                self.wait = 0

            if self.monitor_op(current, self.best):
                self.best = current
                self.wait = 0
            elif not self.in_cooldown():
                self.wait += 1
                if self.wait >= self.patience:
                    old_lr = float(
                        backend.convert_to_numpy(
                            self.model.optimizer.learning_rate
                        )
                    )
                    if old_lr > np.float32(self.min_lr):
                        new_lr = old_lr * self.factor
                        new_lr = max(new_lr, self.min_lr)
                        self.model.optimizer.learning_rate = new_lr
                        if self.verbose > 0:
                            io_utils.print_msg(
                                f"\nEpoch {epoch +1}: "
                                "ReduceLROnPlateau reducing "
                                f"learning rate to {new_lr}."
                            )
                        self.cooldown_counter = self.cooldown
                        self.wait = 0

    def in_cooldown(self):
        return self.cooldown_counter > 0