|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| """Tests for lr_schedule."""
|
| from absl.testing import parameterized
|
| import tensorflow as tf, tf_keras
|
|
|
| from official.modeling.optimization import lr_schedule
|
|
|
|
|
| class PowerAndLinearDecayTest(tf.test.TestCase, parameterized.TestCase):
|
|
|
| @parameterized.named_parameters(
|
| dict(
|
| testcase_name='power_only',
|
| init_lr=1.0,
|
| power=-1.0,
|
| linear_decay_fraction=0.0,
|
| total_decay_steps=100,
|
| offset=0,
|
| expected=[[0, 1.0], [1, 1.0], [40, 1. / 40.], [60, 1. / 60],
|
| [100, 1. / 100]]),
|
| dict(
|
| testcase_name='linear_only',
|
| init_lr=1.0,
|
| power=0.0,
|
| linear_decay_fraction=1.0,
|
| total_decay_steps=100,
|
| offset=0,
|
| expected=[[0, 1.0], [1, 0.99], [40, 0.6], [60, 0.4], [100, 0.0]]),
|
| dict(
|
| testcase_name='general',
|
| init_lr=1.0,
|
| power=-1.0,
|
| linear_decay_fraction=0.5,
|
| total_decay_steps=100,
|
| offset=0,
|
| expected=[[0, 1.0], [1, 1.0], [40, 1. / 40.],
|
| [60, 1. / 60. * 0.8], [100, 0.0]]),
|
| dict(
|
| testcase_name='offset',
|
| init_lr=1.0,
|
| power=-1.0,
|
| linear_decay_fraction=0.5,
|
| total_decay_steps=100,
|
| offset=90,
|
| expected=[[0, 1.0], [90, 1.0], [91, 1.0], [130, 1. / 40.],
|
| [150, 1. / 60. * 0.8], [190, 0.0], [200, 0.0]]),
|
| )
|
| def test_power_linear_lr_schedule(self, init_lr, power, linear_decay_fraction,
|
| total_decay_steps, offset, expected):
|
| lr = lr_schedule.PowerAndLinearDecay(
|
| initial_learning_rate=init_lr,
|
| power=power,
|
| linear_decay_fraction=linear_decay_fraction,
|
| total_decay_steps=total_decay_steps,
|
| offset=offset)
|
| for step, value in expected:
|
| self.assertAlmostEqual(lr(step).numpy(), value)
|
|
|
|
|
| class OffsetLearningRateTest(tf.test.TestCase, parameterized.TestCase):
|
|
|
| @parameterized.parameters(
|
| dict(class_name=lr_schedule.PiecewiseConstantDecayWithOffset),
|
| dict(class_name=lr_schedule.PolynomialDecayWithOffset),
|
| dict(class_name=lr_schedule.ExponentialDecayWithOffset),
|
| dict(class_name=lr_schedule.CosineDecayWithOffset),
|
| )
|
| def test_generated_docstring(self, class_name):
|
| self.assertNotEmpty(class_name.__init__.__doc__)
|
|
|
| @parameterized.parameters(
|
| dict(
|
| class_name=lr_schedule.PiecewiseConstantDecayWithOffset,
|
| kwarg=dict(boundaries=[50, 80], values=[1.0, 0.5, 0.1])),
|
| dict(
|
| class_name=lr_schedule.PolynomialDecayWithOffset,
|
| kwarg=dict(initial_learning_rate=1.0, decay_steps=100)),
|
| dict(
|
| class_name=lr_schedule.ExponentialDecayWithOffset,
|
| kwarg=dict(
|
| initial_learning_rate=1.0, decay_steps=100, decay_rate=0.5)),
|
| dict(
|
| class_name=lr_schedule.CosineDecayWithOffset,
|
| kwarg=dict(initial_learning_rate=1.0, decay_steps=100)),
|
| )
|
| def test_offset(self, class_name, kwarg):
|
| offset = 10
|
| offset_lr = class_name(offset=offset, **kwarg)
|
| base_lr = class_name.base_lr_class(**kwarg)
|
| self.assertIsInstance(offset_lr, class_name)
|
| for step in range(10, 101, 10):
|
| self.assertEqual(offset_lr(step), base_lr(step - offset))
|
|
|
|
|
| if __name__ == '__main__':
|
| tf.test.main()
|
|
|