tensorflow / quantum

Hybrid Quantum-Classical Machine Learning in TensorFlow
https://www.tensorflow.org/quantum
Apache License 2.0
1.77k stars 560 forks source link

Can we use two `PQC` or `ControlledPQC` layers in same `Sequential` class? #737

Open Shuhul24 opened 1 year ago

Shuhul24 commented 1 year ago

I want two different quantum circuits, H1 and H2, in same Sequential class, similar to two tf.keras.layers.Dense that have different weight values, bias values and number of neurons as well. Is it possible using tfq.layers?

lockwo commented 1 year ago

Why make them as different TFQ layers? If you do circuit H1 then circuit H2 you can just combine them in cirq then use one PQC

Shuhul24 commented 1 year ago

Hi. Thanks for the reply! I want to evaluate the gradients with respect to each layer weights (parameters of quantum gates), which is possible if I declare two different PQC layers. In first PQC layer, say H1, I want the output of that layer to be the input for the next PQC layer, H2 and not its observable as the input to next PQC layer. The output of a layer can be evaluated by tfq.layers.State but I think its not possible to use that output state as an input for next PQC layer. Also mentioned that the output state through tfq.layers.State is not differentiable (I am not sure about this), which kind of creates another issue for evaluating gradient.

lockwo commented 1 year ago

I'm not sure I understand your issue. First, it is worth noting that you can get the gradients with respect to different parts of the circuit within a single PQC. Just do

with tf.GradientTape() as tape:
    energy = model(inputs)
grads = tape.gradient(energy, model.trainable_variables)
h1_grads = grads[0:len(h1_params)]
h2_grads = grads[len(h1_params:]

Or something similar (that is more pseudo code than real code).

The reason I am confused is because I think what you are saying is you want to do H1 -> tfq.layers.State() -> H2. You are correct in saying that state is not differentiable. My confusion comes from the fact that that is what circuits just do by default, if you have H1 (cirq.Circuit) and H2 (cirq.Circuit) and do H1 + H2 then use that as a PQC that is the exact same as H1 -> State -> H2 (since the quantum state). You could also get the gradients for just part of this by freezing certain parameters or you just also just get all the gradients and only use those for H1 or H2 for what you need.

Now you could also be asking how do I do H1 -> observable -> controlledPQC(H2), which should be the same as in the demo in hello many worlds. You just specify the controlledPQC param weights to be the output and it should work fine.

Shuhul24 commented 1 year ago

Thanks for the reply! Is it possible to get the weights of different sections within single PQC, as the weights are tf.Variable format and I can't get them just by slicing using tf.slice.

lockwo commented 1 year ago

You should just be able to get certain indices (or sets of indices) (which I believe calls getitem not slice), right? Just make sure to keep in mind, TFQ reorders parameters internally (see: https://github.com/tensorflow/quantum/issues/646)