@ -15,6 +15,7 @@
from __future__ import print_function
from __future__ import print_function
import math
import math
import warnings
from . . import unique_name
from . . import unique_name
from . . framework import Variable
from . . framework import Variable
@ -66,6 +67,51 @@ class LearningRateDecay(object):
persistable = False )
persistable = False )
return lr
return lr
def state_dict ( self ) :
"""
Returns the state of the scheduler as a : class : ` dict ` .
It is a subset of self . __dict__ .
"""
self . _state_keys ( )
state_dict = { }
for key in self . keys :
if key not in self . __dict__ :
continue
value = self . __dict__ [ key ]
if isinstance ( value , Variable ) :
assert value . shape == [
1
] , " shape of Variable in state_dict must be [1] {} " . format (
value . shape )
value = value . numpy ( ) [ 0 ]
state_dict [ key ] = value
return state_dict
def _state_keys ( self ) :
"""
set the keys in self . __dict__ that are needed to be saved .
"""
self . keys = [ ' step_num ' ]
def set_dict ( self , state_dict ) :
"""
Loads the schedulers state .
"""
self . _state_keys ( )
for key in self . keys :
if key in state_dict :
self . __dict__ [ key ] = state_dict [ key ]
else :
raise RuntimeError (
" Please check whether state_dict is correct for optimizer. Can ' t find [ {} ] in state_dict " .
format ( key ) )
if len ( state_dict ) > len ( self . keys ) :
warnings . warn (
" There are some unused values in state_dict. Maybe the optimizer have different ' LearningRateDecay ' when invoking state_dict and set_dict "
)
def step ( self ) :
def step ( self ) :
raise NotImplementedError ( )
raise NotImplementedError ( )
@ -402,7 +448,7 @@ class PolynomialDecay(LearningRateDecay):
learning_rate ( Variable | float ) : The initial learning rate . If the type
learning_rate ( Variable | float ) : The initial learning rate . If the type
is Variable , it ' s a tensor with shape [1], the data type can be
is Variable , it ' s a tensor with shape [1], the data type can be
float32 or float64 . It also can be set to python int number .
float32 or float64 . It also can be set to python int number .
decay_steps ( int32 ) : The decay step size . It determines the decay cycle .
decay_steps ( int ) : The decay step size . It determines the decay cycle .
end_learning_rate ( float , optional ) : The minimum final learning rate . The default value is 0.0001 .
end_learning_rate ( float , optional ) : The minimum final learning rate . The default value is 0.0001 .
power ( float , optional ) : Power of polynomial . The default value is 1.0 .
power ( float , optional ) : Power of polynomial . The default value is 1.0 .
cycle ( bool , optional ) : If set true , decay the learning rate every decay_steps . The default value is False .
cycle ( bool , optional ) : If set true , decay the learning rate every decay_steps . The default value is False .
@ -785,7 +831,7 @@ class ReduceLROnPlateau(LearningRateDecay):
raise ValueError (
raise ValueError (
' new_lr = origin_lr * decay_rate and decay_rate should be < 1.0. '
' new_lr = origin_lr * decay_rate and decay_rate should be < 1.0. '
)
)
self . decay_rate = decay_rate
self . decay_rate = self . create_lr_var ( decay_rate )
threshold_mode = threshold_mode . lower ( )
threshold_mode = threshold_mode . lower ( )
if threshold_mode not in [ ' rel ' , ' abs ' ] :
if threshold_mode not in [ ' rel ' , ' abs ' ] :
@ -794,8 +840,10 @@ class ReduceLROnPlateau(LearningRateDecay):
self . threshold_mode = threshold_mode
self . threshold_mode = threshold_mode
check_type ( learning_rate , ' learning_rate ' , ( float , int , Variable ) ,
check_type ( learning_rate , ' learning_rate ' , ( float , int , Variable ) ,
' ReduceLROnPlateau ' )
' ReduceLROnPlateau ' )
if isinstance ( learning_rate , ( float , int ) ) :
if not isinstance ( learning_rate , ( float , int , Variable ) ) :
learning_rate = self . create_lr_var ( learning_rate )
raise TypeError (
" The type of ' learning_rate ' in ' ReduceLROnPlateau ' must be ' float, int, Variable ' , but received %s . "
% type ( learning_rate ) )
self . learning_rate = learning_rate
self . learning_rate = learning_rate
self . verbose = verbose
self . verbose = verbose
@ -809,9 +857,17 @@ class ReduceLROnPlateau(LearningRateDecay):
self . cooldown_counter = 0
self . cooldown_counter = 0
self . best_loss = None
self . best_loss = None
self . num_bad_epochs = 0
self . num_bad_epochs = 0
self . epoch = 0
self . epoch_num = 0
def _state_keys ( self ) :
self . keys = [
' cooldown_counter ' , ' best_loss ' , ' num_bad_epochs ' , ' epoch_num ' ,
' learning_rate '
]
def __call__ ( self ) :
def __call__ ( self ) :
if not isinstance ( self . learning_rate , Variable ) :
self . learning_rate = self . create_lr_var ( self . learning_rate )
return self . learning_rate
return self . learning_rate
def step ( self , loss ) :
def step ( self , loss ) :
@ -837,7 +893,7 @@ class ReduceLROnPlateau(LearningRateDecay):
" should be (1L,), but the current loss.shape is {} . Maybe that " \
" should be (1L,), but the current loss.shape is {} . Maybe that " \
" you should call fluid.layers.mean to process it first. " . format ( loss . shape )
" you should call fluid.layers.mean to process it first. " . format ( loss . shape )
self . epoch + = 1
self . epoch _num + = 1
if self . cooldown_counter > 0 :
if self . cooldown_counter > 0 :
self . cooldown_counter - = 1
self . cooldown_counter - = 1
else :
else :
@ -855,10 +911,11 @@ class ReduceLROnPlateau(LearningRateDecay):
self . decay_rate , self . min_lr )
self . decay_rate , self . min_lr )
if self . learning_rate - new_lr > self . eps :
if self . learning_rate - new_lr > self . eps :
if self . verbose :
if self . verbose :
old_lr = self . learning_rate . numpy ( ) [ 0 ] if isinstance (
self . learning_rate ,
Variable ) else self . learning_rate
print ( ' Epoch {} : reducing learning rate from {} to {} . ' .
print ( ' Epoch {} : reducing learning rate from {} to {} . ' .
format ( self . epoch ,
format ( self . epoch_num , old_lr , new_lr . numpy ( ) [ 0 ] ) )
self . learning_rate . numpy ( ) [ 0 ] ,
new_lr . numpy ( ) [ 0 ] ) )
self . learning_rate = new_lr
self . learning_rate = new_lr
def _is_better ( self , current , best ) :
def _is_better ( self , current , best ) :
@ -891,22 +948,28 @@ class _LearningRateEpochDecay(LearningRateDecay):
raise TypeError (
raise TypeError (
" The type of ' learning_rate ' must be ' float, int ' , but received %s . "
" The type of ' learning_rate ' must be ' float, int ' , but received %s . "
% type ( learning_rate ) )
% type ( learning_rate ) )
if learning_rate >= 1. 0:
if learning_rate < 0:
raise ValueError ( " The initial learning rate" )
raise ValueError ( " Invalid learning rate: {} " . format ( learning_rate ) )
self . base_lr = float ( learning_rate )
self . base_lr = float ( learning_rate )
self . epoch_num = - 1
self . epoch_num = - 1
self . dtype = dtype
if dtype is None :
if dtype is None :
self . dtype = " float32 "
self . dtype = " float32 "
self . learning_rate = self . create_lr_var ( self . base_lr )
self . learning_rate = self . create_lr_var ( self . base_lr )
self . epoch ( )
self . epoch ( )
def _state_keys ( self ) :
self . keys = [ ' epoch_num ' , ' learning_rate ' ]
def __call__ ( self ) :
def __call__ ( self ) :
"""
"""
Return last computed learning rate on current epoch .
Return last computed learning rate on current epoch .
"""
"""
if not isinstance ( self . learning_rate , Variable ) :
self . learning_rate = self . create_lr_var ( self . learning_rate )
return self . learning_rate
return self . learning_rate
def epoch ( self , epoch = None ) :
def epoch ( self , epoch = None ) :
@ -919,8 +982,6 @@ class _LearningRateEpochDecay(LearningRateDecay):
self . epoch_num = epoch
self . epoch_num = epoch
self . learning_rate = self . get_lr ( )
self . learning_rate = self . get_lr ( )
if isinstance ( self . learning_rate , float ) :
self . learning_rate = self . create_lr_var ( self . learning_rate )
def get_lr ( self ) :
def get_lr ( self ) :
raise NotImplementedError
raise NotImplementedError
@ -947,7 +1008,7 @@ class StepDecay(_LearningRateEpochDecay):
Parameters :
Parameters :
learning_rate ( float | int ) : The initial learning rate . It can be set to python float or int number .
learning_rate ( float | int ) : The initial learning rate . It can be set to python float or int number .
step_size ( int ) : Period of learning rate decay . .
step_size ( int ) : Period of learning rate decay .
decay_rate ( float , optional ) : The Ratio that the learning rate will be reduced . ` ` new_lr = origin_lr * decay_rate ` ` .
decay_rate ( float , optional ) : The Ratio that the learning rate will be reduced . ` ` new_lr = origin_lr * decay_rate ` ` .
It should be less than 1.0 . Default : 0.1 .
It should be less than 1.0 . Default : 0.1 .
@ -1025,7 +1086,7 @@ class MultiStepDecay(_LearningRateEpochDecay):
learning_rate = 0.005
learning_rate = 0.005
Parameters :
Parameters :
learning_rate ( float | int ) : The initial learning rate . It can be set to python float or int number . If it
learning_rate ( float | int ) : The initial learning rate . It can be set to python float or int number .
milestones ( tuple | list ) : List or tuple of each boundaries . Must be increasing .
milestones ( tuple | list ) : List or tuple of each boundaries . Must be increasing .
decay_rate ( float , optional ) : The Ratio that the learning rate will be reduced . ` ` new_lr = origin_lr * decay_rate ` ` .
decay_rate ( float , optional ) : The Ratio that the learning rate will be reduced . ` ` new_lr = origin_lr * decay_rate ` ` .
It should be less than 1.0 . Default : 0.1 .
It should be less than 1.0 . Default : 0.1 .