# Trying to build a Quantum Convolution but 'DefaultQubit' object has no attribute 'reset'

**URL:** https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891
**Category:** PennyLane Help
**Created:** [January 14, 2024, 3:15pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891 "2024-01-14T15:15:19Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![joaofbravo](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/joaofbravo/32/1770_2.png) [@joaofbravo](https://discuss.pennylane.ai/u/joaofbravo)
#### Post date: [January 14, 2024, 3:15pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/1 "2024-01-14T15:15:19Z")

</div>

Hi! I want to make a quantum convolution layer for a hybrid CNN model trainable.

I was trying make a single Keras layer out of it so I could just add it to my CNN model. However, since the quantum convolution requires applying one circuit many times with different parameters depending on the image patch I am looking at, I need to run multiple circuits inside the QNode. I tried to build a loop where I do it for every image patch at once. However I get the error:

```auto
ValueError: ops operation Rot must occur prior to measurements. Please place earlier in the queue.

```

after the first iteration. I tried to reset the full circuit with `dev.reset()` but apparently the DefaultQubit device does not have a reset method. Why is this?

Is there a way of making this work or do you suggest doing things differently?  
Should I make a Keras layer out of the circuit itself and then call it many times with Keras Functional API or something similar?

_Code idea:_

```auto
dev = qml.device("default.qubit", wires=n_qubits)
out = np.empty(shape, dtype=qml.measurements.ExpectationMP)

@qml.qnode(dev)
def quantum_convolution(inputs, params):
    for ...:
        ...
        # Assign measurement expectation values to different channels of the output pixel (j/stride, k/stride)
        for c in range(n_qubits):
            out[j // stride, k // stride, c] = qml.expval(qml.PauliZ(c))

        dev.reset() # Try to fix ValueError: ops operation Rot must occur prior to measurements. Please place earlier in the queue.
    return out

qlayer = qml.qnn.KerasLayer(quantum_convolution, params_shape, output_dim=((image_height-2) // stride + 1, (image_width-2) // stride + 1, n_qubits))

```

_Full error message:_

```auto
AttributeError Traceback (most recent call last)
Cell In[20], line 50
     47 params_shape = {"params": n_qubits*3*2}
     48 qlayer = qml.qnn.KerasLayer(quantum_convolution, params_shape, output_dim=((image_height-2) // stride + 1, (image_width-2) // stride + 1, n_qubits))
---> 50 quantum_convolution(train_images[0], rand_params)

File c:\Users\bravo\AppData\Local\anaconda3\envs\qml\lib\site-packages\pennylane\qnode.py:970, in QNode. __call__ (self, *args, **kwargs)
    967 kwargs["shots"] = _get_device_shots(self._original_device)
    969 # construct the tape
--> 970 self.construct(args, kwargs)
    972 cache = self.execute_kwargs.get("cache", False)
    973 using_custom_cache = (
    974 hasattr(cache, " __getitem__")
    975 and hasattr(cache, " __setitem__")
    976 and hasattr(cache, " __delitem__")
    977 )

File c:\Users\bravo\AppData\Local\anaconda3\envs\qml\lib\site-packages\pennylane\qnode.py:856, in QNode.construct(self, args, kwargs)
    853 self.interface = qml.math.get_interface(*args, *list(kwargs.values()))
    855 with qml.queuing.AnnotatedQueue() as q:
--> 856 self._qfunc_output = self.func(*args, **kwargs)
    858 self._tape = QuantumScript.from_queue(q, shots)
    860 params = self.tape.get_parameters(trainable_only=False)

Cell In[20], line 43
     40 for c in range(n_qubits):
     41 out[j // stride, k // stride, c] = qml.expval(qml.PauliZ(c))
---> 43 dev.reset() # Try to fix ValueError: ops operation Rot must occur prior to measurements. Please place earlier in the queue.
     44 return out

AttributeError: 'DefaultQubit' object has no attribute 'reset'

```

_Output of `qml.about()`:_

```auto
Name: PennyLane
Version: 0.33.1
Summary: PennyLane is a Python quantum machine learning library by Xanadu Inc.
Home-page: https://github.com/PennyLaneAI/pennylane
Author: 
Author-email: 
License: Apache License 2.0
Location: c:\users\bravo\appdata\local\anaconda3\envs\qml\lib\site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane-Cirq, PennyLane-Lightning, PennyLane-qiskit

Platform info: Windows-10-10.0.19045-SP0
Python version: 3.10.11
Numpy version: 1.24.3
Scipy version: 1.11.2
Installed devices:
- default.gaussian (PennyLane-0.33.1)
- default.mixed (PennyLane-0.33.1)
- default.qubit (PennyLane-0.33.1)
- default.qubit.autograd (PennyLane-0.33.1)
- default.qubit.jax (PennyLane-0.33.1)
- default.qubit.legacy (PennyLane-0.33.1)
- default.qubit.tf (PennyLane-0.33.1)
- default.qubit.torch (PennyLane-0.33.1)
- default.qutrit (PennyLane-0.33.1)
- null.qubit (PennyLane-0.33.1)
- cirq.mixedsimulator (PennyLane-Cirq-0.33.0)
- cirq.pasqal (PennyLane-Cirq-0.33.0)
- cirq.qsim (PennyLane-Cirq-0.33.0)
- cirq.qsimh (PennyLane-Cirq-0.33.0)
- cirq.simulator (PennyLane-Cirq-0.33.0)
- lightning.qubit (PennyLane-Lightning-0.33.1)
- qiskit.aer (PennyLane-qiskit-0.33.0)
- qiskit.basicaer (PennyLane-qiskit-0.33.0)
- qiskit.ibmq (PennyLane-qiskit-0.33.0)
- qiskit.ibmq.circuit_runner (PennyLane-qiskit-0.33.0)
- qiskit.ibmq.sampler (PennyLane-qiskit-0.33.0)
- qiskit.remote (PennyLane-qiskit-0.33.0)

```

---

<div class="post-metadata">

### Author: ![isaacdevlugt](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/isaacdevlugt/32/1159_2.png) [@isaacdevlugt](https://discuss.pennylane.ai/u/isaacdevlugt)
#### Post date: [January 17, 2024, 12:51am UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/2 "2024-01-17T00:51:31Z")

</div>

Hey @joaofbravo, welcome back!

A few releases ago, we totally revamped our device API. So, some features were added and others were removed. You can access the old device API by using `default.qubit.legacy` 🙂. Let me know if that solves things!

---

<div class="post-metadata">

### Author: ![joaofbravo](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/joaofbravo/32/1770_2.png) [@joaofbravo](https://discuss.pennylane.ai/u/joaofbravo)
#### Post date: [January 22, 2024, 9:01am UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/3 "2024-01-22T09:01:14Z")

</div>

Hi. With the legacy device, it accepts the reset method but still gives the initial error

```auto
ValueError: ops operation Rot must occur prior to measurements. Please place earlier in the queue.

```

---

<div class="post-metadata">

### Author: ![isaacdevlugt](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/isaacdevlugt/32/1159_2.png) [@isaacdevlugt](https://discuss.pennylane.ai/u/isaacdevlugt)
#### Post date: [January 23, 2024, 11:02pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/4 "2024-01-23T23:02:47Z")

</div>

Hey @joaofbravo, can you attach your full code just so that I can try to replicate the error? In the mean time, let me ask one of the PennyLane developers to see if they know something I don’t 😃

---

<div class="post-metadata">

### Author: ![joaofbravo](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/joaofbravo/32/1770_2.png) [@joaofbravo](https://discuss.pennylane.ai/u/joaofbravo)
#### Post date: [January 24, 2024, 9:56am UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/5 "2024-01-24T09:56:28Z")

</div>

I cannot share my data but here is a version without explicit data. I generated random data for you to see the error. This comes from a Jupyter notebook and you can run it cell by cell in VS Code.

[qccnn\_trainable\_dummy.py](https://discuss.pennylane.ai/uploads/short-url/dFTR3MDVFalrK1A9KN2eBZlxzMs.py) (12.4 KB)

The cell starting with

> # test full quantum convolution in one layer

is the trial with the `dev.reset()` method. The errors I experience are written as comments at the end of the cell.

I also tried to use Keras Functional API in the cell starting with

> # test Keras Functional API

Here, I create the Keras layer named QuantumConv from one quantum circuit and then apply the layer many times to each image patch. However, I get another error when using the QuantumConv layer: `Input to reshape is a tensor with 4 values, but the requested shape has 64 [Op:Reshape]`.

This makes it seem like the implementation of `qml.qnn.KerasLayer` has some issue or maybe it is just my ignorance. I set the custom layer to receive 64 samples of 4 values but it is only receiving 1 sample of 4 values and assumes those values as the first dimension.

I wrote about it on StackOverflow [here](https://stackoverflow.com/questions/77861443/tensorflow-keras-error-input-to-reshape-is-a-tensor-with-x-values-but-the-requ).

---

<div class="post-metadata">

### Author: ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)
#### Post date: [January 24, 2024, 1:39pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/6 "2024-01-24T13:39:34Z")

</div>

Hi @joaofbravo! I just want to take a step back for a second and understand what you would like to do. Do you want to:

- Have an input circuit
- Map the input circuit to a batch of new circuits, e.g., with slightly different parameters
- Execute the batch of circuits
- Do some calculation on the execution results

If so, I’d recommend [creating your own transform](https://docs.pennylane.ai/en/stable/code/qml_transforms.html#creating-your-own-transform). When applying a transform to your target QNode, PennyLane will be able to take care of the batch creation and execution.

If this sounds along the right lines, we’d be happy to help you with creating the transform.

---

<div class="post-metadata">

### Author: ![joaofbravo](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/joaofbravo/32/1770_2.png) [@joaofbravo](https://discuss.pennylane.ai/u/joaofbravo)
#### Post date: [January 24, 2024, 1:48pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/7 "2024-01-24T13:48:59Z")

</div>

I want to create a Keras model with one trainable Quantum Convolution layer and one classical Dense layer.

I tried two things:

- building the Quantum Convolution layer all with Pennylane and then using `qml.qnn.KerasLayer` to get a usable Keras layer.

- Using `qml.qnn.KerasLayer` to turn the Quantum convolution step of applying the quantum circuit to one image patch into one layer and then using this layer many times for all image patches.

Both are not working.

Your description sounds along the lines of what I want this Quantum Convolution to behave like. For now, the circuit structure is fixed but I would like to change it on the fly at some point. If “Map the input circuit to a batch of new circuits” includes the typical ML training process of inputting values to some parameters and then training the trainable parameters according to some loss function, then yes.  
If you could help me do it I would appreciate it a lot.

---

<div class="post-metadata">

### Author: ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)
#### Post date: [January 25, 2024, 2:27pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/8 "2024-01-25T14:27:40Z")

</div>

@joaofbravo ok I think that transforms _might_ work here, though I still need to fully understand the objective. Are you able to share a small-scale example of the circuits you want to run? E.g., as a small script or even just the `qml.draw()` drawing of the circuits.

---

<div class="post-metadata">

### Author: ![joaofbravo](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/joaofbravo/32/1770_2.png) [@joaofbravo](https://discuss.pennylane.ai/u/joaofbravo)
#### Post date: [January 25, 2024, 8:28pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/9 "2024-01-25T20:28:03Z")

</div>

Thanks Tom. Yeah, the py file I shared has that code already.  
I am trying to do the same yet again, now with Keras model subclassing. Let’s see if I can make it work but I doubt it. The circuit is this:

```auto
# Create a quantum device
self.dev = qml.device(device, wires=n_qubits)

# Define the trainable quantum circuit
# @qml.qnode(self.dev, interface='tensorfloww')
@qml.qnode(self.dev)
def circuit(inputs, params):
    # Apply trainable encoding operations on each qubit
    for i in range(self.n_qubits):
        qml.Rot(params[i] * inputs[i] + params[i + self.n_qubits],
                params[i + 2 * self.n_qubits] * inputs[i] + params[i + 3 * self.n_qubits],
                params[i + 4 * self.n_qubits] * inputs[i] + params[i + 5 * self.n_qubits],
                wires=i)

    # Apply circular entanglement
    for i in range(self.n_qubits):
        qml.CNOT(wires=[i, (i + 1) % self.n_qubits])

    # Measure all qubits
    # return [qml.expval(qml.PauliZ(i)) for i in range(self.n_qubits)]
    return qml.expval(qml.PauliZ(0))
  
# Convert quantum circuit to a Keras layer
# params_shape = {"params": n_qubits*3*2}
# self.circuit = qml.qnn.KerasLayer(circuit, params_shape, output_dim=n_qubits, trainable=True, name='QuantumConv')
self.circuit = circuit

```

Here is the cute version:

 ![image](https://canada1.discourse-cdn.com/flex012/uploads/pennylane/original/2X/a/a700ef3ba38b821223a7c65b5190c6ba4269e1f1.png)

I would also like to try global measurements but I commented the line to try to make the simpler case work first

---

<div class="post-metadata">

### Author: ![CatalinaAlbornoz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/catalinaalbornoz/32/1196_2.png) [@CatalinaAlbornoz](https://discuss.pennylane.ai/u/CatalinaAlbornoz)
#### Post date: [January 29, 2024, 9:15pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/10 "2024-01-29T21:15:10Z")

</div>

Hi @joaofbravo,  
Thank you for your question!  
We have forwarded this question to members of our technical team who will be getting back to you within a week. Feel free to post any updates to your question here in the thread in the meantime!

---

<div class="post-metadata">

### Author: ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)
#### Post date: [January 31, 2024, 2:24pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/11 "2024-01-31T14:24:52Z")

</div>

Hi @joaofbravo! Sorry for the late response.

I did mention transforms earlier, but if your objective is to support batching over the `inputs` to the circuit, this should work with the following:

```python
import pennylane as qml
import tensorflow as tf
import numpy as np

n_qubits = 5
batch_size = 10

dev = qml.device("default.qubit")

@qml.qnode(dev)
def circuit(inputs, params):
    for i in range(n_qubits):
        qml.Rot(params[i] * inputs[:, i] + params[i + n_qubits],
                params[i + 2 * n_qubits] * inputs[:, i] + params[i + 3 * n_qubits],
                params[i + 4 * n_qubits] * inputs[:, i] + params[i + 5 * n_qubits],
                wires=i)

    for i in range(n_qubits):
        qml.CNOT(wires=[i, (i + 1) % n_qubits])

    return [qml.expval(qml.PauliZ(i)) for i in range(n_qubits)]

np.random.seed(1967)
inputs = tf.Variable(np.random.random((batch_size, n_qubits)), dtype=tf.float32)
weight_shapes = {"params": 6 * n_qubits}

qlayer = qml.qnn.KerasLayer(circuit, weight_shapes, output_dim=n_qubits)

```

Now, you can run `qlayer` with a batched `inputs`:

```pycon
>>> with qml.Tracker(dev) as tracker:
... qlayer(inputs)
<tf.Tensor: shape=(10, 5), dtype=float64, numpy=
array([[0.93605248, 0.99408909, 0.99408903, 0.99371811, 0.93396978],
       [0.96466191, 0.98711064, 0.98701866, 0.98617346, 0.95601068],
       [0.92515829, 0.99426603, 0.99416447, 0.98064854, 0.92399067],
       [0.94792998, 0.99527761, 0.98947615, 0.98812718, 0.9478812],
       [0.9350724 , 0.98666198, 0.98418557, 0.97639893, 0.9241491],
       [0.952517 , 0.98494446, 0.98465518, 0.97125787, 0.94331156],
       [0.9555457 , 0.99163104, 0.98932147, 0.98863627, 0.95170552],
       [0.9693765 , 0.98815707, 0.98808828, 0.98784985, 0.96172342],
       [0.93760943, 0.98209362, 0.9752507 , 0.97349233, 0.9279201],
       [0.9497824 , 0.99702711, 0.99106769, 0.97656875, 0.94877646]])>
>>> tracker.totals
{'batches': 1, 'simulations': 1, 'executions': 10}

```

In the above, PennyLane has automatically handled the input batch dimension so that there is a single batch run, which would require `batch_size` executions on real hardware.

Does this help with what you’re working on?

---

<div class="post-metadata">

### Author: ![joaofbravo](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/joaofbravo/32/1770_2.png) [@joaofbravo](https://discuss.pennylane.ai/u/joaofbravo)
#### Post date: [May 27, 2024, 9:34pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/12 "2024-05-27T21:34:16Z")

</div>

> [@Tom\_Bromley](#):
>
> Hi @joaofbravo! Sorry for the late response.
> 
> I did mention transforms earlier, but if your objective is to support batching over the `inputs` to the circuit, this should work with the following: (…)

Sorry for the very late response too. That worked perfectly indeed. Thanks!

---

<div class="post-metadata">

### Author: ![CatalinaAlbornoz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/catalinaalbornoz/32/1196_2.png) [@CatalinaAlbornoz](https://discuss.pennylane.ai/u/CatalinaAlbornoz)
#### Post date: [May 28, 2024, 4:37pm UTC](https://discuss.pennylane.ai/t/trying-to-build-a-quantum-convolution-but-defaultqubit-object-has-no-attribute-reset/3891/13 "2024-05-28T16:37:59Z")

</div>

Thanks for letting us know @joaofbravo !
