Exemplo n.º 1
0
    def test_works_with_registered(self):
        class CustomClass(object):
            def value(self):
                return tf.convert_to_tensor(42.)

        tf.register_tensor_conversion_function(
            CustomClass, lambda value, **_: value.value())

        tf_utils.register_symbolic_tensor_type(CustomClass)

        if tf.executing_eagerly():
            self.assertFalse(
                tf_utils.is_symbolic_tensor(
                    tf.Variable(name='blah', initial_value=0.)))
            self.assertFalse(
                tf_utils.is_symbolic_tensor(tf.convert_to_tensor(0.)))
            self.assertFalse(
                tf_utils.is_symbolic_tensor(
                    tf.SparseTensor(indices=[[0, 0], [1, 2]],
                                    values=[1, 2],
                                    dense_shape=[3, 4])))
            self.assertFalse(tf_utils.is_symbolic_tensor(CustomClass()))
        else:
            self.assertTrue(
                tf_utils.is_symbolic_tensor(
                    tf.Variable(name='blah', initial_value=0.)))
            self.assertTrue(
                tf_utils.is_symbolic_tensor(tf.convert_to_tensor(0.)))
            self.assertTrue(
                tf_utils.is_symbolic_tensor(
                    tf.SparseTensor(indices=[[0, 0], [1, 2]],
                                    values=[1, 2],
                                    dense_shape=[3, 4])))
            self.assertTrue(tf_utils.is_symbolic_tensor(CustomClass()))
Exemplo n.º 2
0
    def apply_gradients(self, grads_and_vars, **kwargs):
        """Wrapped apply_gradient method.

        Returns an operation to be executed.
        """

        for spec in self.optimizer_specs:
            spec["gv"] = []

        for grad, var in tuple(grads_and_vars):
            for spec in self.optimizer_specs:
                for name in spec["weights"]:
                    if var.name == name:
                        spec["gv"].append((grad, var))

        update_ops = [
            spec["optimizer"].apply_gradients(spec["gv"], **kwargs)
            for spec in self.optimizer_specs
        ]
        update_group = tf.group(update_ops)

        any_symbolic = any(
            isinstance(i, tf.Operation) or tf_utils.is_symbolic_tensor(i)
            for i in update_ops)

        if not tf.executing_eagerly() or any_symbolic:
            # If the current context is graph mode or any of the update ops are
            # symbolic then the step update should be carried out under a graph
            # context. (eager updates execute immediately)
            with backend._current_graph(  # pylint: disable=protected-access
                    update_ops).as_default():
                with tf.control_dependencies([update_group]):
                    return self.iterations.assign_add(1, read_value=False)

        return self.iterations.assign_add(1)
Exemplo n.º 3
0
 def test_dict_eager(self):
     if not tf.executing_eagerly():
         self.skipTest('Run in eager mode only.')
     with testing_utils.use_keras_tensors_scope(False):
         a = {'b': np.ones(10), 'a': np.ones(20)}
         model_inputs = training_utils_v1.ModelInputs(a)
         self.assertEqual(['a', 'b'], model_inputs.get_input_names())
         vals = model_inputs.get_symbolic_inputs()
         self.assertTrue(tf_utils.is_symbolic_tensor(vals['a']))
         self.assertTrue(tf_utils.is_symbolic_tensor(vals['b']))
     with testing_utils.use_keras_tensors_scope(True):
         a = {'b': np.ones(10), 'a': np.ones(20)}
         model_inputs = training_utils_v1.ModelInputs(a)
         self.assertEqual(['a', 'b'], model_inputs.get_input_names())
         vals = model_inputs.get_symbolic_inputs()
         self.assertIsInstance(vals['a'], keras_tensor.KerasTensor)
         self.assertIsInstance(vals['b'], keras_tensor.KerasTensor)
Exemplo n.º 4
0
    def test_simple_build_with_constant(self):
        class BuildConstantLayer(keras.layers.Layer):
            def build(self, input_shape):
                self.b = tf.convert_to_tensor(2.0)

            def call(self, inputs):
                return self.b * inputs

        layer = BuildConstantLayer()
        model = testing_utils.get_model_from_layers(
            [layer, keras.layers.Dense(1)], input_shape=(1, ))

        x = tf.convert_to_tensor([[3.0]])
        self.assertEqual(tf_utils.is_symbolic_tensor(model(x)),
                         not tf.executing_eagerly())
        self.assertEqual(tf_utils.is_symbolic_tensor(layer(x)),
                         not tf.executing_eagerly())
        self.assertAllClose(keras.backend.get_value(layer(x)), [[6.0]])
Exemplo n.º 5
0
    def test_build_with_derived_constant(self):
        class BuildDerivedConstantLayer(keras.layers.Layer):
            def build(self, input_shape):
                a = tf.convert_to_tensor(1.0)
                b = 2.0 * a
                self.variable = tf.Variable(b)
                self.constant = tf.convert_to_tensor(self.variable)

            def call(self, inputs):
                return self.variable * self.constant * inputs

        layer = BuildDerivedConstantLayer()
        model = testing_utils.get_model_from_layers(
            [layer, keras.layers.Dense(1)], input_shape=(1, ))

        x = tf.convert_to_tensor([[3.0]])
        self.assertEqual(tf_utils.is_symbolic_tensor(model(x)),
                         not tf.executing_eagerly())
        self.assertEqual(tf_utils.is_symbolic_tensor(layer(x)),
                         not tf.executing_eagerly())
        self.assertAllClose(keras.backend.get_value(layer(x)), [[12.0]])
Exemplo n.º 6
0
 def test_default_behavior(self):
     if tf.executing_eagerly():
         self.assertFalse(
             tf_utils.is_symbolic_tensor(
                 tf.Variable(name="blah", initial_value=0.0)))
         self.assertFalse(
             tf_utils.is_symbolic_tensor(tf.convert_to_tensor(0.0)))
         self.assertFalse(
             tf_utils.is_symbolic_tensor(
                 tf.SparseTensor(
                     indices=[[0, 0], [1, 2]],
                     values=[1, 2],
                     dense_shape=[3, 4],
                 )))
     else:
         self.assertTrue(
             tf_utils.is_symbolic_tensor(
                 tf.Variable(name="blah", initial_value=0.0)))
         self.assertTrue(
             tf_utils.is_symbolic_tensor(tf.convert_to_tensor(0.0)))
         self.assertTrue(
             tf_utils.is_symbolic_tensor(
                 tf.SparseTensor(
                     indices=[[0, 0], [1, 2]],
                     values=[1, 2],
                     dense_shape=[3, 4],
                 )))
Exemplo n.º 7
0
 def test_single_thing_eager(self):
     if not tf.executing_eagerly():
         self.skipTest('Run in eager mode only.')
     with testing_utils.use_keras_tensors_scope(False):
         a = np.ones(10, dtype=np.int32)
         model_inputs = training_utils_v1.ModelInputs(a)
         self.assertEqual(['input_1'], model_inputs.get_input_names())
         val = model_inputs.get_symbolic_inputs()
         self.assertTrue(tf_utils.is_symbolic_tensor(val))
         vals = model_inputs.get_symbolic_inputs(return_single_as_list=True)
         self.assertEqual(1, len(vals))
         self.assertTrue(tf_utils.is_symbolic_tensor(vals[0]))
         self.assertEqual(tf.int32, vals[0].dtype)
     with testing_utils.use_keras_tensors_scope(True):
         a = np.ones(10, dtype=np.int32)
         model_inputs = training_utils_v1.ModelInputs(a)
         self.assertEqual(['input_1'], model_inputs.get_input_names())
         val = model_inputs.get_symbolic_inputs()
         self.assertIsInstance(val, keras_tensor.KerasTensor)
         vals = model_inputs.get_symbolic_inputs(return_single_as_list=True)
         self.assertEqual(1, len(vals))
         self.assertIsInstance(vals[0], keras_tensor.KerasTensor)
         self.assertEqual(tf.int32, vals[0].dtype)
Exemplo n.º 8
0
    def __init__(
        self,
        input_shape=None,
        batch_size=None,
        dtype=None,
        input_tensor=None,
        sparse=None,
        name=None,
        ragged=None,
        type_spec=None,
        **kwargs,
    ):
        self._init_input_shape = input_shape
        self._init_batch_size = batch_size
        self._init_dtype = dtype
        self._init_sparse = sparse
        self._init_ragged = ragged
        self._init_type_spec = type_spec

        strategy = tf.distribute.get_strategy()
        if (strategy and batch_size is not None
                and distributed_training_utils.global_batch_size_supported(
                    strategy)):
            if batch_size % strategy.num_replicas_in_sync != 0:
                raise ValueError(
                    "The `batch_size` argument ({}) must be divisible by "
                    "the number of replicas ({})".format(
                        batch_size, strategy.num_replicas_in_sync))
            batch_size = batch_size // strategy.num_replicas_in_sync

        if "batch_input_shape" in kwargs:
            batch_input_shape = kwargs.pop("batch_input_shape")
            if input_shape and batch_input_shape:
                raise ValueError("Only provide the input_shape OR "
                                 "batch_input_shape argument to "
                                 "InputLayer, not both at the same time.")
            # Set the input shape and batch size from the batch_input_shape.
            # Note that batch_input_shape can be None (unknown rank) or [] (scalar),
            # in which case the batch size must be None.
            if batch_input_shape:
                batch_size = batch_input_shape[0]
                input_shape = batch_input_shape[1:]
        if kwargs:
            raise ValueError(
                f"Unrecognized keyword arguments: {list(kwargs.keys())}")

        if sparse and ragged:
            raise ValueError(
                "Cannot set both sparse and ragged to True in a Keras input.")

        if not name:
            prefix = "input"
            name = prefix + "_" + str(backend.get_uid(prefix))

        if not dtype:
            if input_tensor is None:
                dtype = backend.floatx()
            else:
                dtype = backend.dtype(input_tensor)
        elif input_tensor is not None and input_tensor.dtype != dtype:
            raise ValueError(
                "`input_tensor.dtype` differs from `dtype`. Received: "
                f"input_tensor.dtype={input_tensor.dtype} "
                f"but expected dtype={dtype}")
        super().__init__(dtype=dtype, name=name)
        self.built = True
        self.sparse = True if sparse else False
        self.ragged = True if ragged else False
        self.batch_size = batch_size
        self.supports_masking = True

        if isinstance(input_shape, tf.TensorShape):
            input_shape = tuple(input_shape.as_list())
        elif isinstance(input_shape, int):
            input_shape = (input_shape, )

        if type_spec is not None:
            args_that_must_be_none = [
                ("(input_)shape", self._init_input_shape),
                ("batch_size", self._init_batch_size),
                ("dtype", self._init_dtype),
                ("input_tensor", input_tensor),
                ("sparse", self._init_sparse),
                ("ragged", self._init_ragged),
            ]
            for arg_name, arg in args_that_must_be_none:
                _assert_other_arg_none(arg_name, arg)
            if not tf.compat.v1.executing_eagerly_outside_functions():
                raise ValueError(
                    "Creating Keras inputs from a type_spec is only "
                    "supported when eager execution is enabled.")
            input_tensor = keras_tensor.keras_tensor_from_type_spec(type_spec)
            if isinstance(input_tensor, keras_tensor.SparseKerasTensor):
                self.sparse = True
            if isinstance(input_tensor, keras_tensor.RaggedKerasTensor):
                self.ragged = True
            self.is_placeholder = True
            try:
                self._batch_input_shape = tuple(input_tensor.shape.as_list())
            except ValueError:
                # If the shape cannot be represented as a tuple (e.g. unknown rank)
                self._batch_input_shape = None
        elif input_tensor is None:
            if input_shape is not None:
                batch_input_shape = (batch_size, ) + tuple(input_shape)
            else:
                batch_input_shape = None
            graph = backend.get_graph()
            with graph.as_default():
                input_tensor = backend.placeholder(
                    shape=batch_input_shape,
                    dtype=dtype,
                    name=self.name,
                    sparse=sparse,
                    ragged=ragged,
                )

            self.is_placeholder = True
            self._batch_input_shape = batch_input_shape
        else:
            if tf.compat.v1.executing_eagerly_outside_functions():
                if not isinstance(input_tensor, keras_tensor.KerasTensor):
                    input_tensor = keras_tensor.keras_tensor_from_tensor(
                        input_tensor)
            else:
                if not tf_utils.is_symbolic_tensor(input_tensor):
                    raise ValueError(
                        "You should not pass an EagerTensor to `Input`. "
                        "For example, instead of creating an "
                        "`InputLayer`, you should instantiate your model "
                        "and directly call it on your input.")
            self.is_placeholder = False
            try:
                self._batch_input_shape = tuple(input_tensor.shape.as_list())
            except ValueError:
                # If the shape cannot be represented as a tuple (e.g. unknown rank)
                self._batch_input_shape = None
        # Create an input node.
        input_tensor._keras_mask = None
        node_module.Node(layer=self, outputs=input_tensor)

        # Store type spec
        if isinstance(input_tensor, keras_tensor.KerasTensor) or (
                tf_utils.is_extension_type(input_tensor)):
            self._type_spec = (input_tensor._type_spec)  # pylint: disable=protected-access
        else:
            self._type_spec = tf.TensorSpec(
                shape=input_tensor.shape,
                dtype=input_tensor.dtype,
                name=self.name,
            )
Exemplo n.º 9
0
    def __init__(self,
                 input_shape=None,
                 batch_size=None,
                 dtype=None,
                 input_tensor=None,
                 sparse=None,
                 name=None,
                 ragged=None,
                 type_spec=None,
                 **kwargs):
        self._init_input_shape = input_shape
        self._init_batch_size = batch_size
        self._init_dtype = dtype
        self._init_sparse = sparse
        self._init_ragged = ragged
        self._init_type_spec = type_spec

        strategy = tf.distribute.get_strategy()
        if strategy and batch_size is not None and \
            distributed_training_utils.global_batch_size_supported(strategy):
            if batch_size % strategy.num_replicas_in_sync != 0:
                raise ValueError(
                    'The `batch_size` argument ({}) must be divisible by '
                    'the number of replicas ({})'.format(
                        batch_size, strategy.num_replicas_in_sync))
            batch_size = batch_size // strategy.num_replicas_in_sync

        if 'batch_input_shape' in kwargs:
            batch_input_shape = kwargs.pop('batch_input_shape')
            if input_shape and batch_input_shape:
                raise ValueError('Only provide the input_shape OR '
                                 'batch_input_shape argument to '
                                 'InputLayer, not both at the same time.')
            batch_size = batch_input_shape[0]
            input_shape = batch_input_shape[1:]
        if kwargs:
            raise ValueError('Unrecognized keyword arguments:', kwargs.keys())

        if sparse and ragged:
            raise ValueError(
                'Cannot set both sparse and ragged to True in a Keras input.')

        if not name:
            prefix = 'input'
            name = prefix + '_' + str(backend.get_uid(prefix))

        if not dtype:
            if input_tensor is None:
                dtype = backend.floatx()
            else:
                dtype = backend.dtype(input_tensor)
        elif input_tensor is not None and input_tensor.dtype != dtype:
            raise ValueError(
                '`input_tensor.dtype` differs from `dtype`: %s vs. %s' %
                (input_tensor.dtype, dtype))
        super(InputLayer, self).__init__(dtype=dtype, name=name)
        self.built = True
        self.sparse = True if sparse else False
        self.ragged = True if ragged else False
        self.batch_size = batch_size
        self.supports_masking = True

        if isinstance(input_shape, tf.TensorShape):
            input_shape = tuple(input_shape.as_list())
        elif isinstance(input_shape, int):
            input_shape = (input_shape, )

        if type_spec is not None:
            args_that_must_be_none = [
                ('(input_)shape', self._init_input_shape),
                ('batch_size', self._init_batch_size),
                ('dtype', self._init_dtype),
                ('input_tensor', input_tensor),
                ('sparse', self._init_sparse),
                ('ragged', self._init_ragged),
            ]
            for arg_name, arg in args_that_must_be_none:
                _assert_other_arg_none(arg_name, arg)
            if not keras_tensor.keras_tensors_enabled():
                raise ValueError(
                    'Creating Keras inputs from a type_spec is only '
                    'supported when eager execution is enabled.')
            input_tensor = keras_tensor.keras_tensor_from_type_spec(type_spec)
            if isinstance(input_tensor, keras_tensor.SparseKerasTensor):
                self.sparse = True
            if isinstance(input_tensor, keras_tensor.RaggedKerasTensor):
                self.ragged = True
            self.is_placeholder = True
            try:
                self._batch_input_shape = tuple(input_tensor.shape.as_list())
            except ValueError:
                # If the shape cannot be represented as a tuple (e.g. unknown rank)
                self._batch_input_shape = None
        elif input_tensor is None:
            if input_shape is not None:
                batch_input_shape = (batch_size, ) + tuple(input_shape)
            else:
                batch_input_shape = None
            graph = backend.get_graph()
            with graph.as_default():
                input_tensor = backend.placeholder(shape=batch_input_shape,
                                                   dtype=dtype,
                                                   name=self.name,
                                                   sparse=sparse,
                                                   ragged=ragged)

            self.is_placeholder = True
            self._batch_input_shape = batch_input_shape
        else:
            if keras_tensor.keras_tensors_enabled():
                if not isinstance(input_tensor, keras_tensor.KerasTensor):
                    input_tensor = keras_tensor.keras_tensor_from_tensor(
                        input_tensor)
            else:
                if not tf_utils.is_symbolic_tensor(input_tensor):
                    raise ValueError(
                        'You should not pass an EagerTensor to `Input`. '
                        'For example, instead of creating an '
                        'InputLayer, you should instantiate your model and '
                        'directly call it on your input.')
            self.is_placeholder = False
            try:
                self._batch_input_shape = tuple(input_tensor.shape.as_list())
            except ValueError:
                # If the shape cannot be represented as a tuple (e.g. unknown rank)
                self._batch_input_shape = None
        # Create an input node.
        input_tensor._keras_mask = None
        node_module.Node(layer=self, outputs=input_tensor)

        # Store type spec
        if isinstance(input_tensor, keras_tensor.KerasTensor) or (
                tf_utils.is_extension_type(input_tensor)):
            self._type_spec = input_tensor._type_spec  # pylint: disable=protected-access
        else:
            self._type_spec = tf.TensorSpec(shape=input_tensor.shape,
                                            dtype=input_tensor.dtype,
                                            name=self.name)