deleted 32 characters in body
Source Link
Martin Vesely
  • 10.6k
  • 3
  • 14
  • 48

Hope this helps.

-Michael

Hope this helps.

-Michael

added 166 characters in body
Source Link
Michael
  • 363
  • 1
  • 5

 my_symbols = ...
my_circuit = cirq.Circuit(...) # created containing `my_symbols`

true_parameters = [1,2,3]
guess_parameters = [4,5,6]

# guess_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
guess_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = guess_parameters, repetitions=10000)

# true_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
true_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = true_parameters, repetitions=10000)

# Compute the histograms. [n_circuits, 2^n_qubits + 1]
guess_probs = tf.math.bincount(tf.cast(guess_distribution.to_tensor(), tf.dtypes.int32)) / 10000
true_probs = tf.math.bincount(tf.cast(true_distribution.to_tensor(), tf.dtypes.int32)) / 10000

# Measure the distribution overlap between your parameter guess and the true parameters. scalar tensor.
kl_overlap = tf.keras.losses.KLDivergence()(guess_probs, true_probs)

This is a far more complex problem and could function very similarly to the example you linked in your question, where the neural network must learn to map from labels to parameter values where the loss gets backprop'd through the samples you take via your closeness measure. At a high level this would require incorporating the above snippet decorated with a @tf.custom_gradient into that tutorial plus some structural modifications to the tf.keras.Model, but is in principle very doable. There are some more complex TFQ examples here that we also walk through here.


 my_symbols = ...
my_circuit = cirq.Circuit(...) # created containing `my_symbols`

true_parameters = [1,2,3]
guess_parameters = [4,5,6]

# guess_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
guess_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = guess_parameters, repetitions=10000)

# true_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
true_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = true_parameters, repetitions=10000)

# Compute the histograms. [n_circuits, 2^n_qubits + 1]
guess_probs = tf.math.bincount(tf.cast(guess_distribution.to_tensor(), tf.dtypes.int32)) / 10000
true_probs = tf.math.bincount(tf.cast(true_distribution.to_tensor(), tf.dtypes.int32)) / 10000

# Measure the distribution overlap between your parameter guess and the true parameters. scalar tensor.
kl_overlap = tf.keras.losses.KLDivergence()(guess_probs, true_probs)

This is a far more complex problem and could function very similarly to the example you linked in your question, where the neural network must learn to map from labels to parameter values where the loss gets backprop'd through the samples you take via your closeness measure. At a high level this would require incorporating the above snippet decorated with a @tf.custom_gradient into that tutorial plus some structural modifications to the tf.keras.Model, but is in principle very doable.

my_symbols = ...
my_circuit = cirq.Circuit(...) # created containing `my_symbols`

true_parameters = [1,2,3]
guess_parameters = [4,5,6]

# guess_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
guess_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = guess_parameters, repetitions=10000)

# true_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
true_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = true_parameters, repetitions=10000)

# Compute the histograms. [n_circuits, 2^n_qubits + 1]
guess_probs = tf.math.bincount(tf.cast(guess_distribution.to_tensor(), tf.dtypes.int32)) / 10000
true_probs = tf.math.bincount(tf.cast(true_distribution.to_tensor(), tf.dtypes.int32)) / 10000

# Measure the distribution overlap between your parameter guess and the true parameters. scalar tensor.
kl_overlap = tf.keras.losses.KLDivergence()(guess_probs, true_probs)

This is a far more complex problem and could function very similarly to the example you linked in your question, where the neural network must learn to map from labels to parameter values where the loss gets backprop'd through the samples you take via your closeness measure. At a high level this would require incorporating the above snippet decorated with a @tf.custom_gradient into that tutorial plus some structural modifications to the tf.keras.Model, but is in principle very doable. There are some more complex TFQ examples here that we also walk through here.

Source Link
Michael
  • 363
  • 1
  • 5

I think there might be a lot to unpack here. Just making sure my understanding of the problem is correct:

I hand you a quantum circuit with some free parameters and then I hand you some samples from that quantum circuit at specific parameter values, but I don't tell you what the parameter values are and then your goal is to try and determine what the parameter values are via some optimization or ML type algorithm that takes the samples I gave you as input. I'm not entirely sure this is what you're after, but I can offer you a simple piece of code that does some of the major steps here in TFQ, which can hopefully serve as a good starting point to play around with things:


my_symbols = ...
my_circuit = cirq.Circuit(...) # created containing `my_symbols`

true_parameters = [1,2,3]
guess_parameters = [4,5,6]

# guess_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
guess_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = guess_parameters, repetitions=10000)

# true_distribution is a ragged tensor of shape [n_circuits, n_samples, n_qubits]
true_distribution = tfq.layers.Sample(my_circuit, symbol_names=my_symbols, symbol_values = true_parameters, repetitions=10000)

# Compute the histograms. [n_circuits, 2^n_qubits + 1]
guess_probs = tf.math.bincount(tf.cast(guess_distribution.to_tensor(), tf.dtypes.int32)) / 10000
true_probs = tf.math.bincount(tf.cast(true_distribution.to_tensor(), tf.dtypes.int32)) / 10000

# Measure the distribution overlap between your parameter guess and the true parameters. scalar tensor.
kl_overlap = tf.keras.losses.KLDivergence()(guess_probs, true_probs)

You could go a lot of different ways with this snippet. For example:

  1. You could try different ways to characterize distribution closeness. KL divergence is a good way, but it is by no means the only way. Like you mention in your question there might be some ways of computing a few expectation values from your circuit that work as a good proxy quantity for distribution closeness.

  2. You could remain focused on the single circuit case and attempt to optimize the values of guess_parameters using an optimizer of your choice (gradient free ones like this one could work well). If you would like to use gradient based optimizers like the ones found in TensorFlow, you might need to investigate defining a custom gradient for your specific problem of "measuring distribution closeness" (since sampling on it's own is not differentiable) using the @tf.custom_gradient tag. This would then be compatible with your standard GradientTape workflow:

x = tf.constant(my_guess)
with tf.GradientTape() as g:
  g.watch(x)
  y = my_closeness_function_decorated_with_custom_gradient(x)

# Can now optimize x values using this tensor here.
# Along with any of `tf.optimizers`.
dy_dx = g.gradient(y, x)
  1. Lastly you could frame the problem slightly differently: I hand you a quantum circuit with some free parameters and then I hand you some samples from that quantum circuit where each sample has a corresponding label associated with it. This label indicates a unique values of parameters that this sample came from. Again I don't tell you what any of these parameters are, but now the problem has become slightly harder in your goal is to try and determine which parameter values correspond to each specific label (not just one set of values for alpha and beta this time like in #1) using an algorithm that incorporates just the samples and labels.

This is a far more complex problem and could function very similarly to the example you linked in your question, where the neural network must learn to map from labels to parameter values where the loss gets backprop'd through the samples you take via your closeness measure. At a high level this would require incorporating the above snippet decorated with a @tf.custom_gradient into that tutorial plus some structural modifications to the tf.keras.Model, but is in principle very doable.

As a final note I will say TensorFlow is tricky and when you throw things like TensorFlow Quantum (or pennylane) on top of that, things can get really tricky. If you are more interested in 1 and 2 from the list, you might be better off sticking with you favorite between cirq/qiskit and doing everything manually, but if you are more interested in 3 I'd say tackling the learning curve of TF + TFQ would definitely help in the long run.

Here's a paper that might also interest you. They tackle a slightly different problem. Here the authors tried to use a neural network to emulate sampling from a quantum circuit. Turns out it's a little tricky :).

Hope this helps.

-Michael