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

Hope this helps.

-Michael

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.

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)
g.watch(x)

# Can now optimize x values using this tensor here.
# Along with any of tf.optimizers.

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.