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:
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:
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:
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()
:
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)