common.title

Overview
Service overview
Terms of service

Privacy policy

Contact

Sign in
Sign up
common.title

量子回路でTTNやMPS、および効率的に実装

Yuichiro Minato

2021/02/08 23:46

#機械学習

はじめに

量子ビットの節約は近年のまだ量子ビット数の少ないマシンでは重要です。そのうちでTree Tensor Networkの構造を量子ビットの再利用を使って節約する方法を見てみます。

TTN

木構造をもつTTNによってユニタリ変換を繰り返し、片方の測定を行わず捨てることで、量子ビットの量子状態をどんどん統合していくテクがあります。

11.png

QCNNなどに利用されてるTTNやMERAでみられますが、量子回路を再利用することで、より効率的に実行できる回路を見てみます。

上の図の左側は8量子ビットを準備し、順番に計算をしながら量子ビットの数を半分にしながら計算をしています。最初に4つのゲート、残った4量子ビットに2つのゲート、最後に1つのゲートで1量子ビットの測定にまとめています。

上記の右側は量子ビットを捨てて、初期化をすることで、再度利用を行い、初期の量子ビット数を半分に減らしています。

Towards Quantum Machine Learning with Tensor Networks

もちょいみてみます。

Towards Quantum Machine Learning with Tensor Networks William Huggins,1 Piyush Patil,1 Bradley Mitchell,1 K. Birgitta Whaley,1 and E. Miles Stoudenmire2 1University of California Berkeley, Berkeley, CA 94720 USA 2Center for Computational Quantum Physics, Flatiron Institute, 162 5th Avenue, New York, NY 10010, USA (Dated: August 1, 2018)

基本的に量子状態を表現するのにテンソルネットワークの木構造を使うことがありますが、下記のような8量子ビットの量子状態は、左側テンソルネットワークで結合次元が4の構造を利用するのに対して、右側の量子回路は量子ビット数を最終的な出力数に揃えて入力数を準備してあげる必要があり、ユニタリ回路を通じて同様の操作を実現します。

22.png

引用:https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5/pdf

次に

33.png

引用:https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5/pdf

TTNの構造を量子回路に落とし込んだものを見てみます。左側は量子回路に相当し、斜線が日本あるところは測定無しになってます。右側では量子状態の期待値を求めるものですが、測定する最後の量子ビット以外は縮約を取り、縮約密度行列ができます。

MPS

行列積状態を実現する量子回路は論文より、

44.png

引用:https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5/pdf

隣接するノードとの結合次元がユニタリ操作を通じて実現されています。

生成TTN

TTNモデルを識別モデルではなく、生成モデルとしてデータ生成に活かすためには、逆方向に実装し、0状態からユニタリ操作を通じて最終的に全ての量子ビットの測定を行ってサンプルを取ります。

55.png

引用:https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5/pdf

生成MPS

MPSを生成モデルとして利用する際にも、同じようにできます。0に量子ビット準備して、ユニタリ回路で実装してきます。最終的に全ての量子ビットのサンプルを取ります。

66.png

引用:https://iopscience.iop.org/article/10.1088/2058-9565/ab4eb5/pdf

めちゃんこ便利ですね。実装してみます。

MERA

今回作るモデルはMERAと呼ばれる木構造をしています。U3ゲートとCXゲートを使います。

|0> --[input]--U3--*--
                   |
|0> --[input]--U3--X--U3--*--
                          |
|0> --[input]--U3--*--    |
                   |      |
|0> --[input]--U3--X--U3--X--[m]-[expt]-[loss]-[output]
#MERA circuit def mera(a): u = Circuit() u.u3(a[0],a[1],a[2])[0] u.u3(a[3],a[4],a[5])[1] u.u3(a[6],a[7],a[8])[2] u.u3(a[9],a[10],a[11])[3] u.cx[0,1].cx[2,3] u.u3(a[12],a[13],a[14])[1] u.u3(a[15],a[16],a[17])[3] u.cx[1,3] return u from blueqat import Circuit import matplotlib.pyplot as plt import numpy as np import pandas as pd import time %matplotlib inline np.random.seed(39) #initial parameters ainit = [np.random.rand()*np.pi*2 for i in range(18)]

必要な関数を実装します。

#expectation value def E(sv): return sum(np.abs(sv[:8])**2)-sum(np.abs(sv[8:])**2) #loss function def L(p,t): return (p-t)**2 #data to gate def ix(l): u = Circuit(4) for i in l: u.x[i] return u

データを準備します。トレーニング用のデータと検証用を準備しました。

#training data inp = [[0,1],[2,3],[0],[3]] tgt = [1,1,-1,-1] #validation data inp_c = [[1],[2],[0,2],[1,3]] tgt_c = [-1,-1,1,1]

早速開始です。毎回の勾配の計算時に訓練データをランダムで選び最適化をかけます。

#initial parameters a = ainit.copy() #result list ar = [] h = 0.01 e = 0.01 #iterations nsteps = 800 start = time.time() for i in range(nsteps): r = np.random.randint(0,len(inp)) c = ix(inp[r])+mera(a) loss = L(E(c.run()),tgt[r]) ar.append(loss) at = [0 for i in range(len(a))] for j in range(len(a)): aa = a.copy() aa[j] += h loss2 = L(E((ix(inp[r])+mera(aa)).run()),tgt[r]) at[j] = a[j] - e*(loss2 - loss)/h a = at plt.plot(ar) plt.show() print(time.time() - start)
<Figure size 432x288 with 1 Axes>output
5.946179628372192

DB7D2F69-4E79-4803-951F-72C1E7D3A0C4.png

うまく収束したのでチェックしてみたいと思います。

#training accuracy np.mean([E((ix(inp[i])+mera(a)).run())/tgt[i] for i in range(len(inp))]) #=>0.9760245973174358
0.9760245973174352
#validation accuracy np.mean([E((ix(inp_c[i])+mera(a)).run())/tgt_c[i] for i in range(len(inp_c))]) #=>0.9769492668551134
0.9769492668551134

いい感じですね。

MPS

次に作るのモデルはMPSと呼ばれる階段構造をしています。U3ゲートとCXゲートを使います。

|0> --[input]--U3--*--
                   |
|0> --[input]--U3--X--U3--*--
                          |
|0> --[input]---------U3--X--U3--*
                                 |
|0> --[input]----------------U3--X--[m]-[expt]-[loss]-[output]

モデルは、

#MPS circuit def mps(a): u = Circuit() u.u3(a[0],a[1],a[2])[0] u.u3(a[3],a[4],a[5])[1] u.u3(a[6],a[7],a[8])[2] u.u3(a[9],a[10],a[11])[3] u.cx[0,1] u.u3(a[12],a[13],a[14])[1] u.cx[1,2] u.u3(a[15],a[16],a[17])[2] u.cx[2,3] return u

早速計算します。その他のパラメータ類は先ほどと同じにします。

start = time.time() #initial parameters a = ainit.copy() #result list ar = [] h = 0.01 e = 0.01 for i in range(nsteps): r = np.random.randint(0,len(inp)) loss = L(E((ix(inp[r])+mps(a)).run()),tgt[r]) ar.append(loss) at = [0 for i in range(len(a))] for j in range(len(a)): aa = a.copy() aa[j] += h loss2 = L(E((ix(inp[r])+mps(aa)).run()),tgt[r]) at[j] = a[j] - e*(loss2 - loss)/h a = at plt.plot(ar) plt.show() print(time.time() - start)
<Figure size 432x288 with 1 Axes>output
5.819611310958862

10D080C7-4812-4041-96FF-F4E57DC0EACA.png

7.919758081436157

精度です。

#training accuracy np.mean([E((ix(inp[i])+mps(a)).run())/tgt[i] for i in range(len(inp))]) #=>0.9697437828925157
0.9700788727843366
#validation accuracy np.mean([E((ix(inp_c[i])+mps(a)).run())/tgt_c[i] for i in range(len(inp_c))]) #=>0.9696755262709482
0.970138094683916

© 2024, blueqat Inc. All rights reserved