Мультиклассовая классификация с использованием TensorFlow Quantum
Я запускаю несколько примеров и тестов на TensorFlow Quantum (TFQ), и я изо всех сил пытаюсь выполнить мультиклассовую классификацию. Я буду использовать пример классификации MNIST в качестве основы (https://www.tensorflow.org/quantum/tutorials/mnist), так как именно здесь я тоже начинаю.
Для бинарной классификации я играл с различными примерами классов и различными комбинациями вентилей, и результат классификации был получен путем измерения результата одного считываемого кубита (qR), таким образом, если qR=0, мы классифицируем с классом 0, а если qR=1, то мы иметь 1 класс.
Я расширил его до мультиклассовых задач, поэтому у нас есть 4 класса (0,1,2,3). Для этого я меняю метки классов наtf.keras.utils.to_categorical(y_train)
, чтобы метки преобразовывались из отдельных значений в векторы (0 -> (1,0,0,0); 1-> (0,1,0,0); и т. д.), используйте tf.keras.losses.CategoricalHinge()
в качестве потери модели и создайте 4 кубита чтения, по одному для каждого класса (M(qR0, qR1, qR2, qR3) = (0,0,1,0) -> класс 2), и это работает.
Однако этот метод значительно увеличивает размер схемы. Итак, я хочу передать в TFQ только 2 считывающих кубита и использовать комбинированное измерение для классификации 4 классов (|00> = 0, |10> = 1, |01> = 2, |11> = 3). В идеале это позволило бы провести мультиклассовую классификацию 2^n, где n - количество кубитов. В Cirq я могу добиться этого результата, выполнивcirq.measure(qR0, qR1, key='measure')
на двух считывающих кубитах. Однако я изо всех сил пытаюсь передать такую команду в TFQ, поскольку, насколько я понимаю, он измеряет только кубиты, которые заканчиваются одним гейтом Паули кубита.
Итак, есть ли что-то, чего мне не хватает в функциях TFQ, что позволяет проводить такие измерения в процессе обучения?
1 ответ
Начиная с этого фрагмента:
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 разных схемы, и я взял два ожидаемых значения для каждой схемы. Стоимость на[1, 0]
из output
было бы:
Тогда значение при [2, 1]
из output
было бы:
Форма и содержание output
значения частично продиктованы формой и содержанием ops
. Если бы я хотел сделать выходную форму[3, 3]
Я мог бы просто добавить еще один действительный cirq.PauliSum
возражать против ops
список. В вашем случае, если вы хотите получить вероятность получения 00, 01, 10, 11 на двух конкретныхcirq.GridQubit
s q0
а также q1
вы можете сделать что-то вроде этого:
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]
. Это помогает прояснить ситуацию?