Closed WATLE closed 2 years ago
poetry.lock がこわれてたので直しました
Solverを使うようにしました。 細かい調整などはまだです。 とりあえずBFGS部分のテストは手元で通りました。 formatとかはまだです。 Adamは元のAdam()と同じでは通らないと思います。shapeが違うので。
いや、通るか
generation をうまく実装しました ちゃんとSolverが使えます
私も#99 生成モデル確認して、コードみてみます。
元論文読んで、元コードと実装されたコードを見ました。
以下、こんな感じの実装がされていると思いました。
データを与えると、そのデータが持つ確率分布を推定して、確率分布を生成します。
- VQEと同様の回路 create_farhi_neven_ansatz() を使う。
- fit_direct_distribution() は、テスト用に直接確率分布を与えれるようになっている。
- predict(): 確率分布推定
`y_pred_in = self._predict_inner().get_vector()` を実行すると
量子回路の状態ベクトルから設定したデータの確率振幅が取り出せる。
複素共役を取って、かけて確率分布にして返す。
- fit(): 学習。スケール調整して、fit_direct_distribution()を呼び出す。
- conving(): カーネル関数。畳み込み演算を行う。
- cost_func(): 損失関数は、MMDを使う。
カーネル関数の辺りは、まだざっとしか見れておりません。。 最適化アルゴリズムをAdamにして、BFGSと比較するとよいかも知れません。。
@WATLE テストコードのスキップされている test_bar_stripe() と test_bar_stripe_hamming() ですが QNNGeneretorクラスの第2パラメータにSolverを指定する必要があるかと思います。
評価アルゴリズム: Adam() と カーネルタイプ: gauss 等の組み合わせで実行しようとした所、zero divのエラーになりました。。
テストコード
from math import exp
import time
import numpy as np
from skqulacs.circuit import create_farhi_neven_ansatz
from skqulacs.qnn import QNNGeneretor
from skqulacs.qnn.solver import Bfgs, Adam
# 80%程度の正解率は出る。
def test_bar_stripe(solver, karnel_type):
n_qubit = 9
depth = 22
circuit = create_farhi_neven_ansatz(n_qubit, depth)
#qnn = QNNGeneretor(circuit, Bfgs(), "same", 0, 9)
qnn = QNNGeneretor(circuit, solver, karnel_type, 0, 9)
prob_list = np.zeros(512)
for i in range(8):
prob_list[i * 73] += 0.0625
uuu = 0
if (i & 4) > 0:
uuu += 64
if (i & 2) > 0:
uuu += 8
if (i & 1) > 0:
uuu += 1
prob_list[uuu * 7] += 0.0625
datas = np.random.choice(a=range(512), size=100000, p=prob_list)
maxiter = 600
qnn.fit(datas, maxiter)
data_param = qnn.predict()
gosa = 0
for i in range(512):
gosa += abs(data_param[i] - prob_list[i])
if prob_list[i] > 0.001:
print(i, data_param[i])
assert gosa < 0.4
print("gosa: ", gosa)
start = time.time()
test_bar_stripe(Bfgs(), "same")
elapsed_time = time.time() - start
print ("Bfgs and same: {0}".format(elapsed_time) + "[sec]")
start = time.time()
test_bar_stripe(Bfgs(), "gauss")
elapsed_time = time.time() - start
print ("Bfgs and same: {0}".format(elapsed_time) + "[sec]")
start = time.time()
test_bar_stripe(Adam(), "same")
elapsed_time = time.time() - start
print ("Adam and same: {0}".format(elapsed_time) + "[sec]")
start = time.time()
test_bar_stripe(Adam(), "gauss")
elapsed_time = time.time() - start
print ("Adam and same: {0}".format(elapsed_time) + "[sec]")
エラーログ
root@c45c40769a39:~/temp/20200518# python s.py
Traceback (most recent call last):
File "/root/temp/20200518/s.py", line 51, in <module>
test_bar_stripe(Bfgs(), "gauss")
File "/root/temp/20200518/s.py", line 33, in test_bar_stripe
qnn.fit(datas, maxiter)
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/generation.py", line 83, in fit
return self.fit_direct_distribution(train_scaled, maxiter)
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/generation.py", line 89, in fit_direct_distribution
return self.solver.run(
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/solver.py", line 74, in run
result = minimize(
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_minimize.py", line 676, in minimize
res = _minimize_bfgs(fun, x0, args, jac, callback, **options)
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_optimize.py", line 1296, in _minimize_bfgs
sf = _prepare_scalar_function(fun, x0, jac, args=args, epsilon=eps,
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_optimize.py", line 263, in _prepare_scalar_function
sf = ScalarFunction(fun, x0, args, grad, hess,
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_differentiable_functions.py", line 158, in __init__
self._update_fun()
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_differentiable_functions.py", line 251, in _update_fun
self._update_fun_impl()
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_differentiable_functions.py", line 155, in update_fun
self.f = fun_wrapped(self.x)
File "/usr/local/lib/python3.9/dist-packages/scipy/optimize/_differentiable_functions.py", line 137, in fun_wrapped
fx = fun(np.copy(x), *args)
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/generation.py", line 195, in cost_func
conv_diff = self.conving(data_diff)
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/generation.py", line 148, in conving
beta = -0.5 / self.gauss_sigma
ZeroDivisionError: float division by zero
root@c45c40769a39:~/temp/20200518# python s.py
Traceback (most recent call last):
File "/root/temp/20200518/s.py", line 56, in <module>
test_bar_stripe(Adam(), "same")
File "/root/temp/20200518/s.py", line 33, in test_bar_stripe
qnn.fit(datas, maxiter)
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/generation.py", line 83, in fit
return self.fit_direct_distribution(train_scaled, maxiter)
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/generation.py", line 89, in fit_direct_distribution
return self.solver.run(
File "/usr/local/lib/python3.9/dist-packages/skqulacs/qnn/solver.py", line 121, in run
y[iter % len(y) : iter % len(y) + 5],
ZeroDivisionError: integer division or modulo by zero
ちょっと見てみます。
評価アルゴリズム: Adam() と カーネルタイプ: gauss 等の組み合わせで実行しようとした所、zero divのエラーになりました。。
よく見たら指定しているパラメータが0だからですね。。
以下のような感じになりました。 Adam()は、最適化の処理自体は速いですが、精度が悪いですね。。 Bfgs()で、カーネルは gauss の方がよい結果がでましたが、結果が安定しない気がしています。
※Adam() の場合、_cost_func_grad()の更新時に、イテレーション数があわないため、一時的にイテレーション数を512に書き換えて実行しました。
結果
# python s.py
/usr/local/lib/python3.9/dist-packages/scipy/optimize/_linesearch.py:155: ComplexWarning: Casting complex values to real discards the imaginary part
stp, phi1, derphi1, task = minpack2.dcsrch(alpha1, phi1, derphi1,
0 (0.122732656334093+0j)
7 (0.059786281708801875+0j)
56 (0.060585023834097695+0j)
63 (0.060847034043319065+0j)
73 (0.060640690587019055+0j)
146 (0.06141697300562065+0j)
219 (0.05917982291209568+0j)
292 (0.059938702802542876+0j)
365 (0.0616526192593371+0j)
438 (0.060140588647330205+0j)
448 (0.05951952352845949+0j)
455 (0.0611376097740885+0j)
504 (0.059992893239780236+0j)
511 (0.12348470656661531+0j)
gosa: 0.05788974751359935
Bfgs and same: 73.56574845314026[sec]
0 (0.12471545025285323+0j)
7 (0.062039626623453206+0j)
56 (0.061765524845125035+0j)
63 (0.061748263713792814+0j)
73 (0.06128091097183188+0j)
146 (0.062441298707139374+0j)
219 (0.06198032845480563+0j)
292 (0.0624442754395209+0j)
365 (0.059927025342892126+0j)
438 (0.06256253929742411+0j)
448 (0.06201679016502146+0j)
455 (0.062159586399058345+0j)
504 (0.061863337599216806+0j)
511 (0.12503881466219652+0j)
gosa: 0.016235162970578393
Bfgs and gauss: 57.84395384788513[sec]
0 (0.11500141585727836+0j)
7 (0.04806137224609201+0j)
56 (0.05461186662747158+0j)
63 (0.05178309712504523+0j)
73 (0.0037156778337893636+0j)
146 (0.005867236658809195+0j)
219 (0.05188175378918395+0j)
292 (0.05154550348272225+0j)
365 (0.0018954332212237418+0j)
438 (0.001299931607384525+0j)
448 (0.052877636801976026+0j)
455 (0.051848747593337775+0j)
504 (0.04831710617517458+0j)
511 (0.11414771996089268+0j)
gosa: 0.6942910020392374
Adam and same: 2.8896913528442383[sec]
0 (0.11097037286877917+0j)
7 (0.039327967724504934+0j)
56 (0.055329816298311525+0j)
63 (0.04980675708311158+0j)
73 (0.009020876379897236+0j)
146 (0.0024222674417955564+0j)
219 (0.037703831464262386+0j)
292 (0.036674488492328836+0j)
365 (0.015907798087379632+0j)
438 (0.001585521338788234+0j)
448 (0.04844926053711909+0j)
455 (0.052112764296371336+0j)
504 (0.03655547907220827+0j)
511 (0.11368371640404687+0j)
gosa: 0.7808981650221903
Adam and gauss: 2.896209955215454[sec]
root@c45c40769a39:~/temp/20200518#
Adam()で、maxiterを600から40倍の24000で試しました。 あまり結果が安定していないですし、Bfgs()に比べて、それほど良い精度にはなりませんでした。。
root@c45c40769a39:~/temp/seisei# python s.py
0 (0.12282892078419376+0j)
7 (0.061298138928447765+0j)
56 (0.06186084965831065+0j)
63 (0.061397889445434804+0j)
73 (0.06304935828499061+0j)
146 (0.06076738982625458+0j)
219 (0.06342910553990032+0j)
292 (0.06296746657256204+0j)
365 (0.06166897356026799+0j)
438 (0.06140369405171732+0j)
448 (0.06059533922977197+0j)
455 (0.06342394756245828+0j)
504 (0.06271674956569716+0j)
511 (0.12358929774132336+0j)
gosa: 0.02417901354855656
Adam and same: 113.7599241733551[sec]
root@c45c40769a39:~/temp/seisei#
root@c45c40769a39:~/temp/seisei#
root@c45c40769a39:~/temp/seisei#
root@c45c40769a39:~/temp/seisei# python s.py
0 (0.1231643378083779+0j)
7 (0.060739238826695144+0j)
56 (0.06216170162834887+0j)
63 (0.06200357226838695+0j)
73 (0.06320408727754581+0j)
146 (0.06138740929427611+0j)
219 (0.06180659618484891+0j)
292 (0.06354351337990076+0j)
365 (0.06357588556832985+0j)
438 (0.0637136485634689+0j)
448 (0.06402319181040111+0j)
455 (0.0613884496474543+0j)
504 (0.06229059835451905+0j)
511 (0.125730999023939+0j)
gosa: 0.015116191974185678
Adam and same: 115.66483664512634[sec]
root@c45c40769a39:~/temp/seisei#
root@c45c40769a39:~/temp/seisei# python s.py
0 (0.12430451674398407+0j)
7 (0.06250563897611967+0j)
56 (0.0625659989704961+0j)
63 (0.06293780930964371+0j)
73 (0.061823651975557004+0j)
146 (0.06305458666753191+0j)
219 (0.06288752990957323+0j)
292 (0.06262393601371959+0j)
365 (0.06103062576565881+0j)
438 (0.06294921786483577+0j)
448 (0.061935657377202566+0j)
455 (0.06260952946299758+0j)
504 (0.06266552324393973+0j)
511 (0.12423873820846883+0j)
gosa: 0.008333619858258232
Adam and same: 114.75292730331421[sec]
結局、マージOKですか?
簡単なチュートリアルノートブック用意していただけますか?
@WATLE もし、チュートリアル作るのに時間がかかりそうなら、言ってください。サポートします。
チュートリアル作ります
チュートリアルつくりました
@WATLE
生成モデルですが、以下のような説明がいいかなと思いました。
生成モデルとは、 教師なし学習の一種で、 入力データを学習し、 それと特徴が似た出力をするモデルです。
生成モデルとは、教師なし学習の一種で、与えられた入力データから確率分布を学習し、それに応じて新しいサンプルを生成するモデルです。
後、コードの説明をもう少し入れた方がよいかなと思いました。 例えば、
:exclamation: No coverage uploaded for pull request base (
main@4ff6849
). Click here to learn what that means. The diff coverage isn/a
.
@@ Coverage Diff @@
## main #174 +/- ##
=======================================
Coverage ? 90.61%
=======================================
Files ? 12
Lines ? 863
Branches ? 163
=======================================
Hits ? 782
Misses ? 50
Partials ? 31
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update 4ff6849...3f3fce6. Read the comment docs.
LGTMです! いかがでしょうか? > @kosukemtr
少しだけ修正お願いします。チュートリアルに文章やコメントに謎の全角スペースが入っているのと、よくわからないコメント (# VQEと同じ回路を用いている とかです) を直してほしいです。よろしくお願いします。それ以外は LGTM です
全角消しました
mainをマージして、qulcasを0.3.0に上げたら、実行できて、テスト通った