量子機械学習で利用する連続値のデータ入出力について
量子コンピュータを利用して機械学習をすると量子ビットが01の離散値を取るのでデータ入力に連続値がとりづらいと考える場合に、連続値を入れて連続値を出力として取り出す方法を学びます。
データの入力は連続値の角度で
データの入力は角度で行います。量子ビットには任意回転角ゲートがありますので、連続値を角度に変換して行います。
from blueqat import Circuit
import numpy as np
#データを0以上1未満の値で適当に作成
data = np.random.rand()
data
0.41307280106851774
この値を角度に変換してRXゲートに入れます。RXゲートは角度を指定してから量子ビット番号を指定します。
data2 = data*2*np.pi
c = Circuit().rx(data2)[0]
print(c)
c.run()
Circuit(1).rx(2.595412954469227)[0]
array([0.26970807+0.j , 0. -0.96294214j])
c.run_with_ibmq(returns='draw', output='mpl')
<Figure size 133.526x144.48 with 1 Axes>
今回は状態ベクトルを確認しましたが、複雑な値が出ています。サンプリングは同じ回路で測定をして、実行回数を指定する必要があります。
(c+ Circuit().m[:]).run(shots=100)
Counter({'1': 93, '0': 7})
(c+ Circuit().m[:]).run_with_ibmq(returns='draw', output='mpl')
<Figure size 193.726x144.48 with 1 Axes>
こうすることでデータを入力した回路からサンプルを取り出せました。
状態ベクトルやサンプリングの値を期待値に直す
入力は連続値ができました。出力はこの状態ベクトルを使って連続値をとりだせます。もともと状態ベクトルは複素数で連続値になってますので、簡単に取り出せばよさそうです。期待値を計算します。期待値は状態ベクトルとハミルトニアンから作れます。今回は1量子ビットですのでZの期待値を計算します。
計算は簡単です。式は
#状態ベクトルを取り出します
result = c.run()
print(result)
#上記の式通り計算すればOK
exptZ = result.conj()@np.array([[1,0],[0,-1]])@result
exptZ.real
[0.26970807+0.j 0. -0.96294214j]
-0.8545151185209441
計算結果が出ました。連続値が取り出せました。もちろん手計算してもいいです。上記の式は状態ベクトルに対して、
exptZ = np.abs(result[0])**2 - np.abs(result[1])**2
exptZ
-0.8545151185209441
同じ値が取り出せました。次にサンプリングをしてみます。同じ式で10000回計算をしてみます。0と1が所望の回数でます。
sample = 10000
result = (c + Circuit().m[:]).run(shots=sample)
print(result)
Counter({'1': 9321, '0': 679})
期待値の計算は簡単です(0の出た回数-1の出た階数)/サンプル数です。
exptZ = (result['0'] - result['1'])/sample
exptZ
-0.8642
比較的近い値が出ました。大数の法則でたくさん計算して近づけていくしかありません。100000回計算してみます。
sample = 100000
result = (c + Circuit().m[:]).run(shots=sample)
print(result)
exptZ = (result['0'] - result['1'])/sample
exptZ
Counter({'1': 92755, '0': 7245})
-0.8551
ちょっとずつ近づいてる気もします。精度が必要とされる量子機械学習の現場ではシミュレータを使うことが多いので力業で状態ベクトルを使うことが多いです。実機を使うときには状態ベクトルが使えないのでサンプリングでやりましょう。以上です。