Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate parameters for the trainable part and the encoding part in EstimatorQNN #820

Open
Pingal-Pratyush-Nath opened this issue Jul 18, 2024 · 2 comments
Assignees
Labels
type: feature request 💡 New feature or request

Comments

@Pingal-Pratyush-Nath
Copy link

What should we add?

The circuit that we pass in the estimator QNN contains two parts : the encoding part(non trainable) and the trainable part. If the encoding circuit changes for every data point, we will have to reinstantiate the model every-time. It would have been better if we can change that encoding part of the model every time we call the model. I know we can create a parameterized circuit and pass in the parameters everytime, but sometimes the circuit itself changes depending on the data point and it is difficult to use Torch Connector for that.

I have added a sample code.

def initial_state(data)->QuantumCircuit:
    graph = to_networkx(data)

    adj_mat = nx.adjacency_matrix(graph).todense()
    adj_circ = GraphState(adj_mat)
    adj_circ.barrier()
    for i in range(adj_circ.num_qubits):
        adj_circ.rz(2*np.pi*float(data.z[i])/9,i)
    edge_attr = egde_attr_encoding(data)
    for i in range(len(edge_attr)):
        adj_circ.crz(edge_attr[i][0],edge_attr[i][1],edge_attr[i][2])

    adj_circ.decompose()

        
    return adj_circ

qc = initial_state(data_val)
ansatz = EfficientSU2(num_qubits = 5, num_reps = 2)
qc_final = ansatz.compose(qc)

qnn= EstimatorQNN(
    circuit=qc_final, input_params=qc.parameters, weight_params=ansatz.parameters
)

initial_weights = 0.1 * (2 * algorithm_globals.random.random(qnn1.num_weights) - 1)
model = TorchConnector(qnn, initial_weights=initial_weights)


@FrancescaSchiav FrancescaSchiav removed their assignment Sep 30, 2024
@oscar-wallis oscar-wallis self-assigned this Sep 30, 2024
@edoaltamura
Copy link
Collaborator

edoaltamura commented Oct 17, 2024

Thanks for pointing this out @Pingal-Pratyush-Nath, this is an interesting and tricky problem! Currently, EstimatorQNN only supports dynamic parameters but not a feature map with a fully dynamic circuit structure. In my view, this would be achieved in the following way.

Change the EstimatorQNN arguments to take a (constant) ansatz: QuantumCircuit and a variable feature_map: QuantumCircuit | Callable[[Any], QuantumCircuit] similar to QNNCircuit.

Note that changing the structure of the circuit for every data point (or GraphState) means that you have to transpile the composed circuit every time, if you want to run on real or emulated hardware, for two reasons (i) to optimise gates and pulses and (ii) to convert the circuit to the backend’s Instruction Set Architecture (ISA). Potentially, this is an expensive operation to repeat every time, so you may want to keep an eye on this step if you're after performance/speed.

Currently, we do not have a plan for including dynamic feature maps in EstimatorQNN, however, I warmly encourage you to share your ideas and code snippets in this threads so that us and the rest of the community can make suggestions.

@edoaltamura edoaltamura added the type: feature request 💡 New feature or request label Oct 17, 2024
@edoaltamura edoaltamura self-assigned this Nov 8, 2024
@oscar-wallis
Copy link
Collaborator

@Pingal-Pratyush-Nath I am skeptical towards this being a feature but another idea could be to reframe the qnn to reduce computational overhead. What if instead, the QNN was instantiated with an ISA compliant ansatz and then the circuit was fed the datapoints in the form of transpiled ISA circuits.

So you would take your initial data, turn each into a virtual circuit (QuantumCircuit) and then run the passmanager on all of these to make them ISA, this forms your dataset. Then you feed the QNN the data ISA circs and internally it stitches together each of these with the ISA ansatz and sends them in as jobs.

This would just mean that you transpile the ansatz only once, reducing computational overhead. This kind of model could be worth investigating internally as a way to run "quantum data" through our NeuralNets. Honestly, I think I have convinced myself this is a good idea whilst writing this, maybe this should be a feature for 1.1 - @edoaltamura @OkuyanBoga.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature request 💡 New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants