Esempio n. 1
0
    def test_loss_scale_warning(self):
        with test.mock.patch.object(tf_logging, 'warn') as mock_warn:
            mp_policy.PolicyV1('float32', loss_scale=2.)
            self.assertEqual(
                mock_warn.call_args[0][0],
                'Creating a Policy with a loss scale is only useful for float16 '
                'policies. You passed loss_scale=2.0 for policy float32. Consider '
                'not passing any loss_scale instead.')

        for policy_name in 'float16', 'mixed_float16':
            # Trigger any other warnings that occur only once
            mp_policy.PolicyV1(policy_name, loss_scale=2.)
            with test.mock.patch.object(tf_logging, 'warn') as mock_warn:
                mp_policy.PolicyV1(policy_name, loss_scale=2.)
                mock_warn.assert_not_called()
Esempio n. 2
0
    def test_repr(self):
        # Test Policy repr
        for policy in ('float32', 'int8', 'mixed_float16', 'mixed_bfloat16',
                       '_infer'):
            self.assertEqual(repr(mp_policy.Policy(policy)),
                             '<Policy "%s">' % policy)

        # Test PolicyV1 repr
        for policy in ('float32', 'int8', 'mixed_bfloat16', '_infer'):
            self.assertEqual(repr(mp_policy.PolicyV1(policy)),
                             '<PolicyV1 "%s", loss_scale=None>' % policy)
        self.assertEqual(
            repr(mp_policy.PolicyV1('float16', loss_scale=2)),
            '<PolicyV1 "float16", loss_scale=FixedLossScale(2.0)>')
        self.assertStartsWith(
            repr(mp_policy.PolicyV1('mixed_float16')),
            '<PolicyV1 "mixed_float16", loss_scale=DynamicLossScale(')
Esempio n. 3
0
 def test_policy_v1_without_loss_scale(self):
     with policy.policy_scope(
             policy.PolicyV1('mixed_float16', loss_scale=None)):
         opt = gradient_descent.SGD(1.)
         x = layers.Input(shape=(1, ))
         y = mp_test_util.MultiplyLayer()(x)
         model = models.Model(x, y)
         model.compile(opt, loss='mse')
         self.assertNotIsInstance(model.optimizer,
                                  loss_scale_optimizer.LossScaleOptimizer)
Esempio n. 4
0
 def test_pass_invalid_optimizer_with_loss_scaling(self):
     with policy.policy_scope(policy.PolicyV1('float32', loss_scale=10.)):
         x = layers.Input(shape=(1, ))
         y = mp_test_util.MultiplyLayer()(x)
         model = models.Model(x, y)
         if context.executing_eagerly():
             error_msg = 'Use a `tf.keras` Optimizer instead'
         else:
             error_msg = 'optimizer" must be an instance of '
         with self.assertRaisesRegex(ValueError, error_msg):
             model.compile(optimizer_v1.SGD(1.), 'mse')
Esempio n. 5
0
 def test_loss_scale_optimizer_overrides_policy_v1_loss_scale(self):
     with policy.policy_scope(policy.PolicyV1('float32', loss_scale=10.)):
         opt = gradient_descent.SGD(1.)
         opt = loss_scale_optimizer.LossScaleOptimizer(opt,
                                                       dynamic=False,
                                                       initial_scale=5.)
         x = layers.Input(shape=(1, ))
         y = mp_test_util.MultiplyLayer()(x)
         model = models.Model(x, y)
         model.compile(opt, loss='mse')
         self.assertEqual(self.evaluate(model.optimizer.loss_scale), 5.)
Esempio n. 6
0
    def test_loss_scale(self):
        policy = mp_policy.PolicyV1('float32')
        self.assertEqual(policy.loss_scale, None)

        policy = mp_policy.PolicyV1('float32', loss_scale=None)
        self.assertEqual(policy.loss_scale, None)

        ls = loss_scale_module.DynamicLossScale()
        policy = mp_policy.PolicyV1('float32', loss_scale=ls)
        self.assertIs(policy.loss_scale, ls)

        policy = mp_policy.PolicyV1('float32', loss_scale='dynamic')
        self.assertIsInstance(policy.loss_scale,
                              loss_scale_module.DynamicLossScale)

        policy = mp_policy.PolicyV1('mixed_float16')
        self.assertIsInstance(policy.loss_scale,
                              loss_scale_module.DynamicLossScale)

        policy = mp_policy.PolicyV1('mixed_float16', loss_scale=None)
        self.assertEqual(policy.loss_scale, None)

        policy = mp_policy.PolicyV1('mixed_bfloat16')
        self.assertEqual(policy.loss_scale, None)
Esempio n. 7
0
    def test_dynamic_loss_scaling(self,
                                  strategy_fn,
                                  pass_loss_scale_to_policy=False,
                                  get_config=False,
                                  use_v1_loss_scale_optimizer=False):
        strategy = strategy_fn()
        initial_loss_scale = 2.
        batch_size = 4
        expected_gradient = backend.variable([initial_loss_scale / batch_size],
                                             dtype=dtypes.float16)
        # If this variable is set to True, the model below will have NaN gradients
        have_nan_gradients = backend.variable(False, dtype=dtypes.bool)
        with strategy.scope():
            opt = gradient_descent.SGD(1.)
            if pass_loss_scale_to_policy:
                loss_scale = loss_scale_module.DynamicLossScale(
                    initial_loss_scale=initial_loss_scale, increment_period=2)
                p = policy.PolicyV1('mixed_float16', loss_scale=loss_scale)
            elif use_v1_loss_scale_optimizer:
                loss_scale = loss_scale_module.DynamicLossScale(
                    initial_loss_scale=initial_loss_scale, increment_period=2)
                p = policy.Policy('mixed_float16')
                opt = loss_scale_optimizer.LossScaleOptimizerV1(
                    opt, loss_scale)
            else:
                p = policy.Policy('mixed_float16')
                opt = loss_scale_optimizer.LossScaleOptimizer(
                    opt,
                    initial_scale=initial_loss_scale,
                    dynamic_growth_steps=2)
            with policy.policy_scope(p):
                x = layers.Input(shape=(1, ),
                                 batch_size=batch_size,
                                 dtype=dtypes.float16)
                layer = mp_test_util.MultiplyLayer(assert_type=dtypes.float16)
                y = layer(x)
                identity_with_nan_grads = (
                    mp_test_util.create_identity_with_nan_gradients_fn(
                        have_nan_gradients))
                y = core.Lambda(identity_with_nan_grads)(y)
                identity_with_grad_check_fn = (
                    mp_test_util.create_identity_with_grad_check_fn(
                        expected_dtype=dtypes.float16,
                        expected_gradient=expected_gradient))
                y = core.Lambda(identity_with_grad_check_fn)(y)
                model = models.Model(inputs=x, outputs=y)
                if get_config:
                    config = model.get_config()
                    model = model.__class__.from_config(
                        config,
                        custom_objects={
                            'MultiplyLayer': mp_test_util.MultiplyLayer
                        })
                    (layer, ) = (
                        layer for layer in model.layers
                        if isinstance(layer, mp_test_util.MultiplyLayer))

                def loss_fn(y_true, y_pred):
                    del y_true
                    return math_ops.reduce_mean(y_pred)

                model.compile(opt,
                              loss=loss_fn,
                              run_eagerly=testing_utils.should_run_eagerly())

        self.assertEqual(backend.eval(layer.v), 1)
        x = np.ones((batch_size, 1))
        y = np.ones((batch_size, 1))
        dataset = dataset_ops.Dataset.from_tensor_slices(
            (x, y)).batch(batch_size)
        model.fit(dataset)
        # The variables starts with 1 and has a gradient of 1, so will go down by 1
        # each step.
        self.assertEqual(backend.eval(layer.v), 0)

        model.fit(dataset)
        self.assertEqual(backend.eval(layer.v), -1)

        # There have been two steps without NaNs, so the loss scale will double
        backend.set_value(expected_gradient,
                          backend.get_value(expected_gradient * 2))
        model.fit(dataset)
        self.assertEqual(backend.eval(layer.v), -2)

        # Next test with NaN gradients.
        backend.set_value(have_nan_gradients, True)
        model.fit(dataset)
        # Variable should not be updated
        self.assertEqual(backend.eval(layer.v), -2)

        # Test with finite gradients again
        backend.set_value(have_nan_gradients, False)
        # The loss scale will be halved due to the NaNs, so the gradient will also
        # be halved
        backend.set_value(expected_gradient,
                          backend.get_value(expected_gradient / 2))
        model.fit(dataset)
        self.assertEqual(backend.eval(layer.v), -3)
Esempio n. 8
0
    def test_serialization(self):
        # Test policies that are equivalent to a single dtype
        for policy_name in 'float16', 'float32', 'int8', 'string', 'bool':
            policy = mp_policy.Policy(policy_name)
            config = mp_policy.serialize(policy)
            self.assertEqual(config, policy_name)
            new_policy = mp_policy.deserialize(config)
            self.assertEqual(str(policy), str(new_policy))

        # Test "_infer" policy
        policy = mp_policy.Policy('_infer')
        config = mp_policy.serialize(policy)
        self.assertIsNone(config)
        new_policy = mp_policy.deserialize(config)
        self.assertEqual(str(policy), str(new_policy))

        class MyPolicy(mp_policy.Policy):
            pass

        # Test policies that are not equivalent to a single dtype
        for policy in (mp_policy.Policy('mixed_float16'),
                       mp_policy.Policy('mixed_bfloat16'),
                       MyPolicy('float32')):
            config = mp_policy.serialize(policy)
            self.assertEqual(
                config, {
                    'class_name': policy.__class__.__name__,
                    'config': {
                        'name': policy.name
                    }
                })
            new_policy = mp_policy.deserialize(
                config, custom_objects={'MyPolicy': MyPolicy})
            self.assertEqual(str(policy), str(new_policy))

        # Test V1 policies that override the loss scale
        for policy in (
                mp_policy.PolicyV1('float32', loss_scale=2.),
                mp_policy.PolicyV1('float32', loss_scale=None),
                mp_policy.PolicyV1('mixed_float16', loss_scale=2.),
                mp_policy.PolicyV1('mixed_float16', loss_scale=None),
                mp_policy.PolicyV1('mixed_bfloat16', loss_scale=2.),
                mp_policy.PolicyV1('mixed_bfloat16', loss_scale=None),
        ):
            config = mp_policy.serialize(policy)
            expected_loss_scale_config = None
            if policy.loss_scale:
                expected_loss_scale_config = {
                    'class_name': 'FixedLossScale',
                    'config': {
                        'loss_scale_value': 2.
                    }
                }
            self.assertEqual(
                config, {
                    'class_name': policy.__class__.__name__,
                    'config': {
                        'name': policy.name,
                        'loss_scale': expected_loss_scale_config
                    }
                })
Esempio n. 9
0
    def test_config_policy_v1(self, strategy_fn):
        x = constant_op.constant([1.], dtype=dtypes.float16)
        with strategy_fn().scope():

            layer = mp_test_util.MultiplyLayer(
                dtype=policy.PolicyV1('mixed_float16', loss_scale=None))
            config = layer.get_config()
            self.assertEqual(
                config['dtype'], {
                    'class_name': 'PolicyV1',
                    'config': {
                        'name': 'mixed_float16',
                        'loss_scale': None
                    }
                })
            layer = mp_test_util.MultiplyLayer.from_config(config)
            self.assertEqual(layer.dtype, 'float32')
            self.assertEqual(layer(x).dtype, 'float16')
            self.assertEqual(layer.v.dtype, 'float32')
            # Restoring a PolicyV1 silently converts it to a Policy and drops the loss
            # scale.
            self.assertEqual(type(layer.dtype_policy), policy.Policy)
            config = layer.get_config()
            # The loss_scale is silently dropped
            self.assertEqual(config['dtype'], {
                'class_name': 'Policy',
                'config': {
                    'name': 'mixed_float16'
                }
            })

            layer = mp_test_util.MultiplyLayer(
                dtype=policy.PolicyV1('float64', loss_scale=2.))
            config = layer.get_config()
            self.assertEqual(
                config['dtype'], {
                    'class_name': 'PolicyV1',
                    'config': {
                        'name': 'float64',
                        'loss_scale': {
                            'class_name': 'FixedLossScale',
                            'config': {
                                'loss_scale_value': 2.0
                            }
                        }
                    }
                })
            layer = mp_test_util.MultiplyLayer.from_config(config)
            self.assertEqual(layer.dtype, 'float64')
            self.assertEqual(layer(x).dtype, 'float64')
            self.assertEqual(layer.v.dtype, 'float64')
            self.assertEqual(type(layer.dtype_policy), policy.Policy)
            config = layer.get_config()
            self.assertEqual(config['dtype'], 'float64')

            layer = mp_test_util.MultiplyLayer(
                dtype=policy.PolicyV1('_infer', loss_scale=2.))
            config = layer.get_config()
            self.assertEqual(
                config['dtype'], {
                    'class_name': 'PolicyV1',
                    'config': {
                        'name': '_infer',
                        'loss_scale': {
                            'class_name': 'FixedLossScale',
                            'config': {
                                'loss_scale_value': 2.0
                            }
                        }
                    }
                })
            layer = mp_test_util.MultiplyLayer.from_config(config)
            self.assertEqual(layer.dtype, None)
            self.assertEqual(layer(x).dtype, 'float16')
            self.assertEqual(layer.v.dtype, 'float16')
            self.assertEqual(type(layer.dtype_policy), policy.Policy)
            config = layer.get_config()
            self.assertEqual(config['dtype'], 'float16')