PennyLane : 初級 Tutorials : 高度な使用方法

PennyLane 初級 Tutorials : 高度な使用方法 (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 10/28/2019

* 本ページは、PennyLane : Tutorials : Learn PennyLane の次のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
$$

 

初級 Tutorials : 高度な使用方法

前の 3 つの入門的なチュートリアル (量子回転Gaussian 変換、そして プラグイン & ハイブリッド計算) で PennyLane の基本的な概念を調べました、これらは量子ビット- と CV-モデル量子計算、勾配ベースの最適化、そしてハイブリッド古典的量子計算の構築を含みます。このチュートリアルでは、PennyLane のより高度な特徴の幾つかをハイライトします。

 

マルチ測定

総ての前のサンプルでは、単一の期待値だけを持つ量子関数を考えました。実際には、ワイヤ毎に一つまで、PennyLane はマルチ測定の返し (= return) をサポートします。

通常は、PennyLane と NumPy の PennyLane-提供バージョンをインポートすることから始めて、計算のために 2-ワイヤ量子ビットデバイスをセットアップします :

import pennylane as qml
from pennylane import numpy as np

dev = qml.device("default.qubit", wires=2)

単純なサンプル回路から始めます、これは 2-量子ビット entangled 状態を生成し、それから各ワイヤで Pauli Z 演算子の期待値を評価します。

@qml.qnode(dev)
def circuit1(param):
    qml.RX(param, wires=0)
    qml.CNOT(wires=[0, 1])
    return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

量子ビットの entanglement の degree は param の値により決定されます。$\frac{\pi}{2}$ の値について、それらは最大限に entangled しています。この場合、各サブシステムの reduced 状態は完全に混合し、ローカル期待値は — 測定しているもののように — ゼロに平均されます。

print(circuit1(np.pi / 2))
[2.22044605e-16 2.22044605e-16]

回路の出力が shape=(2,), i.e., 2-次元ベクトルを持つ NumPy 配列であることに気付くでしょう。これらの 2 次元は量子関数 circuit1 で返される期待値の数に一致しています。

Note
回路の期待値は両者とも ローカル であることを強調しておくことは重要です、i.e., この回路は $\left\langle \sigma_z\right\rangle_0$ と $\left\langle \sigma_z\right\rangle_1$ を評価していて、$\left\langle \sigma_z\otimes \sigma_z\right\rangle_{01}$ ではありません (ここで観測可能量がどのワイヤに位置するか下付きの添字が示しています)。

異なる return 型を混在してさえも良いです、例えば期待値と分散です :

@qml.qnode(dev)
def circuit2(param):
    qml.RX(param, wires=0)
    qml.CNOT(wires=[0, 1])
    return qml.expval(qml.PauliZ(0)), qml.var(qml.PauliZ(1))

 

キーワード引数

自動微分が扱いやすい特徴である一方で、時に微分されない計算パイプライン (e.g., パラメータ化された量子関数 $f(x;\bf{\theta})$ への入力 $x$ や機械学習のための訓練データ) の特定の一部を望みます。

PennyLane はキーワード引数は決して微分されない一方で、量子関数への総ての位置引数は微分されるために利用可能であるというパターンを使用します。こうして、PennyLane に含まれる勾配降下ベースの Optimizer を使用しているとき、非キーワード引数で現れる総ての数値パラメータは更新され、一方でキーワード引数として含まれる総ての数値は更新されません。

Note
回路を構築するとき、キーワード引数は関数シグネチャーにデフォルト値を提供することで定義されます。量子回路関数が呼び出されるたびにキーワード引数値が渡されることを好む場合には、デフォルト値は None として設定できます。

例えば、2 つの引数を受け取る量子ノードを作成しましょう ; 微分可能な回路パラメータ param、そして固定された回路パラメータ fixed です :

@qml.qnode(dev)
def circuit3(param, fixed=None):
    qml.RX(fixed, wires=0)
    qml.RX(param, wires=1)
    qml.CNOT(wires=[0, 1])
    return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

回路を呼び出すとき、キーワード引数 fixed に値を供給できます :

print(circuit3(0.1, fixed=-0.2))

print(circuit3(0.1, fixed=1.2))
[0.98006658 0.97517033]
[0.36235775 0.36054748]

勾配を計算するときキーワード引数は考慮されませんので、Jacobian は依然として 2-次元ベクトルです。

j3 = qml.jacobian(circuit3, argnum=0)
print(j3(2.5, fixed=3.2))
[0.         0.59745161]

ひとたび定義されれば、キーワード引数は常にキーワード引数として渡されなければなりません。PennyLane はキーワード引数値を位置引数として渡すことをサポートしていません。例えば、次の回路評価はfixed パラメータの値を正しく更新します :

print(circuit3(0.1, fixed=0.4))
[0.92106099 0.91645953]

けれども、fixed パラメータを位置引数として渡すことを試みは動作しません、そして PennyLane は代わりにデフォルト値 (None) を使用することを試みます :

>>> circuit3(0.1, 0.4)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-949e31911afa> in <module>()
----> 1 circuit3(0.1, 0.4)
~/pennylane/variable.py in val(self)
    134
    135         # The variable is a placeholder for a keyword argument
--> 136         value = self.kwarg_values[self.name][self.idx] * self.mult
    137         return value
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
 

以上