2
$\begingroup$

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!

$\endgroup$
2
  • $\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$
    – ryanhill1
    Aug 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$ Aug 3, 2021 at 16:49

1 Answer 1

4
$\begingroup$

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

$\endgroup$
1
  • $\begingroup$ Thanks Michael, this helped a lot! $\endgroup$ Aug 8, 2021 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.