使用 TensorFlow Quantum 进行多类分类

Multiclass classification using TensorFlow Quantum

我正在 运行 TensorFlow Quantum (TFQ) 上的一些示例和测试,我正在努力执行多class class化。我将使用 MNIST class化示例作为基础 (https://www.tensorflow.org/quantum/tutorials/mnist),因为这也是我的起点。

对于二进制 classification,我尝试了 classes 的不同示例和不同的门组合,classification 结果是通过测量单个读出量子位 (qR ) 结果,因此如果 qR=0 我们 class 证明 class 0 如果 qR=1 那么我们有 class 1.

我把它扩展到一个多class的问题,所以我们有4个classes (0,1,2,3)。为此,我将 classes 的标签更改为 tf.keras.utils.to_categorical(y_train),以便标签从单个值转换为向量 (0 -> (1,0,0,0); 1-> (0,1,0,0); 等等。),使用 tf.keras.losses.CategoricalHinge() 作为模型的损失并创建 4 个读数量子位,每个 class (M(qR0, qR1, qR2, qR3 ) = (0,0,1,0) -> class 2), 这有效。

然而,这种方法大大增加了电路的尺寸。所以我想做的是仅将 2 个读出量子位传递给 TFQ,并使用 4 classes classification (|00> = 0, |10> = 1, |01) 的组合测量> = 2,|11> = 3)。理想情况下,这将允许 2^n multi-class class化,其中 n 是量子位的数量。在 Cirq 中,我可以通过对两个读出量子位执行 cirq.measure(qR0, qR1, key='measure') 来实现此输出。然而,我正在努力将这样的命令传递给 TFQ,因为据我所知,它只测量以单个量子位保利门结尾的量子位。

那么,在允许在训练过程中进行此类测量的 TFQ 功能中,我是否遗漏了什么?

从这个片段开始:

bit = cirq.GridQubit(0, 0)
symbols = sympy.symbols('x, y, z')

# !This is important!
ops = [-1.0 * cirq.Z(bit), cirq.X(bit) + 2.0 * cirq.Z(bit)]
# !This is important!

circuit_list = [
    _gen_single_bit_rotation_problem(bit, symbols),
    cirq.Circuit(
        cirq.Z(bit) ** symbols[0],
        cirq.X(bit) ** symbols[1],
        cirq.Z(bit) ** symbols[2]
    ),
    cirq.Circuit(
        cirq.X(bit) ** symbols[0],
        cirq.Z(bit) ** symbols[1],
        cirq.X(bit) ** symbols[2]
    )
]
expectation_layer = tfq.layers.Expectation()
output = expectation_layer(
    circuit_list, symbol_names=symbols, operators = ops)
# Here output[i][j] corresponds to the expectation of all the ops
# in ops w.r.t circuits[i] where keras managed variables are
# placed in the symbols 'x', 'y', 'z'.
tf.shape(output)

我从这里拿的:https://www.tensorflow.org/quantum/api_docs/python/tfq/layers/Expectation .

output 张量的形状是 [3, 2] 我有 3 个不同的电路,我在每个电路上取了两个期望值。 output[1, 0] 处的值将是:

那么 output[2, 1] 处的值将是:

output 值的形状和内容部分由 ops 的形状和内容决定。如果我想制作输出形状 [3, 3],我可以将另一个有效的 cirq.PauliSum 对象添加到 ops 列表中。在你的情况下,如果你想要在两个特定的 cirq.GridQubits q0q1 上获得 00、01、10、11 的概率,你可以这样做:

def zero_proj(qubit):
  return (1 + cirq.Z(qubit)) / 2

def one_proj(qubit):
  return (1 - cirq.Z(qubit)) / 2

# ! This is important
ops = [
  zero_proj(q0) * zero_proj(q1),
  zero_proj(q0) * one_proj(q1),
  one_proj(q0) * zero_proj(q1),
  one_proj(q0)* one_proj(q1)
]
# ! This is important

制作任何摄取层的输出形状 ops[whatever_your_batch_size_is, 4]。这有助于清理问题吗?