Hybrid quantum-classical machine learning with pytorch and qiskit

username: Sreetama_Das
cooked: <p>First of all, I apologize if this topic is of little interest to most users because of the quantum-classical interface.<br>
I am working with a code for hybrid classical-quantum neural network which can be run on qiskit simulator. I am following the link here<br>
<a href="https://learn.qiskit.org/course/ch-applications/hybrid-quantum-classical-neural-networks-with-pytorch-and-qiskit" rel="noopener nofollow ugc">https://learn.qiskit.org/course/ch-applications/hybrid-quantum-classical-neural-networks-with-pytorch-and-qiskit</a></p>
<p>The example in this link works with a single trainable parameter “theta” in the quantum circuit. However, I want multiple parameters in the quantum circuit. So I modified the QuantumCircuit class as below.</p>
<blockquote>
<p>class QuantumCircuit:<br>
“”"<br>
This class provides a simple interface for interaction<br>
with the quantum circuit<br>
“”"</p>
<pre><code>def __init__(self, n_qubits, backend, shots):
    # --- Circuit definition ---
    self._circuit = qiskit.QuantumCircuit(n_qubits)
    
    all_qubits = [i for i in range(n_qubits)]
    self.theta = qiskit.circuit.ParameterVector('theta', 2)
    
    self._circuit.h(all_qubits)
    self._circuit.barrier()
    self._circuit.ry(self.theta[0], all_qubits)
    self._circuit.ry(self.theta[1], all_qubits)
    
    self._circuit.measure_all()
    # ---------------------------

    self.backend = backend
    self.shots = shots

def run(self, thetas):
  
    job = self.backend.run(transpile([self._circuit.bind_parameters({self.theta: theta}) for theta in thetas], backend=self.backend), shots=self.shots)
    result = job.result().get_counts()
    
    counts = np.array(list(result.values()))
    states = np.array(list(result.keys())).astype(float)
    
    # Compute probabilities for each state
    probabilities = counts / self.shots
    # Get state expectation
    expectation = np.sum(states * probabilities)
    
    return np.array([expectation])
</code></pre>
</blockquote>
<p>I kept everything else same. I am getting the following error:</p>
<blockquote>
<p>Traceback (most recent call last):<br>
File “/home/sreetamadas/Downloads/test.py”, line 198, in <br>
output = model(data)<br>
File “/home/sreetamadas/anaconda3/lib/python3.10/site-packages/torch/nn/modules/module.py”, line 1501, in _call_impl<br>
return forward_call(*args, **kwargs)<br>
File “/home/sreetamadas/Downloads/test.py”, line 180, in forward<br>
x = self.hybrid(x)<br>
File “/home/sreetamadas/anaconda3/lib/python3.10/site-packages/torch/nn/modules/module.py”, line 1501, in _call_impl<br>
return forward_call(*args, **kwargs)<br>
File “/home/sreetamadas/Downloads/test.py”, line 125, in forward<br>
return HybridFunction.apply(input, self.quantum_circuit, self.shift)<br>
File “/home/sreetamadas/anaconda3/lib/python3.10/site-packages/torch/autograd/function.py”, line 506, in apply<br>
return super().apply(*args, **kwargs)  # type: ignore[misc]<br>
File “/home/sreetamadas/Downloads/test.py”, line 74, in forward<br>
expectation_z = ctx.quantum_circuit.run(input[0].tolist())<br>
File “/home/sreetamadas/Downloads/test.py”, line 50, in run<br>
job = self.backend.run(transpile([self._circuit.bind_parameters({self.theta: theta}) for theta in thetas], backend=self.backend), shots=self.shots)<br>
File “/home/sreetamadas/Downloads/test.py”, line 50, in <br>
job = self.backend.run(transpile([self._circuit.bind_parameters({self.theta: theta}) for theta in thetas], backend=self.backend), shots=self.shots)<br>
File “/home/sreetamadas/anaconda3/lib/python3.10/site-packages/qiskit/circuit/quantumcircuit.py”, line 2783, in bind_parameters<br>
return self.assign_parameters(values)<br>
File “/home/sreetamadas/anaconda3/lib/python3.10/site-packages/qiskit/circuit/quantumcircuit.py”, line 2725, in assign_parameters<br>
unrolled_param_dict = self._unroll_param_dict(parameters)<br>
File “/home/sreetamadas/anaconda3/lib/python3.10/site-packages/qiskit/circuit/quantumcircuit.py”, line 2797, in _unroll_param_dict<br>
if not len(param) == len(value):<br>
TypeError: object of type ‘float’ has no len()</p>
</blockquote>
<p>I think the error is occurring because the parameter “input” in the class Hybrid is a still a float number. The changes I made did not affect it. I have tried to manually set “input” as a (1, 2) dimensional tensor, but that also did not work. How can I modify the classes to include more variable parameters?</p>