使用 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.GridQubit
s q0
和 q1
上获得 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]
。这有助于清理问题吗?
我正在 运行 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.GridQubit
s q0
和 q1
上获得 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]
。这有助于清理问题吗?