I am implementing variational quantum circuit that takes inputs of Statevectors(similar to RawFeatureVector) and produce some Statevector-like-results (qiskit Statevector or (n(=number of qubits) X 2) matrix, arrays, or else) with parameterized rotation gates(rx, ry, or rz gates) using Qiskit.
I tried to build the circuit by myself and connect it to Pytorch with TorchConnector, the backward process goes wrong (the gradients did not spread out to update the weight parameters) because I could not provide appropriate backward function. I also read the documents and examples using SamplerQNN or EstimatorQNN, but all of their examples that I explored were based on the many-shots based simulation, so I thought it was slightly different from what I expected (I want to get the Statevector representation of the circuit instead of the measurement outcome).
Question: is there any way to build a quantum neural network (SamplerQNN or EstimatorQNN) that does the above behavior using Qiskit? Or, are there any other ways I can try to build such QNN?
Here is some simplified snippet of what I want to do.
# Might be wrong in syntax
# but kindly ask you to take this as the pseudocode that I want to do..
class Model(nn.module):
def __init__(self):
# do some initialization if needed
def quantum_circuit(self, weights, n_qubit):
# weights: torch.tensor that needs autograd
fm = RawFeatureVector(n_qubit) # circuit for feature map
rc = QuantumCircuit(n_qubit) # circuit with rotation gates
for i in range(n_qubit):
rc.rx(weights[3*i], i)
rc.ry(weights[3*i+1], i)
rc.rz(weights[3*i+2], i)
for i in range((n_qubit//2)):
rc.cx(2*i, 2*i+1)
qc = QuantumCircuit(n_qubit)
qc.compose(fm)
qc.compose(rc)
return qc
def train(inputs, initial_weights, n_qubit, target_statevector):
# input: torch.tensor with/without autograd
max_iter = 100
weights = ParameterVector('a', 3*n_qubit)
weight_params = torch.from_numpy(initial_weights)
weight_params.requires_grad = True
model = Model()
qc, fm, rc = model.quantum_circuit(weights, n_qubit)
simulator = Aer.get_backend('statevector_simulator')
# QNN that returns the Statevector(qc) as an output of 'forward' method
# Use statevector_simulator to get the statevector of the result..?
qnn = QNN(qc, fm.parameters, rc.parameters, simulator)
torch_connector = TorchConnector(qnn, initial_weights)
optimizer = torch.optim.Adam([weight_params], lr = 0.01)
torch_connector.train()
for iter in range(max_iter):
# outputs the statevector of the qnn with the inputs and weight_params
statevector = qnn.forward(inputs, weight_params)
# loss function using statevector and target_statevector as tensors
loss = loss_function(statevector, target_statevector)
optimizer.zero_grad()
# autograd, update weight_params with regard to the circuit in qnn
loss.backward()
optimizer.step()
return weight_params # return optimal parameter of the model
I am using qiskit 0.45.3 (maybe I can update this to 1.0.0) and qiskit_machine_learning 0.7.1, qiskit_aer 0.13.3, qiskit_algorithms 0.2.2, Python 3.11.5.