Quantum Neural Network (statevector generation) with qiskit and pytorch

81 Views Asked by At

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.

0

There are 0 best solutions below