Module kerod.core.learning_rate_schedule
Manual Stepping is designed to integrate the computation graph and compute the learning_rate at
each step.
However, the WarmupLearningRateScheduler is Callback handle by the fit in keras.
View Source
"""
Manual Stepping is designed to integrate the computation graph and compute the learning_rate at
each step.
However, the WarmupLearningRateScheduler is Callback handle by the fit in keras.
"""
from typing import List
import tensorflow as tf
from tensorflow.keras import backend as K
from tensorflow.keras.optimizers.schedules import LearningRateSchedule
from tensorflow.python.keras.callbacks import Callback
class LearningRateScheduler(Callback):
"""Warmup Learning rate scheduler. It will perform at the beginning of the training
a linear warmup from `init_lr` to `base_lr`. The learning rate is decreased by 10 according
to the schedule provided by `epochs`.
Arguments:
- *base_lr*: The target learning rate value after the linear warmup
- *num_gpus*: Number of gpus used during the training
- *epochs*: A list of epoch on which the learning rate should be reduce.
- *use_warmup*: Perform the warmup strategy.
- *init_lr*: Learning rate value from which the warmup will start.
- *num_warmup_steps*: Number of training step on which the warmup will be performed.
"""
def __init__(self,
base_lr: float,
num_gpus: int,
epochs: List[int],
use_warmup: bool = True,
init_lr: float = 1e-2 / 3,
num_warmup_steps: int = 1000):
super().__init__()
self._init_lr = init_lr * min(8 / num_gpus, 1)
self.slope = (base_lr - self._init_lr) / num_warmup_steps
self._epochs_to_lr = {epoch: base_lr * 1 / 10**(i + 1) for i, epoch in enumerate(epochs)}
self._epochs = epochs
self._num_gpus = num_gpus
self._use_warmup = use_warmup
self._num_warmup_steps = num_warmup_steps
def on_train_batch_begin(self, batch, logs=None):
global_step = K.get_value((self.model.optimizer.iterations))
if global_step <= self._num_warmup_steps and global_step != 0 and self._use_warmup:
lr = self._init_lr + global_step * self.slope
K.set_value(self.model.optimizer.lr, lr)
def on_epoch_begin(self, epoch, logs=None):
if not hasattr(self.model.optimizer, 'lr'):
raise ValueError('Optimizer must have a "lr" attribute.')
if not hasattr(self.model.optimizer, 'iterations'):
raise ValueError('Optimizer must have an "iterations" attribute.')
global_step = K.get_value(self.model.optimizer.iterations)
target_epochs = [
e for e in self._epochs if epoch >= e and global_step > self._num_warmup_steps
]
if target_epochs:
lr = self._epochs_to_lr[max(target_epochs)]
K.set_value(self.model.optimizer.lr, lr)
class ManualStepping(LearningRateSchedule):
"""Manually stepped learning rate schedule. (Taken and modified from Google object detection)
This function provides fine grained control over learning rates. One must
specify a sequence of learning rates as well as a set of integer steps
at which the current learning rate must transition to the next. For example,
if boundaries = [5, 10] and rates = [.1, .01, .001], then the learning
rate returned by this function is .1 for step=0,...,4, .01 for
step=5...9, and .001 for step=10 and onward.
You can pass this schedule directly into a `tf.keras.optimizers.Optimizer`
as the learning rate.
```python
lr_schedule = tf.keras.optimizers.schedules.ManualStepping(
boundaries=[5, 10],
rates=[.1, .01, .001],
warmup=True)
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=lr_schedule),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(data, labels, epochs=5)
```
The learning rate schedule is also serializable and deserializable using
`tf.keras.optimizers.schedules.serialize` and
`tf.keras.optimizers.schedules.deserialize`.
Arguments:
- *boundaries*: A List of scalar `int32` or `int64` or a `Tensor`. It is a
list of global steps at which to switch learning
rates. This list is assumed to consist of increasing positive integers.
- *rates*: a list of (float) learning rates corresponding to intervals between
the boundaries. The length of this list must be exactly
len(boundaries) + 1.
- *warmup*: Whether to linearly interpolate learning rate for steps in
[0, boundaries[0]].
- *name*: String. Optional name of the operation. Defaults to
'ExponentialDecay'.
Return:
A 1-arg callable learning rate schedule that takes the current optimizer
step and outputs the decayed learning rate, a scalar `Tensor` of the same
type as `rates`.
"""
def __init__(self, boundaries, rates, warmup=False, name=None):
super().__init__()
self.name = name
if warmup and boundaries:
slope = (rates[1] - rates[0]) * 1.0 / boundaries[0]
warmup_steps = list(range(boundaries[0]))
warmup_rates = [rates[0] + slope * step for step in warmup_steps]
boundaries = warmup_steps + boundaries
rates = warmup_rates + rates[1:]
else:
boundaries = [0] + boundaries
self.warmup = warmup
self.rates = rates
self.boundaries = boundaries
self.num_boundaries = len(boundaries)
self.dtype = tf.convert_to_tensor(rates[0]).dtype
def __call__(self, step):
with tf.name_scope(self.name or "ManualStepping"):
boundaries = tf.convert_to_tensor(self.boundaries, self.dtype)
rates = tf.convert_to_tensor(self.rates, self.dtype)
step = tf.convert_to_tensor(step, self.dtype)
rate_index = tf.reduce_max(
tf.where(tf.greater_equal(step, boundaries), list(range(self.num_boundaries)),
[0] * self.num_boundaries))
return tf.reduce_sum(rates * tf.one_hot(rate_index, depth=self.num_boundaries))
def get_config(self):
return {
"boundaries": self.boundaries,
"rates": self.rates,
"warmup": self.warmup,
"name": self.name
}
Classes
LearningRateScheduler
class LearningRateScheduler(
base_lr: float,
num_gpus: int,
epochs: List[int],
use_warmup: bool = True,
init_lr: float = 0.0033333333333333335,
num_warmup_steps: int = 1000
)
a linear warmup from init_lr
to base_lr
. The learning rate is decreased by 10 according
to the schedule provided by epochs
.
Arguments:
- base_lr: The target learning rate value after the linear warmup
- num_gpus: Number of gpus used during the training
- epochs: A list of epoch on which the learning rate should be reduce.
- use_warmup: Perform the warmup strategy.
- init_lr: Learning rate value from which the warmup will start.
- num_warmup_steps: Number of training step on which the warmup will be performed.
Ancestors (in MRO)
- tensorflow.python.keras.callbacks.Callback
Methods
on_batch_begin
def on_batch_begin(
self,
batch,
logs=None
)
A backwards compatibility alias for on_train_batch_begin
.
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_batch_begin(self, batch, logs=None):
"""A backwards compatibility alias for `on_train_batch_begin`."""
on_batch_end
def on_batch_end(
self,
batch,
logs=None
)
A backwards compatibility alias for on_train_batch_end
.
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_batch_end(self, batch, logs=None):
"""A backwards compatibility alias for `on_train_batch_end`."""
on_epoch_begin
def on_epoch_begin(
self,
epoch,
logs=None
)
View Source
def on_epoch_begin(self, epoch, logs=None):
if not hasattr(self.model.optimizer, 'lr'):
raise ValueError('Optimizer must have a "lr" attribute.')
if not hasattr(self.model.optimizer, 'iterations'):
raise ValueError('Optimizer must have an "iterations" attribute.')
global_step = K.get_value(self.model.optimizer.iterations)
target_epochs = [
e for e in self._epochs if epoch >= e and global_step > self._num_warmup_steps
]
if target_epochs:
lr = self._epochs_to_lr[max(target_epochs)]
K.set_value(self.model.optimizer.lr, lr)
on_epoch_end
def on_epoch_end(
self,
epoch,
logs=None
)
Called at the end of an epoch.
Subclasses should override for any actions to run. This function should only be called during TRAIN mode.
Parameters:
Name | Description |
---|---|
epoch | Integer, index of epoch. |
logs | Dict, metric results for this training epoch, and for the validation epoch if validation is performed. Validation result keys are prefixed with val_ . For training epoch, the values of the Model 's metrics are returned. Example : {'loss': 0.2, 'acc': 0.7} . |
View Source
@doc_controls.for_subclass_implementers
def on_epoch_end(self, epoch, logs=None):
"""Called at the end of an epoch.
Subclasses should override for any actions to run. This function should only
be called during TRAIN mode.
Arguments:
epoch: Integer, index of epoch.
logs: Dict, metric results for this training epoch, and for the
validation epoch if validation is performed. Validation result keys
are prefixed with `val_`. For training epoch, the values of the
`Model`'s metrics are returned. Example : `{'loss': 0.2, 'acc': 0.7}`.
"""
on_predict_batch_begin
def on_predict_batch_begin(
self,
batch,
logs=None
)
Called at the beginning of a batch in predict
methods.
Subclasses should override for any actions to run.
Note that if the steps_per_execution
argument to compile
in
tf.keras.Model
is set to N
, this method will only be called every N
batches.
Parameters:
Name | Description |
---|---|
batch | Integer, index of batch within the current epoch. |
logs | Dict, contains the return value of model.predict_step ,it typically returns a dict with a key 'outputs' containing the model's outputs. |
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_predict_batch_begin(self, batch, logs=None):
"""Called at the beginning of a batch in `predict` methods.
Subclasses should override for any actions to run.
Note that if the `steps_per_execution` argument to `compile` in
`tf.keras.Model` is set to `N`, this method will only be called every `N`
batches.
Arguments:
batch: Integer, index of batch within the current epoch.
logs: Dict, contains the return value of `model.predict_step`,
it typically returns a dict with a key 'outputs' containing
the model's outputs.
"""
on_predict_batch_end
def on_predict_batch_end(
self,
batch,
logs=None
)
Called at the end of a batch in predict
methods.
Subclasses should override for any actions to run.
Note that if the steps_per_execution
argument to compile
in
tf.keras.Model
is set to N
, this method will only be called every N
batches.
Parameters:
Name | Description |
---|---|
batch | Integer, index of batch within the current epoch. |
logs | Dict. Aggregated metric results up until this batch. |
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_predict_batch_end(self, batch, logs=None):
"""Called at the end of a batch in `predict` methods.
Subclasses should override for any actions to run.
Note that if the `steps_per_execution` argument to `compile` in
`tf.keras.Model` is set to `N`, this method will only be called every `N`
batches.
Arguments:
batch: Integer, index of batch within the current epoch.
logs: Dict. Aggregated metric results up until this batch.
"""
on_predict_begin
def on_predict_begin(
self,
logs=None
)
Called at the beginning of prediction.
Subclasses should override for any actions to run.
Parameters:
Name | Description |
---|---|
logs | Dict. Currently no data is passed to this argument for this method but that may change in the future. |
View Source
@doc_controls.for_subclass_implementers
def on_predict_begin(self, logs=None):
"""Called at the beginning of prediction.
Subclasses should override for any actions to run.
Arguments:
logs: Dict. Currently no data is passed to this argument for this method
but that may change in the future.
"""
on_predict_end
def on_predict_end(
self,
logs=None
)
Called at the end of prediction.
Subclasses should override for any actions to run.
Parameters:
Name | Description |
---|---|
logs | Dict. Currently no data is passed to this argument for this method but that may change in the future. |
View Source
@doc_controls.for_subclass_implementers
def on_predict_end(self, logs=None):
"""Called at the end of prediction.
Subclasses should override for any actions to run.
Arguments:
logs: Dict. Currently no data is passed to this argument for this method
but that may change in the future.
"""
on_test_batch_begin
def on_test_batch_begin(
self,
batch,
logs=None
)
Called at the beginning of a batch in evaluate
methods.
Also called at the beginning of a validation batch in the fit
methods, if validation data is provided.
Subclasses should override for any actions to run.
Note that if the steps_per_execution
argument to compile
in
tf.keras.Model
is set to N
, this method will only be called every N
batches.
Parameters:
Name | Description |
---|---|
batch | Integer, index of batch within the current epoch. |
logs | Dict, contains the return value of model.test_step . Typically,the values of the Model 's metrics are returned. Example:{'loss': 0.2, 'accuracy': 0.7} . |
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_test_batch_begin(self, batch, logs=None):
"""Called at the beginning of a batch in `evaluate` methods.
Also called at the beginning of a validation batch in the `fit`
methods, if validation data is provided.
Subclasses should override for any actions to run.
Note that if the `steps_per_execution` argument to `compile` in
`tf.keras.Model` is set to `N`, this method will only be called every `N`
batches.
Arguments:
batch: Integer, index of batch within the current epoch.
logs: Dict, contains the return value of `model.test_step`. Typically,
the values of the `Model`'s metrics are returned. Example:
`{'loss': 0.2, 'accuracy': 0.7}`.
"""
on_test_batch_end
def on_test_batch_end(
self,
batch,
logs=None
)
Called at the end of a batch in evaluate
methods.
Also called at the end of a validation batch in the fit
methods, if validation data is provided.
Subclasses should override for any actions to run.
Note that if the steps_per_execution
argument to compile
in
tf.keras.Model
is set to N
, this method will only be called every N
batches.
Parameters:
Name | Description |
---|---|
batch | Integer, index of batch within the current epoch. |
logs | Dict. Aggregated metric results up until this batch. |
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_test_batch_end(self, batch, logs=None):
"""Called at the end of a batch in `evaluate` methods.
Also called at the end of a validation batch in the `fit`
methods, if validation data is provided.
Subclasses should override for any actions to run.
Note that if the `steps_per_execution` argument to `compile` in
`tf.keras.Model` is set to `N`, this method will only be called every `N`
batches.
Arguments:
batch: Integer, index of batch within the current epoch.
logs: Dict. Aggregated metric results up until this batch.
"""
on_test_begin
def on_test_begin(
self,
logs=None
)
Called at the beginning of evaluation or validation.
Subclasses should override for any actions to run.
Parameters:
Name | Description |
---|---|
logs | Dict. Currently no data is passed to this argument for this method but that may change in the future. |
View Source
@doc_controls.for_subclass_implementers
def on_test_begin(self, logs=None):
"""Called at the beginning of evaluation or validation.
Subclasses should override for any actions to run.
Arguments:
logs: Dict. Currently no data is passed to this argument for this method
but that may change in the future.
"""
on_test_end
def on_test_end(
self,
logs=None
)
Called at the end of evaluation or validation.
Subclasses should override for any actions to run.
Parameters:
Name | Description |
---|---|
logs | Dict. Currently the output of the last call toon_test_batch_end() is passed to this argument for this methodbut that may change in the future. |
View Source
@doc_controls.for_subclass_implementers
def on_test_end(self, logs=None):
"""Called at the end of evaluation or validation.
Subclasses should override for any actions to run.
Arguments:
logs: Dict. Currently the output of the last call to
`on_test_batch_end()` is passed to this argument for this method
but that may change in the future.
"""
on_train_batch_begin
def on_train_batch_begin(
self,
batch,
logs=None
)
View Source
def on_train_batch_begin(self, batch, logs=None):
global_step = K.get_value((self.model.optimizer.iterations))
if global_step <= self._num_warmup_steps and global_step != 0 and self._use_warmup:
lr = self._init_lr + global_step * self.slope
K.set_value(self.model.optimizer.lr, lr)
on_train_batch_end
def on_train_batch_end(
self,
batch,
logs=None
)
Called at the end of a training batch in fit
methods.
Subclasses should override for any actions to run.
Note that if the steps_per_execution
argument to compile
in
tf.keras.Model
is set to N
, this method will only be called every N
batches.
Parameters:
Name | Description |
---|---|
batch | Integer, index of batch within the current epoch. |
logs | Dict. Aggregated metric results up until this batch. |
View Source
@doc_controls.for_subclass_implementers
@generic_utils.default
def on_train_batch_end(self, batch, logs=None):
"""Called at the end of a training batch in `fit` methods.
Subclasses should override for any actions to run.
Note that if the `steps_per_execution` argument to `compile` in
`tf.keras.Model` is set to `N`, this method will only be called every `N`
batches.
Arguments:
batch: Integer, index of batch within the current epoch.
logs: Dict. Aggregated metric results up until this batch.
"""
# For backwards compatibility.
self.on_batch_end(batch, logs=logs)
on_train_begin
def on_train_begin(
self,
logs=None
)
Called at the beginning of training.
Subclasses should override for any actions to run.
Parameters:
Name | Description |
---|---|
logs | Dict. Currently no data is passed to this argument for this method but that may change in the future. |
View Source
@doc_controls.for_subclass_implementers
def on_train_begin(self, logs=None):
"""Called at the beginning of training.
Subclasses should override for any actions to run.
Arguments:
logs: Dict. Currently no data is passed to this argument for this method
but that may change in the future.
"""
on_train_end
def on_train_end(
self,
logs=None
)
Called at the end of training.
Subclasses should override for any actions to run.
Parameters:
Name | Description |
---|---|
logs | Dict. Currently the output of the last call to on_epoch_end() is passed to this argument for this method but that may change in the future. |
View Source
@doc_controls.for_subclass_implementers
def on_train_end(self, logs=None):
"""Called at the end of training.
Subclasses should override for any actions to run.
Arguments:
logs: Dict. Currently the output of the last call to `on_epoch_end()`
is passed to this argument for this method but that may change in
the future.
"""
set_model
def set_model(
self,
model
)
View Source
def set_model(self, model):
self.model = model
set_params
def set_params(
self,
params
)
View Source
def set_params(self, params):
self.params = params
ManualStepping
class ManualStepping(
boundaries,
rates,
warmup=False,
name=None
)
This function provides fine grained control over learning rates. One must specify a sequence of learning rates as well as a set of integer steps at which the current learning rate must transition to the next. For example, if boundaries = [5, 10] and rates = [.1, .01, .001], then the learning rate returned by this function is .1 for step=0,...,4, .01 for step=5...9, and .001 for step=10 and onward.
You can pass this schedule directly into a tf.keras.optimizers.Optimizer
as the learning rate.
lr_schedule = tf.keras.optimizers.schedules.ManualStepping(
boundaries=[5, 10],
rates=[.1, .01, .001],
warmup=True)
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=lr_schedule),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(data, labels, epochs=5)
The learning rate schedule is also serializable and deserializable using
tf.keras.optimizers.schedules.serialize
and
tf.keras.optimizers.schedules.deserialize
.
Arguments:
- boundaries: A List of scalar
int32
orint64
or aTensor
. It is a list of global steps at which to switch learning rates. This list is assumed to consist of increasing positive integers. - rates: a list of (float) learning rates corresponding to intervals between the boundaries. The length of this list must be exactly len(boundaries) + 1.
- warmup: Whether to linearly interpolate learning rate for steps in [0, boundaries[0]].
- name: String. Optional name of the operation. Defaults to 'ExponentialDecay'.
Return:
A 1-arg callable learning rate schedule that takes the current optimizer
step and outputs the decayed learning rate, a scalar Tensor
of the same
type as rates
.
Ancestors (in MRO)
- tensorflow.python.keras.optimizer_v2.learning_rate_schedule.LearningRateSchedule
Static methods
from_config
def from_config(
config
)
Instantiates a LearningRateSchedule
from its config.
Parameters:
Name | Description |
---|---|
config | Output of get_config() . |
Returns:
Type | Description |
---|---|
None | A LearningRateSchedule instance. |
View Source
@classmethod
def from_config(cls, config):
"""Instantiates a `LearningRateSchedule` from its config.
Args:
config: Output of `get_config()`.
Returns:
A `LearningRateSchedule` instance.
"""
return cls(**config)
Methods
get_config
def get_config(
self
)
View Source
def get_config(self):
return {
"boundaries": self.boundaries,
"rates": self.rates,
"warmup": self.warmup,
"name": self.name
}