Ejemplo n.º 1
0
    def test_tf_conversion(self, qnode, tol):
        """Tests that the to_tf() function ignores QNodes that already
        have the TF interface."""
        converted_qnode = to_tf(qnode)
        assert converted_qnode is qnode

        x = tf.Variable(0.4)

        with tf.GradientTape() as tape:
            res = converted_qnode(x)

        assert np.allclose(res, tf.cos(x), atol=tol, rtol=0)

        grad = tape.gradient(res, x)
        assert np.allclose(grad, -tf.sin(x), atol=tol, rtol=0)
Ejemplo n.º 2
0
    def test_other_conversion(self, qnode, tol):
        """Tests that the to_tf() function correctly converts both torch and autograd qnodes
        and QNodes with no interface."""
        converted_qnode = to_tf(qnode)
        assert converted_qnode is not qnode
        assert converted_qnode._qnode is getattr(qnode, "_qnode", qnode)

        x = tf.Variable(0.4)

        with tf.GradientTape() as tape:
            res = converted_qnode(x)

        assert np.allclose(res, tf.cos(x), atol=tol, rtol=0)

        grad = tape.gradient(res, x)
        assert np.allclose(grad, -tf.sin(x), atol=tol, rtol=0)
Ejemplo n.º 3
0
    def __init__(self,
                 qnode,
                 weight_shapes: dict,
                 output_dim: Iterable,
                 weight_specs: Optional[dict] = None,
                 *args,
                 **kwargs):
        if not CORRECT_TF_VERSION:
            raise ImportError(
                "Quanv2D requires TensorFlow version 2 or above. The latest "
                "version of TensorFlow can be installed using:\n"
                "pip install tensorflow --upgrade\nAlternatively, visit "
                "https://www.tensorflow.org/install for detailed instructions."
            )

        self.weight_shapes = {
            weight: (tuple(size) if isinstance(size, Iterable) else
                     (size, ) if size > 1 else ())
            for weight, size in weight_shapes.items()
        }

        if qml.tape_mode_active():
            self._signature_validation_tape_mode(qnode, weight_shapes)
            self.qnode = qnode

            dtype = tf.float32 if tf.keras.backend.floatx(
            ) == tf.float32 else tf.float64

            if self.qnode.diff_method != "backprop":
                self.qnode.to_tf(dtype=dtype)
        else:
            self._signature_validation(qnode, weight_shapes)
            self.qnode = to_tf(qnode, dtype=tf.keras.backend.floatx())

        # Output dim must be an iterable with at least 2 dimensions (possibly a third for channels) TODO check this
        if len(output_dim) != 3:
            raise ValueError(
                "Output must have three dimensions (the 2 image dimensions and one for the channels)"
            )
        else:
            self.output_dim = output_dim

        self.weight_specs = weight_specs if weight_specs is not None else {}

        self.qnode_weights = {}

        super().__init__(dynamic=True, *args, **kwargs)
Ejemplo n.º 4
0
    def __init__(self,
                 qnode,
                 weight_shapes: dict,
                 output_dim,
                 weight_specs: Optional[dict] = None,
                 **kwargs):
        if not CORRECT_TF_VERSION:
            raise ImportError(
                "KerasLayer requires TensorFlow version 2 or above. The latest "
                "version of TensorFlow can be installed using:\n"
                "pip install tensorflow --upgrade\nAlternatively, visit "
                "https://www.tensorflow.org/install for detailed instructions."
            )

        self.weight_shapes = {
            weight: (tuple(size) if isinstance(size, Iterable) else
                     (size, ) if size > 1 else ())
            for weight, size in weight_shapes.items()
        }

        if qml.tape_mode_active():
            self._signature_validation_tape_mode(qnode, weight_shapes)
            self.qnode = qnode

            dtype = tf.float32 if tf.keras.backend.floatx(
            ) == tf.float32 else tf.float64

            if self.qnode.diff_method != "backprop":
                self.qnode.to_tf(dtype=dtype)
        else:
            self._signature_validation(qnode, weight_shapes)
            self.qnode = to_tf(qnode, dtype=tf.keras.backend.floatx())

        # Allows output_dim to be specified as an int, e.g., 5, or as a length-1 tuple, e.g., (5,)
        self.output_dim = output_dim[0] if isinstance(output_dim,
                                                      Iterable) else output_dim

        self.weight_specs = weight_specs if weight_specs is not None else {}

        self.qnode_weights = {}

        super().__init__(dynamic=True, **kwargs)
Ejemplo n.º 5
0
    def __init__(self,
                 qnode,
                 weight_shapes: dict,
                 output_dim,
                 weight_specs: Optional[dict] = None,
                 **kwargs):
        if not CORRECT_TF_VERSION:
            raise ImportError(
                "KerasLayer requires TensorFlow version 2 or above. The latest "
                "version of TensorFlow can be installed using:\n"
                "pip install tensorflow --upgrade\nAlternatively, visit "
                "https://www.tensorflow.org/install for detailed instructions."
            )

        self.sig = qnode.func.sig

        if self.input_arg not in self.sig:
            raise TypeError(
                "QNode must include an argument with name {} for inputting data"
                .format(self.input_arg))

        if self.input_arg in set(weight_shapes.keys()):
            raise ValueError(
                "{} argument should not have its dimension specified in "
                "weight_shapes".format(self.input_arg))

        if set(weight_shapes.keys()) | {self.input_arg} != set(
                self.sig.keys()):
            raise ValueError(
                "Must specify a shape for every non-input parameter in the QNode"
            )

        if qnode.func.var_pos:
            raise TypeError(
                "Cannot have a variable number of positional arguments")

        if qnode.func.var_keyword:
            raise TypeError(
                "Cannot have a variable number of keyword arguments")

        self.qnode = to_tf(qnode, dtype=tf.keras.backend.floatx())
        self.weight_shapes = {
            weight: (tuple(size) if isinstance(size, Iterable) else
                     (size, ) if size > 1 else ())
            for weight, size in weight_shapes.items()
        }

        # Allows output_dim to be specified as an int, e.g., 5, or as a length-1 tuple, e.g., (5,)
        self.output_dim = output_dim[0] if isinstance(output_dim,
                                                      Iterable) else output_dim

        defaults = {
            name
            for name, sig in self.sig.items()
            if sig.par.default != inspect.Parameter.empty
        }
        self.input_is_default = self.input_arg in defaults
        if defaults - {self.input_arg} != set():
            raise TypeError(
                "Only the argument {} is permitted to have a default".format(
                    self.input_arg))

        self.weight_specs = weight_specs if weight_specs is not None else {}

        self.qnode_weights = {}

        super().__init__(dynamic=True, **kwargs)