I am working on a dataset where I have 6 input features that are numbers in the range of 1 - 1000 that need to be encoded as a quantum circuit. I am using TensorFlow Quantum for my research. While I have come across papers that explain angle encoding and amplitude encoding quite well, I have not quite been able to understand how to express the math in TFQ. I went through the Quantum MNIST tutorial on the TFQ pages but the way the images are encoded there is vastly different from how how numeric data rows would be encoded. Any help guiding me to encode this data would be appreciated!
-
$\begingroup$ So you understand how both angle embedding and amplitude encoding work, but are not sure how to implement them using TFQ? And are you looking for advice on implementing both techniques, or is there one you believe is better suited for your data? $\endgroup$– ryanhill1Aug 3, 2021 at 16:18
-
$\begingroup$ I'd like some advice on how to implement any encoding for my data. The dataset is fairly small so there are no space or time constraints, which is why any encoding that I can perform in TFQ would be great. $\endgroup$– Lakshit DabasAug 3, 2021 at 16:49
1 Answer
I can lend some ideas, but since I don't know exactly what you're after I will have to guess a bit.
Looking at the original snippet from the MNIST tutorial:
def convert_to_circuit(image):
"""Encode truncated classical image into quantum datapoint."""
values = np.ndarray.flatten(image)
qubits = cirq.GridQubit.rect(4, 4)
circuit = cirq.Circuit()
for i, value in enumerate(values):
if value:
circuit.append(cirq.X(qubits[i]))
return circuit
It's clear that if a pixel is turned on there is an X gate applied to that qubit. Building off of this we can try something like:
def convert_to_circuit(row):
"""Encode a vector with features in [1, 1000] using angle-encoding"""
values = (np.ndarray.flatten(row).astype(np.float32) - 1) / 999
qubits = cirq.GridQubit.rect(1, len(values))
circuit = cirq.Circuit(cirq.X(q) ** v for v,q in zip(values, qubits))
return circuit
Which applies an X rotation on each qubit proportional to that features value (if row[5] == 321
then qubit 5 would be given cirq.X ** 0.321
and if row[6] == 1000
then qubit 6 in the circuit would be given a full cirq.X ** 1.0
rotation). Here the rotations are normalized to the range $[0, 1]$. If I wanted to get them between $[-\pi, \pi]$ we could do something like:
def convert_to_circuit(row):
"""Encode a vector with features in [1, 1000] using angle-encoding"""
values = (np.ndarray.flatten(row).astype(np.float32) - 1) / 999
values = values * (2 * np.pi) - np.pi
qubits = cirq.GridQubit.rect(1, len(values))
circuit = cirq.Circuit(cirq.rx(v)(q) for v,q in zip(values, qubits))
return circuit
This is a rough implementation of "angle encoding" like is talked about here or here. You could then feed these datapoint circuits into any downstream TFQ model (as long as they acted on the same qubits of course).
For some more ideas check out the scheme used here or here it contains a few (decently well written) examples that might give you some inspiration on encoding you data. In general the field doesn't have complete consensus on what "the absolute best encoding to use for all cases" is so you have to try stuff, do some math and see what works. Hope this helps.
-Michael