@yuichirominato 2019.02.28更新 198views

【RBM】量子ゲートで量子ボルツマンマシン


はじめに

量子アニーリングの解の分布を使って学習更新するボルツマンマシンのモデルを見てきましたが、これを量子ゲートに展開する方法を確認してみたいと思います。

前回までの内容

前回までのコード

import matplotlib.pyplot as plt
from blueqat.opt import Opt
import networkx as nx
import numpy as np
import collections

class rbm:
    def __init__(self):
        self.J = []
        self.v = 0
        self.h = 0
        self.n = 0
     
    def setRBM(self,v=4,h=4):
        n = v+h
        self.v = v
        self.h = h
        self.n = n
        self.J = np.diag([np.random.randint(99)/100 for i in range(n)])
        for i in range(v):
            for j in range(v,n):
                self.J[i][j] = np.random.randint(99)/100
        return self
     
    def network(self):
        G= nx.Graph()     
        edges = []
        for i in range(self.v):
            edges += [(i,j) for j in range(self.v,self.n)]
        G.add_edges_from(edges)
        pos = {}
        for i in range(self.n):
            if i<self.v:
                pos[i] = [0.1,0.1*(self.v-i)]
            else:
                pos[i] = [0.2,0.1*(self.h+self.v-i)]
        nx.draw_networkx(G,pos)
        plt.show()

    def getMdata(self,vdata):
        hdata = [0 for i in range(self.h)]
        for i in range(self.h):
            hdata[i] += self.J[self.v+i][self.v+i]
            for j in range(self.v):
                hdata[i] += vdata[j]*self.J[j][self.v+i]
            hdata[i] = sigm(hdata[i])
        Mdata = np.diag(vdata+hdata)
        for i in range(self.v):
            for j in range(self.h):
                Mdata[i][self.v+j] = vdata[i]*hdata[j]
        return Mdata

    def getMmodel(self,beta):
        c = Opt().add(beta*self.J).run(shots=100)
        ccc = counter(c)
        print(ccc)
        Mmodel = np.diag([0 for i in range(self.n)])
        for i,j in ccc.items():
            temp = [*i]
            temp = list(map(lambda x:int(x)/j,temp))
            Mmodel = Mmodel + np.diag(temp)
            for k in range(self.v):
                for l in range(self.h):
                    Mmodel[k][self.v+l] = temp[k]*temp[self.v+l]
        return Mmodel

    def train(self,vdata,alpha=0.9,epsilon=0.1,beta=1):
         a.J = alpha*a.J-epsilon*(a.getMdata(vdata)-a.getMmodel(beta))
         return self
    
def counter(narr):
    dis = []
    for i in range(len(narr)):
        dis.append(''.join([str(x) for x in narr[i]]))
    return collections.Counter(dis)

def bars(cc):
    index = []
    value = []
    for k,v in counter(cc).items():
        index.append(k)
        value.append(v)
    plt.bar(index,value)
    plt.show()

def sigm(xx):
     return 1/(1+np.exp(-xx))

ここまでできてればあとは、シンプルです。一応学習更新式を確認してみます。

$$b_{i,t+1} = \alpha * b_{i,t} + \epsilon(v_{data} -v_{model})\\ c_{i,t+1} = \alpha * c_{i,t} + \epsilon(h_{data} -h_{model})\\ w_{ij,t+1} = \alpha * w_{ij,t} + \epsilon(vh_{data} -vh_{model})$$

QAOAで解分布を取ってみる

上記を量子アニーリングからQAOAにするには、

c = Opt().add(self.J).run(shots=100)

の部分をQAOAにするだけです。QAOAに関してはざっくりこちらで、

実行方法に関しては、

試しに単体でやってみます。適当な例題を作ってみてやってみます。まずは普通のアニーリング

a = rbm().setRBM(4,4)

モデルを作ります。逆温度パラメータを設定して解分布を取ります。

c = Opt().add(0.1*a.J).run(shots=100)

次にQAOAをやってみます。先ほどのQUBOを量子ゲートのVQE+QAOAで計算します。

c = Opt().add(0.1*a.J).qaoa(shots=100)

結果は、

c.most_common(12)

#=>
(((0, 0, 0, 0, 0, 0, 0, 0), 0.4072213424296961),
 ((0, 0, 1, 0, 0, 0, 0, 0), 0.18526818450665403),
 ((0, 0, 0, 0, 0, 1, 0, 0), 0.11036387100498915),
 ((0, 0, 0, 0, 0, 0, 1, 0), 0.0563814515181246),
 ((0, 0, 1, 0, 0, 1, 0, 0), 0.037928302595366385),
 ((0, 1, 0, 0, 0, 0, 0, 0), 0.03717892125780595),
 ((0, 0, 0, 0, 0, 0, 0, 1), 0.01960392923651757),
 ((0, 0, 0, 0, 0, 1, 1, 0), 0.01683173270893821),
 ((0, 1, 1, 0, 0, 0, 0, 0), 0.016153879541206548),
 ((0, 0, 0, 1, 0, 0, 0, 0), 0.015227462186776007),
 ((0, 0, 1, 0, 0, 0, 1, 0), 0.014427956796671807),
 ((0, 0, 0, 0, 1, 0, 0, 0), 0.007943667895491113))

グラフにすると、

index = []
value = []
k=0
for i,j in c.most_common(12):
    index.append(k)
    value.append(j)
    k += 1
plt.bar(index,value)
plt.show()

並びが変わりましたが、だいたい同じ結果になりました。

このようにして、量子ゲートモデルでも、確率分布をとって計算をすることができました。実機につなげたいところですが、VQEは色々制限があるので、いいVQEマシンを今後用意してみたいと思います。以上です!

Recommended


Wikiへ移動