|
23 | 23 | __all__ = [
|
24 | 24 | 'NoamDecay', 'PiecewiseDecay', 'NaturalExpDecay', 'ExponentialDecay',
|
25 | 25 | 'InverseTimeDecay', 'PolynomialDecay', 'CosineDecay', 'LinearLrWarmup',
|
26 |
| - 'ReduceLROnPlateau', 'StepDecay', 'MultiStepDecay' |
| 26 | + 'ReduceLROnPlateau', 'StepDecay', 'MultiStepDecay', 'LambdaDecay' |
27 | 27 | ]
|
28 | 28 |
|
29 | 29 |
|
@@ -1086,3 +1086,70 @@ def get_lr(self):
|
1086 | 1086 | return self.base_lr * (decay_rate**i)
|
1087 | 1087 |
|
1088 | 1088 | return self.base_lr * (decay_rate**len(self.milestones))
|
| 1089 | + |
| 1090 | + |
| 1091 | +class LambdaDecay(_LearningRateEpochDecay): |
| 1092 | + """ |
| 1093 | + :api_attr: imperative |
| 1094 | +
|
| 1095 | + Sets the learning rate of ``optimizer`` to the initial lr times a multiplicative factor, and this multiplicative |
| 1096 | + factor is computed by function ``lr_lambda`` . ``lr_lambda`` is funciton which receives ``epoch`` . |
| 1097 | +
|
| 1098 | + The algorithm can be described as the code below. |
| 1099 | +
|
| 1100 | + .. code-block:: text |
| 1101 | +
|
| 1102 | + learning_rate = 0.5 # init learning_rate |
| 1103 | + lr_lambda = lambda epoch: 0.95 ** epoch |
| 1104 | +
|
| 1105 | + learning_rate = 0.5 # epoch 0 |
| 1106 | + learning_rate = 0.475 # epoch 1 |
| 1107 | + learning_rate = 0.45125 # epoch 2 |
| 1108 | +
|
| 1109 | + Parameters: |
| 1110 | + learning_rate (float|int): The initial learning rate. It can be set to python float or int number. |
| 1111 | + lr_lambda (function): A function which computes a multiplicative factor given an integer parameter ``epoch`` , and |
| 1112 | + then multiply the initial learning rate by this multiplicative factor. |
| 1113 | + |
| 1114 | + Returns: |
| 1115 | + None. |
| 1116 | +
|
| 1117 | + Examples: |
| 1118 | + .. code-block:: python |
| 1119 | + |
| 1120 | + import paddle.fluid as fluid |
| 1121 | + import numpy as np |
| 1122 | + with fluid.dygraph.guard(): |
| 1123 | + x = np.random.uniform(-1, 1, [10, 10]).astype("float32") |
| 1124 | + linear = fluid.dygraph.Linear(10, 10) |
| 1125 | + input = fluid.dygraph.to_variable(x) |
| 1126 | + scheduler = fluid.dygraph.LambdaDecay(0.5, lr_lambda=lambda x: 0.95**x) |
| 1127 | + adam = fluid.optimizer.Adam(learning_rate = scheduler, parameter_list = linear.parameters()) |
| 1128 | +
|
| 1129 | + for epoch in range(6): |
| 1130 | + for batch_id in range(5): |
| 1131 | + out = linear(input) |
| 1132 | + loss = fluid.layers.reduce_mean(out) |
| 1133 | + adam.minimize(loss) |
| 1134 | + scheduler.epoch() |
| 1135 | +
|
| 1136 | + print("epoch:%d, current lr is %f" .format(epoch, adam.current_step_lr())) |
| 1137 | + # epoch:0, current lr is 0.5 |
| 1138 | + # epoch:1, current lr is 0.475 |
| 1139 | + # epoch:2, current lr is 0.45125 |
| 1140 | +
|
| 1141 | + """ |
| 1142 | + |
| 1143 | + def __init__(self, learning_rate, lr_lambda): |
| 1144 | + if not callable(lr_lambda): |
| 1145 | + raise TypeError( |
| 1146 | + "The type of 'lr_lambda' in 'LambdaDecay' must be 'function', but received %s." |
| 1147 | + % type(lr_lambda)) |
| 1148 | + |
| 1149 | + self.lr_lambda = lr_lambda |
| 1150 | + super(LambdaDecay, self).__init__(learning_rate) |
| 1151 | + |
| 1152 | + def get_lr(self): |
| 1153 | + base_lr = self.create_lr_var(self.base_lr) |
| 1154 | + |
| 1155 | + return self.base_lr * self.lr_lambda(self.epoch_num) |
0 commit comments