Quantum K-nearest neighbor#

Автор(ы):

Введение#

Если вы занимались машинным обучением, то, скорее всего, знакомы с классическим алгоритмом k ближайших соседей. Он относительно прост, применяется как в задачах классификации, так и в регрессии. Кстати, классический knn можно вспомнить обратившись к лекции от ODS по классическому машинному обучению.

Давайте немножко вспомним задачу классификации с использованием классического kNN алгоритма:

У нас есть x{0,1}Nтестовый образец, а также тренировочные образцы – это набор векторов vi{0,1}N, в котором каждый вектор уже размечен. И наша задача подобрать правильную метку тестовому образцу.

Тогда мы пройдём следующие шаги:

  1. Вычислим похожесть между тестовым образцом и каждым тренировочным образцом.

  2. Найдем k ближайших к тестовому образцу соседей.

  3. Подсчитаем количество представителей для каждого класса и приписываем метку самого часто встречающегося класса к тестовому образцу.

Самой трудозатратным шагом является вычисление расстояния от тестового образца к каждому тренировочному. Также и в квантовой версии алгоритма.

Note

На текущий момент разработано несколько разных версий квантового алгоритма поиска ближайших соседей. Есть версия основанная расстоянии Хэмминга [LTG21]:

Расстояние Хэмминга между векторами x и vi:

di=|xvi|=j=1N(xjvij)

Но в данной работе мы обратим внимание на версию, которая вычисляет fidelity между двумя векторами состояниями.

Пусть задано Гильбертово пространство n кубитов, размерности N=2n. Вектор |ψH – это тестовое состояние, для которого нам нужно определить метку.

Пусть {|ϕ:j{0,...,M1}}H - это набор тренировочных состояний, для которых мы знаем их метки. M=2m,mZ

Определим fidelity между тестовым состоянием и j-тым тренировочным |ϕj как

Fj=F(ψ,ϕj)=|ψ|ϕj|2

В свою очередь F=[F0,F1,...,FM1] - это таблица fidelity значений между тестовым состоянием и каждым из тренировочных.

Заметим, что задача нахождения k ближайших соседей сводится к задаче нахождения k максимумов значений fidelity из таблицы F. Для этого мы должны реализовать оракула

Oy,A|j|0=|j|fy,A(j),

где fy,A - это булева функция определённая как

fy,A(j)={1:Fj>Fy and jA,0: otherwise ,

Алгоритм#

Далее мы алгоритм представленный в работе [BAG21].

../../../_images/qknn.png

Fig. 67 Принципиальная схема QkNN алгоритма. Взято из работы [BAG21].#

Квантовый алгоритм поиска k ближайших соседей будет состоять из двух основных шагов:

  1. Используй оракул Oy,A (для алгоритма Гровера) мы находим k состояний {|ϕj1,...,|ϕjk} для которых значение fidelity с тестовым состоянием максимально.

  2. Найти преобладающую метку среди k найденных состояний и присвоить её тестовому состоянию.

Самой нетривиальной задачей для нас будет построение оракула Oy,A.

  1. Вначале нужно составить оператор F, который выполняет преобразование вида:

    F|j|0=|j|Fj

    для j{0,...,M1}. |Fj – это одно из базисных состояний вычислительного базиса (выражающее двоичное представление числа Fj).

    • Выполняется преобразование: ξamp|j|0=|j|ψj. В амплитуду состояния |ψj закодирована информация о числе Fj Делается это с помощью Swap test.

      Swap test это применение контролируемой операции Swap, которым можно пользоваться для того, чтобы статистически определять fidelity: F(ψ,ϕ)=|ψ|ϕ|2 между двумя произвольными чистыми состояниями |ψ и |ϕ.

      CSWAP(|0|ψ|ϕ)=|0|ψ|ϕCSWAP(|1|ψ|ϕ)=|1|ψ|ϕ
      ../../../_images/swap_test.png

      Fig. 68 Схема Swap test#

    • Выполняется преобразование ξdig|j|ψj=|j|Fj

      И тогда F=ξdigξamp.

  2. Берём 2 пары регистров i1,f1;i2,f2. Инициализируются они в форме |ji1|0f1|yi2|0f2

    Применяется F на каждой паре:

    F(|ji1|0f1)F(|yi2|0f2)=|ji1|Fjf1|yi2|Fyf2
  3. Теперь информация закодирована в регистры и нам нужно реализовать функцию fy,A. И пусть C это оператор, реализующий fy,A.

    C(|ji1|Fjf1|yi2|Fyf2)=|ji1|0f1|fy,Ai2|0f2

Теперь займёмся вопросом конструирования оракула Oy,A. Просьба держаться за ваши кресла.

Вначале мы подготовим состояния. Но чтобы это сделать нам нужны оракулы V,W. Как их имплементировать указано в статье, которая указывалась выше.

V|0n=|ψ
W|j|0n=|j|ϕ

для всех j{0,...,M1}.

  1. Инициализируем 4 регистра i, tr, tst, B с соответствующим количеством кубитов в каждом m, n, n, 1, где n=log(N), m=log(M).

    |ji|0ntr|0ntst|0B
  2. Применяем W

    W(|ji|0ntr|0ntst|0B)=|ji|ϕjtr|0ntst|0B
  3. Применяем V

    V(|ji|ϕjtr|0ntst|0B)=|ji|ϕjtr|ψjtst|0B
  4. Применяем swap test между тренировочным регистром tr и тестовым регистром tst, а регистр B будет выступать в качестве контрольного.

    12[(|ϕj|ψtst+|ψj|ϕtst)|0B+(|ϕj|ψtst|ψj|ϕtst)|1B]=|ji|ψjtr,tst,B

    Определим U как унитарное преобразование, которое объединяет шаги 3-4. Кстати, если мы сейчас произведём измерение регистра B, то будем иметь

    Pr(B=0)=1+Fj2Pr(B=1)=1Fj2

    На этом шаге информация о fidelity теперь закодирована в амплитуды. Теперь же мы должны перевести fidelity из амплитуды в число.

  5. Теперь мы будем конструировать новый гейт G. Вообще говоря, он описан в работе [MKF19], где вы можете подробнее с ним ознакомиться.

    G=Utr,tst,BWi,trS0tr,tst,BWi,trUtr,tst,BZB,

    где ZB – это действие гейта Z на регистре B, S0=I2|00|.

  6. Текущее состояние |ψtr,tst,B может быть представлено в виде композиции двух состояний

    |ψj=i2(eiπθj|ψj+eiπθj|ψj)
  7. Теперь применяем алгоритм QPE (Quantum Phase Estimation), чтобы перевести значение фазы θj в числовое представление.

    QPE(|ψj)=i2|ji[eiπθj|θjph|ψj+tr,tst,Beiπθj|1θjph|ψjtr,tst,B]=|ji|ψj,AEph,tr,tst,B
  8. Применяем алгоритм квантовой арифметики:

    |j|Fjfid|ψj,AEph,tr,tst,B
  9. Обнуляем регистры ph,tr,tst,B и получаем |ji|Fjfid На самом деле шаги 5-9 составляют оператор ξdig, который мы упоминали ранее.

  10. Теперь применяем оператор F

    |ji1|Fjf1|yi2|Fyf2
  11. Добавим кубит Q1 для выполнения сравнения

    J|a|b|0={|a|b|1:a>b,|a|b|0:ab,
    |ji1|Fjf1|yi2|Fyf2|g(j)Q1,

    где

    g(j)={1:Fj>Fy,0:FjFy,

    По кубиту Q1 мы сможем распознать все индексы j для которых Fj>Fy.

  12. Обнуляем регистры i2, f2.

  13. Добавляем ещё один кубит Q2 для каждого ilA, применяя гейт D(il)

    D(il)|j|0={|j|1:j=il,|j|0:jil,

    на индексах регистра. И в результате получим состояние

    |ji1|Fjf1|g(j)Q1|χA(j)Q2
  14. О да… Теперь мы добавляем ещё один кубит Q3. Применяем гейт X на кубите Q2 и гейт Тоффоли с контролирующими (Q1,Q2) и целевой Q3

    |ji1|Fjf1|g(j)Q1|χA(j)Q2|fy,A(j)Q3
  15. Обнуляем все регистры, кроме Q3

    |ji1|fy,A(j)Q3

    Что ж, вот мы и построили преобразование Oy,A которое так хотели

    Oy,A|j|0=|j|fy,A(j)