Nobisuke
Dekisugi
RAG
Privacy policy
2021/01/31 07:13
1
量子コンピュータのアルゴリズムを今後作っていくにあたって、いろいろ覚えることが増えそうです。今回はざっくりテンソルネットワークを学んでいきたいと思います。
テンソル(英: tensor, 独: Tensor)とは、線形的な量または線形的な幾何概念を一般化したもので、基底を選べば、多次元の配列として表現できるようなものである。 https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%B3%E3%82%BD%E3%83%AB
大きなテンソルをより小さなテンソルに分解してネットワーク化したものです。
足の数によって記法が変わります。*をノード、-をエッジとして見たときに、
・足が一つはベクトル
---*
・足が2つは行列
---*---
・足が3つはオーダー3のテンソル
---*---
|
(表現の仕方がわからないので、なんとなく書いちゃいましたが、、、)
ノード同士はエッジで接続され、それぞれ計算されます。
・ベクトルと行列 ベクトルと行列は計算するとベクトルに、足の数は1になります。
--*--* = ----*
v'_i = \sum_jM_{ij}v_j
・行列同士 行列同士は行列になります。足の数も変わりません。
--*--*-- = --*--
私たちは今後これを量子コンピュータの計算に応用したいので、波動関数・状態ベクトルなどというものと対応させてシミュレータやアプリケーションに応用をしていきたいと考えます。一般的に量子コンピュータとテンソルネットワークを直接結び付けて書いたようなものは多分少ないのと、全部を学ぶのは大変なので必要な量子コンピュータに特化したところを考えて見たいと思います。
量子コンピュータは通常量子ビットは|0>と|1>の重ね合わせで表現されます。
これをテンソルネットワークに対応させると、1ノードのテンソルに対応して、ベクトルでかけます。
-*
上記の波動関数を書き直すと、1量子ビットは、
また、複数量子ビットの場合には、(*同士が並んでる時はテンソル積を取ると考えて)、
-*
-*
-*
-*
これはパラメータの数が量子ビットの場合にはになってしまうので、今後はこのパラメータを減らせるようにネットワークを構成して、パラメータ数を減らして波動関数を効率的に表現できるように目指していきます。
上記波動関数が2次元のオーダーNのテンソルで表現でき、行列同士のテンソルは行列になるということなので、量子回路のようなユニタリ操作を状態ベクトルに対して適用するようなものはテンソルネットワークで表現できそうです。
量子回路の構造によって効率的なテンソルネットワークでかけて、効率的な波動関数の表現があるとすると、シミュレータやアプリケーションに応用できそうです。
特にアプリケーションに関しても、完全にランダムな形式は難しそうですが、機械学習や量子化学計算や、社会問題もハミルトニアンの形式にある程度の傾向や偏りがある場合には効率的なテンソルネットワークの表現が作れそうです。
テンソルネットワークの計算は実際はツール経由で行います。ここではGoogleからでたTensornetworkをnumpyバックエンドとして使って見たいと思います。
Googleから提供されているオープンソースソフトウェアです。インストールはpip経由で、
Copy !pip3 install tensornetwork
となります。blueqat cloudで使ってます。
基本はテンソルネットワークの形を決めてそれぞれをつなぎます。参考は下記になります。
Copy import numpy as np import tensornetwork as tn a = tn.Node(np.ones((10,))) b = tn.Node(np.ones((10,))) edge = a[0] ^ b[0] final_node = tn.contract(edge) print(final_node.tensor)
10.0
こうすると
10.0
が得られます。
まず読み込みます
import numpy as np
import tensornetwork as tn
次にノードを指定します。今回はAとBというベクトルを指定します。
a = tn.Node(np.ones((10,)))
b = tn.Node(np.ones((10,)))
aとbにエッジを指定します。
edge = a[0] ^ b[0]
そして、これらのテンソル縮約をとって表示をして見ます。
final_node = tn.contract(edge)
print(final_node.tensor)
今回は、AとB共に下記のような10この要素が全て1のベクトルなので、
計算結果は、
と、スカラー量となります。
計算して見ます。
Copy a = tn.Node(np.ones((5))) b = tn.Node(np.ones((5,5))) edge = a[0] ^ b[0] final_node = tn.contract(edge) print(final_node.tensor)
[5. 5. 5. 5. 5.]
これはベクトルに、
[5. 5. 5. 5. 5.]
行列の順番とかよくわからなかったですが、、、要素数を揃えたらいけました。
Copy a = tn.Node(np.ones((5,3))) b = tn.Node(np.ones((5,2))) edge = a[0] ^ b[0] final_node = tn.contract(edge) print(final_node.tensor)
[[5. 5.]
[5. 5.]
[5. 5.]]
[[5. 5.]
[5. 5.]
[5. 5.]]
バックエンドを変えることで、GPUモードが使えます。
Copy !pip install tensornetwork jax jaxlib import numpy as np import jax import tensornetwork as tn
例題があったので、それを実行して見ます。
Copy def calculate_abc_trace(a, b, c): an = tn.Node(a) bn = tn.Node(b) cn = tn.Node(c) an[1] ^ bn[0] bn[1] ^ cn[0] cn[1] ^ an[0] return (an @ bn @ cn).tensor a = np.ones((4096, 4096)) b = np.ones((4096, 4096)) c = np.ones((4096, 4096)) tn.set_default_backend("numpy") print("Numpy Backend") %timeit calculate_abc_trace(a, b, c) tn.set_default_backend("jax") print("JAX Backend") %timeit np.array(calculate_abc_trace(a, b, c))
Numpy Backend
4.38 s ± 49.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
JAX Backend
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
2.1 s ± 61.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
高速化されているようです。blueqatの無料版ではGPU対応してないのえ、CPUになります。
Numpy Backend
4.38 s ± 49.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
JAX Backend
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
2.1 s ± 61.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
テンソルネットワーク理論を使って簡単にノードの計算や縮約の計算ができました。様々なテンソルネットワークの記述を駆使して効率的な計算が並列計算機を使ってできるというのでとても楽しいと思います。
量子コンピュータに活用するのが目的なので、シミュレータとして使って見たいと思います。
以上です。
© 2024, blueqat Inc. All rights reserved