科学しよう

量子計算のプログラミングの解説をメインに、データサイエンス・機械学習について勉強したことをご紹介します

MENU

PennyLaneを用いた量子回路最適化

僕が学生時代に量子情報処理の研究に関わっていたのはこちらで自己紹介した通りで、 研究者ではありませんが今も量子情報処理・量子計算には興味があります。
そして今は機械学習エンジニア・データサイエンティストとしてソフトウェア開発に携わっています。
そんな自分が今量子コンピュータの界隈でできたらいいな・機会があれば取り組みたい・自分の経歴を生かすことができると思っていることが、量子機械学習です。

量子機械学習についてはQiitaでKuma氏がまとめてくださっています
主に以下の目的で研究されています。

ただ量子計算も機械学習も両方わからないといけないのでなかなかハードです。
みんなが量子コンピュータ使える頃には使い方をちゃんと知っている人しか使いこなせないという参入障壁が高い状態になっていると困ります。
だから今のうちにやりたい、やりましょう!

ここからは量子機械学習を実装したフレームワークの一つであるPennyLaneのチュートリアルをベースに、要素技術を深掘りして解説していきます。
今回のシリーズは量子回路のパラメータ最適化(回転ゲートの回転角の調整)です。
こちらのチュートリアルです。

対象とする読者

  • 量子計算に興味をがあるエンジニア・高校生・大学生の方
  • 量子機械学習に興味がある機械学習エンジニア・データサイエンティスト など

前提とする知識

バージョン情報

  • Python 3.9.5
  • PennyLane 0.15.1

目次

PennyLaneとは

PannyLaneはカナダのXanado社が開発している量子機械学習を実装した(量子機械学習をするのに必要な・あったら便利な関数やクラスを用意してくれている)ライブラリの一つで、機械学習フレームワークであるPyTorchをベースにしています。

pennylane.ai

PyTorchで作られているので計算結果をPyTorchに連携できます。
ただし、現状では自分のPC内にシミュレータを構築して計算しているので、実機ではありません。

その他に量子機械学習を実装しているフレームワークは2021年6月現在把握してある限り以下です。

あまりないですね、、
中でもこのPennyLaneはチュートリアルが豊富で、ノートブックも用意されているのでとりあえず実行することができます!

コアとなる概念: 量子ノード(Quantum Node, QNode)

PennyLaneを使う上で重要な概念が量子ノード(Quantum Node, QNode)です。
下図のように量子ビットや量子ゲートのパラメータ(入力)、測定結果(出力)、そしてその間の何らかの量子回路からなる計算単位です。
このQNodeを一つの計算グラフとして計算結果を後続の処理に渡したり、組み合わせて量子ニューラルネットワークを構築するのでしょう。
今回のシリーズではQNodeは1つしか使わないので、入力から量子ゲートを経て出力までをセットにした関数と思っていただければ良いです。

f:id:sakumadaisuke32:20210608003041p:plain
図1. 量子ノード概念図

量子回路の計算結果を目的関数として最小化問題を解く

古典の機械学習では解きたい課題を表す目的関数を定義し、様々なパラメータでその目的関数を計算し、目的関数の値が最小もしくは最大となるパラメータの組み合わせを見つけます。
量子機械学習でも同様に、量子回路での計算結果を使って目的関数を定義し、量子回路のパラメータを色々変えて目的関数を計算し、目的関数の値が最小もしくは最大となるパラメータの組み合わせを見つけます。 通常、TensorFlowやPyTorchなどの機械学習フレームワークでは最小とするように計算するようになっています。

今回の解く問題と量子回路

今回解こうとしている問題は「1つの量子ビットの状態を | 0 \gtから | 1 \gtに遷移させるための \mathrm{R_x},  \mathrm{R_Y}ゲートの角度はいくらか」(図2)です。
これは明らかにXゲートもしくはYゲートをかければ良いのですが、あえてこれを探索的に見つけようという練習課題です。

f:id:sakumadaisuke32:20210612084233p:plain
図2. 問題設定を示すBloch球

量子回路は下記です。

from pennylane import numpy as np

dev1 = qml.device("default.qubit", wires=1)

@qml.qnode(dev1)
def circuit(params):
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=0)
    return qml.expval(qml.PauliZ(0))

drawer = qml.draw(circuit)
print(drawer([0.54, 0.12]))

circuit関数で量子回路を定義し、QNodeとして扱うためにqnodeデコレータを指定しています。
この回路のprintした結果は下記です。

 0: ──RX(0.54)──RY(0.12)──┤ ⟨Z⟩ 

可視化のために \mathrm{R_x}ゲートと \mathrm{R_Y}ゲートの角度を指定していますが、これをこの後で探索します。
なお、角度の単位はradianです。

今回の誤差関数

PennyLaneでは測定にPauli演算子を使います。
今回はZ軸への射影測定を想定してPauliZ測定します。

pennylane.readthedocs.io

演算子 \hat{\sigma}_zの期待値は状態 | 0 \gtについては1,  | 1 \gtについては-1であることを利用して、下記となります。
上で定義した量子回路そのままです。

def cost(x):
    return circuit(x)

誤差関数を数式で表すと、演算子 \hat{\sigma}_zを任意の状態 | \psi \gtで期待値を求めるということなので、細かい計算は割愛しますが下記になります。


\begin{aligned}
\lt \hat{\sigma}_z \gt &= \lt \psi | \hat{\sigma}_z | \psi \gt \\
&= \lt 0 | \hat{R}_Y^\dagger (\phi) \hat{R}_X^\dagger (\theta) \hat{\sigma}_z R_Y (\theta) R_X (\phi) | 0 \gt \\
&= \cos \theta \cos \phi
\end{aligned}

 ( \theta , \phi) = (0, 0)の時に最大で \lt \hat{\sigma}_z \gt = 1,  ( \theta , \phi) = (0, \pi)もしくは (\theta , \phi) = (\pi, 0)の時に最小で  \lt \hat{\sigma}_z \gt = -1となります。

勾配降下法で最適化

勾配降下法で最適化します。
コードとしては以下です。

# initialise the optimizer
opt = qml.GradientDescentOptimizer(stepsize=0.4)

# set the number of steps
steps = 100
# set the initial parameter values
init_params = np.array([0.011, 0.012])
params = init_params

for i in range(steps):
    # update the circuit parameters
    params = opt.step(cost, params)

    if (i + 1) % 5 == 0:
        print("Cost after step {:5d}: {: .7f}".format(i + 1, cost(params)))

print("Optimized rotation angles: {}".format(params))

やることは古典の機械学習と同じです。
誤差関数の測定値と勾配に基づいて、パラメータ更新をします。

誤差関数の勾配は下記です。


\begin{aligned}
\nabla \lt \hat{\sigma}_z \gt &= \left( \cos \phi \frac{\partial}{\partial \theta} \cos \theta , \cos \theta \frac{\partial}{\partial \phi} \cos \phi \right) \\
&= \left( - \sin \theta \cos \phi  , - \cos \theta \sin \phi \right) \\
\end{aligned}

計算したらわかりますが ( \theta , \phi) = (0, 0)の時に勾配もゼロとなりパラメータ更新されなくなってしまうので、初期値を少しずらしてあるのがミソです。

パラメータ設定と誤差測定を繰り返して数値的に最適なパラメータを探索する

上のコードを実行すると下記のように誤差関数の更新が行われて、最初に期待した通りにY軸周りに \pi回転する場合が解として求まりました。

Cost after step     5:  0.9961778
Cost after step    10:  0.8974944
Cost after step    15:  0.1440490
Cost after step    20: -0.1536720
Cost after step    25: -0.9152496
Cost after step    30: -0.9994046
Cost after step    35: -0.9999964
Cost after step    40: -1.0000000

(中略)

Cost after step   100: -1.0000000
Optimized rotation angles: [7.15266381e-18 3.14159265e+00]

まとめ

問題設定を量子回路で表現するまでできれば、あとは古典の機械学習と同じ流れでできることを確かめました。

  • PennyLaneでは量子回路をQNodeで定義する
  • 問題設定・誤差関数を量子回路で表現する
  • パラメータ最適化は古典機械学習と同じく誤差関数の勾配から勾配降下法で行える


【送料無料】 量子コンピュータによる機械学習 / Maria Schuld 【本】