PennyLaneを用いた量子回路最適化
僕が学生時代に量子情報処理の研究に関わっていたのはこちらで自己紹介した通りで、
研究者ではありませんが今も量子情報処理・量子計算には興味があります。
そして今は機械学習エンジニア・データサイエンティストとしてソフトウェア開発に携わっています。
そんな自分が今量子コンピュータの界隈でできたらいいな・機会があれば取り組みたい・自分の経歴を生かすことができると思っていることが、量子機械学習です。
量子機械学習についてはQiitaでKuma氏がまとめてくださっています。
主に以下の目的で研究されています。
ただ量子計算も機械学習も両方わからないといけないのでなかなかハードです。
みんなが量子コンピュータ使える頃には使い方をちゃんと知っている人しか使いこなせないという参入障壁が高い状態になっていると困ります。
だから今のうちにやりたい、やりましょう!
ここからは量子機械学習を実装したフレームワークの一つであるPennyLaneのチュートリアルをベースに、要素技術を深掘りして解説していきます。
今回のシリーズは量子回路のパラメータ最適化(回転ゲートの回転角の調整)です。
こちらのチュートリアルです。
対象とする読者
前提とする知識
- 機械学習もしくは最適化という言葉を知っていること
- 量子ビット、波動関数、重ね合わせ状態、測定という言葉を知っていること
- 簡単な1量子ビットゲート(X, Y, Z, Rx, Ry, Rz)を理解していること
バージョン情報
- Python 3.9.5
- PennyLane 0.15.1
目次
PennyLaneとは
PannyLaneはカナダのXanado社が開発している量子機械学習を実装した(量子機械学習をするのに必要な・あったら便利な関数やクラスを用意してくれている)ライブラリの一つで、機械学習フレームワークであるPyTorchをベースにしています。
PyTorchで作られているので計算結果をPyTorchに連携できます。
ただし、現状では自分のPC内にシミュレータを構築して計算しているので、実機ではありません。
その他に量子機械学習を実装しているフレームワークは2021年6月現在把握してある限り以下です。
あまりないですね、、
中でもこのPennyLaneはチュートリアルが豊富で、ノートブックも用意されているのでとりあえず実行することができます!
コアとなる概念: 量子ノード(Quantum Node, QNode)
PennyLaneを使う上で重要な概念が量子ノード(Quantum Node, QNode)です。
下図のように量子ビットや量子ゲートのパラメータ(入力)、測定結果(出力)、そしてその間の何らかの量子回路からなる計算単位です。
このQNodeを一つの計算グラフとして計算結果を後続の処理に渡したり、組み合わせて量子ニューラルネットワークを構築するのでしょう。
今回のシリーズではQNodeは1つしか使わないので、入力から量子ゲートを経て出力までをセットにした関数と思っていただければ良いです。
量子回路の計算結果を目的関数として最小化問題を解く
古典の機械学習では解きたい課題を表す目的関数を定義し、様々なパラメータでその目的関数を計算し、目的関数の値が最小もしくは最大となるパラメータの組み合わせを見つけます。
量子機械学習でも同様に、量子回路での計算結果を使って目的関数を定義し、量子回路のパラメータを色々変えて目的関数を計算し、目的関数の値が最小もしくは最大となるパラメータの組み合わせを見つけます。
通常、TensorFlowやPyTorchなどの機械学習フレームワークでは最小とするように計算するようになっています。
今回の解く問題と量子回路
今回解こうとしている問題は「1つの量子ビットの状態をからに遷移させるための, ゲートの角度はいくらか」(図2)です。
これは明らかにXゲートもしくはYゲートをかければ良いのですが、あえてこれを探索的に見つけようという練習課題です。
量子回路は下記です。
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⟩
可視化のためにゲートとゲートの角度を指定していますが、これをこの後で探索します。
なお、角度の単位はradianです。
今回の誤差関数
PennyLaneでは測定にPauli演算子を使います。
今回はZ軸への射影測定を想定してPauliZ測定します。
演算子の期待値は状態については1, については-1であることを利用して、下記となります。
上で定義した量子回路そのままです。
def cost(x): return circuit(x)
誤差関数を数式で表すと、演算子を任意の状態で期待値を求めるということなので、細かい計算は割愛しますが下記になります。
の時に最大で, もしくはの時に最小で となります。
勾配降下法で最適化
勾配降下法で最適化します。
コードとしては以下です。
# 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))
やることは古典の機械学習と同じです。
誤差関数の測定値と勾配に基づいて、パラメータ更新をします。
誤差関数の勾配は下記です。
計算したらわかりますがの時に勾配もゼロとなりパラメータ更新されなくなってしまうので、初期値を少しずらしてあるのがミソです。
パラメータ設定と誤差測定を繰り返して数値的に最適なパラメータを探索する
上のコードを実行すると下記のように誤差関数の更新が行われて、最初に期待した通りにY軸周りに回転する場合が解として求まりました。
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で定義する
- 問題設定・誤差関数を量子回路で表現する
- パラメータ最適化は古典機械学習と同じく誤差関数の勾配から勾配降下法で行える