I am running some examples and tests on TensorFlow Quantum (TFQ) and I am struggling to perform a multi-class classification. I will used the MNIST classification example as base (https://www.tensorflow.org/quantum/tutorials/mnist), since this is where I am starting from too.
For binary classification I played with the different examples of classes and different gates combination, and the classification result is obtained by measuring a single readout qubit (qR)result, thus if qR=0 we classify with class 0 and if qR=1 then we have class 1.
I extended it to a multi-class problems, so we have a 4 classes (0,1,2,3). To do this I change the labels of the classes with tf.keras.utils.to_categorical(y_train)
, such that the labels get converted from single values to vectors (0 -> (1,0,0,0); 1-> (0,1,0,0); etc..), use tf.keras.losses.CategoricalHinge()
as loss of the model and create 4 readouts qubits, one for each class (M(qR0, qR1, qR2, qR3) = (0,0,1,0) -> class 2), and this works.
However, this method increases massively the size of the circuit. So what I want to do is to pass to TFQ only 2 readout qubits and use the combined measurement for the 4 classes classification (|00> = 0, |10> = 1, |01> = 2, |11> = 3). Ideally this would allow a 2^n multi-class classification, where n is the number of qubits. In Cirq I can achieved this output by performing a cirq.measure(qR0, qR1, key='measure')
on the two readout qubits. However I am struggling in passing such command to TFQ, since from what I understand it measures only the qubits that end with a single qubit Pauli gate.
So, is there something that I am missing in the functionalities of TFQ that allows such kind of measurements in the training process?
Starting with this snippet:
Which I took from here: https://www.tensorflow.org/quantum/api_docs/python/tfq/layers/Expectation .
The shape of the
output
tensor is[3, 2]
Where I have 3 different circuits and I took two expectation values over each circuit. The value at[1, 0]
ofoutput
would be:Then the value at
[2, 1]
ofoutput
would be:The shape and contents of
output
's values are partly dictated by the shape and contents ofops
. If I wanted to make the output shape[3, 3]
I could just add another validcirq.PauliSum
object to theops
list. In your case if you want the probability of getting 00, 01, 10, 11, on two particularcirq.GridQubit
sq0
andq1
you can do something like this:Making the output shape of any layer that ingests
ops
:[whatever_your_batch_size_is, 4]
. Does this help clear things up ?