注釈
このページは docs/migration/01_migration_guide_0.5.ipynb から生成されました。
Qiskit Machine Learning v0.5 移行ガイド¶
このチュートリアルでは、コードを Qiskit Machine Learning v0.4 から v0.5 へマイグレーションするプロセスをガイドします。
はじめに¶
Qiskit Machine Learning のリリース0.5における主な焦点は、Qiskitで導入されたPrimitiveへの量子カーネルや量子ニューラルネットワークなどのベースの計算ブロックの移行と、アルゴリズムにおけるprimitiveの拡張サポートです。
目次:
Primitiveの概要
新量子カーネル
新量子ニューラル・ネットワーク
その他の注意すべき非推奨事項
Primitiveの概要¶
量子コンピューターが古典コンピューターと異なる点は、出力に非古典的な確率分布を生成することができる点です。確率分布の基本的な操作は、確率分布からのサンプリングと確率分布に基づく量の推定です。このサンプリングと推定という操作が、量子アルゴリズム開発の基本的な構成要素となっています。そのため、 `こちら <https://research.ibm.com/blog/qiskit-runtime-for-useful-quantum-computing>`_で発表したように,この2つの操作を実装したSamplerとEstimatorという基本プリミティブが導入されました。
Samplerクラスは、量子回路のビット列の確率または準確率を計算します。基本クラスは qiskit.primitives.BaseSampler です。
Estimatorクラスは、量子回路や観測値の期待値を推定するクラスです。基本クラスは qiskit.primitives.BaseEstimator です。
Qiskit Terraはコアインターフェースと2つの実装を提供します:
状態ベクトルベースのリファレンス実装です。この実装はバックエンドやシミュレーターを必要とせず、 quantum_info パッケージのクラスに依存しています。
バックエンドベースのprimitiveは、primitiveを直接サポートしないプロバイダー/バックエンドをサポートするためのものです。この実装では、primitiveに渡すバックエンドのインスタンスが必要です。
Qiskit Terra primitiveに関するより詳しい情報は documentation に記載されています。
他の実装についても触れておくとよいでしょう:
Aer primitiveは、Aerシミュレーターで使用されるものです。これらはTerraの対応するインターフェースを拡張したもので、Terraのprimitiveと同じように使用することができます。詳しくは documentation を参照してください。
IBMのデバイスで使用するためのRumtive primitiveです。実際のハードウェアでのクラウドコンピューティングに特化した実装です。`こちら __<https://qiskit.org/documentation/partners/qiskit_ibm_runtime/apidocs/runtime_service.html>``__を参照してください。
Terraはprimitiveとともに、QMLで非常に有用なprimitive的アルゴリズムを持っており、0.5の新機能で使用されています。
Algorithms to calculate the gradient of a quantum circuit. For each core primitive there’s a corresponding base interface that defines quantum circuit gradient. The documentation on gradients is here.
Algorithms that compute the fidelity or 「closeness」 of pairs of quantum states. Currently, only one implementation is available that requires a sampler primitive and is based on the compute-uncompute method. The documentation is here.
この2つのアルゴリズムは、コアprimitiveと非常によく似ており、同じメソッドシグネチャーを共有しているため、primitiveパッケージに含まれていないにもかかわらず、高レベルのprimitiveとして呼び出すことができます。
新量子カーネル¶
以前の実装では、1つのクラス QuantumKernel がすべてを担っていました。
回路の構築
回路の実行と回路間の重なりの評価
学習用パラメーターを提供
パラメーターに割り当てられた値の追跡
この実装は高度で柔軟性に欠け、新しいprimitiveのサポートを追加するのは困難でした。そこで、柔軟かつ拡張可能な新しい量子カーネルを開発しました。新しい設計の目標は以下の通りです。
Primitiveに移行し、Fidelity アルゴリズムを活用します。これにより、ユーザーは独自のFidelity 計算の実装をプラグインすることができます。
訓練可能な機能を専用のクラスに抽出する。
他のカーネルが拡張可能な基本クラスを導入する。
量子カーネルの新しい設計を次の図に示します。
新しいカーネルは、 quantum_instance
パラメーターを除いて、同じインターフェースと同じパラメーターを公開しています。このパラメーターは直接的に置き換えることができず、代わりにfidelityパラメーターを使用しなければなりません。バックエンドの処理・選択は、以前は``quantum_instance``を使用していましたが、現在は fidelity
に与えられたSampler primitiveを介して処理されます。
図に示すような新しい階層が導入されます。
ベースとなる抽象クラス BaseKernel が導入されました。すべての具体的な実装は、このクラスを継承する必要があります。
Fidelity ベースの量子カーネル FidelityQuantumKernel が追加されました。これは、以前の量子カーネル実装をそのまま置き換えたものです。新しいクラスは、オーバーラップを推定し、カーネル行列を構築するために、Fidelity(忠実度)のインスタンスを取るという違いがあります。
また、量子カーネルを学習するための抽象クラス TrainableKernel が追加されました.
Fidelity ベースの量子カーネル TrainableFidelityQuantumKernel が導入されました.これは、従来の量子カーネルを 置き換える もので、訓練可能なカーネルが必要な場合に使用します。トレーナである QuantumKernelTrainer は,新型と旧型の両方の量子カーネルを受け入れることができるようになりました。
以前の量子カーネル実装である`QuantumKernel <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.kernels.QuantumKernel.html>`__ は,新しい抽象クラスを継承しており,新しく導入されたインターフェースと互換性を持っています.この実装は 現在 非推奨 であり,将来のリリースで非推奨となり,その後削除される予定です。新しいプリミティブベースの量子カーネルを使用する必要があります。
QSVC、QSVR、その他のカーネルベースのアルゴリズムは更新され、両方の実装で動作するようになります。
例えば,QSVM分類器は以下のように学習させることができます。
データセットの準備¶
ランダム性を固定します。
[1]:
from qiskit.utils import algorithm_globals
algorithm_globals.random_seed = 123456
Scikit-learn を使用して簡単なデータセットを生成します。
[2]:
from sklearn.datasets import make_blobs
features, labels = make_blobs(
n_samples=20,
centers=2,
center_box=(-1, 1),
cluster_std=0.1,
random_state=algorithm_globals.random_seed,
)
量子カーネルの以前の実装¶
前回の実装では、 QuantumInstance
のインスタンスを作成するところから始めました。このクラスは、量子回路が実行される場所を定義します。今回は、量子インスタンスに状態ベクトルシミュレーターをラップしています。
[3]:
from qiskit import BasicAer
from qiskit.utils import QuantumInstance
sv_qi = QuantumInstance(
BasicAer.get_backend("statevector_simulator"),
seed_simulator=algorithm_globals.random_seed,
seed_transpiler=algorithm_globals.random_seed,
)
その後、量子カーネルを作ります。
[4]:
from qiskit.circuit.library import ZZFeatureMap
from qiskit_machine_learning.kernels import QuantumKernel
feature_map = ZZFeatureMap(2)
previous_kernel = QuantumKernel(feature_map=feature_map, quantum_instance=sv_qi)
そして最終的にはSVM分類器に適合します。
[5]:
from qiskit_machine_learning.algorithms import QSVC
qsvc = QSVC(quantum_kernel=previous_kernel)
qsvc.fit(features, labels)
qsvc.score(features, labels)
[5]:
0.95
新しい量子カーネル実装¶
新しい実装では、Fidelityのインスタンスを作成するところから始めます。Fidelityはオプションで、何も渡されない場合は量子カーネルが自動的に作成します。しかし、ここでは、説明のために手動で作成します。Fidelityのインスタンスを作成するために、Samplerを渡します。Samplerとは、量子回路を実行する際に参照する実装のことであり、量子回路が実行される場所を定義します。QiskitのRuntime serviceを活用するために、QiskitRuntimeService <https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.QiskitRuntimeService.html> からSampler インスタンスを作成することができます。
[6]:
from qiskit.algorithms.state_fidelities import ComputeUncompute
from qiskit.primitives import Sampler
fidelity = ComputeUncompute(sampler=Sampler())
次に、fidelify (忠実度) インスタンスで新しい量子カーネルを作成します。
[7]:
from qiskit_machine_learning.kernels import FidelityQuantumKernel
feature_map = ZZFeatureMap(2)
new_kernel = FidelityQuantumKernel(feature_map=feature_map, fidelity=fidelity)
そして、前と同じようにSVM分類器を当てはめます。
[8]:
from qiskit_machine_learning.algorithms import QSVC
qsvc = QSVC(quantum_kernel=new_kernel)
qsvc.fit(features, labels)
qsvc.score(features, labels)
[8]:
0.95
新量子ニューラル・ネットワーク¶
量子ニューラルネットワークの変更は、量子カーネルほど劇的なものではありません。また、既存のニューラルネットワークを置き換えるものとして、2つの新しいネットワークが導入されています。SamplerQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.SamplerQNN.html>`__と`EstimatorQNN で、既存の`CircuitQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.CircuitQNN.html>`__、OpflowQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.OpflowQNN.html>`__ 、`TwoLayerQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.TwoLayerQNN.html>`__を置き換えるもので、詳細は以下の通りです。
SamplerQNN¶
新しい`Sampler Quantum Neural Network <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.SamplerQNN.html>`__は、sampler primitive、sampler Gradientsを活用し、`CircuitQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.CircuitQNN.html>`__を 直接置き換える ものです。
新しい`SamplerQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.SamplerQNN.html>`__ は既存の`CircuitQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.CircuitQNN.html>`__と同様のインターフェイスを公開しますが、いくつかの違いがあります。1つは quantum_instance
パラメーターです。このパラメーターは直接の置き換えがなく、代わりに sampler
パラメーターを使用する必要があります。gradient
パラメーターは`CircuitQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.CircuitQNN.html>`__の実装と同じ名前を保っていますが、入力としてOpflow gradientクラスを受け付けなくなりました。代わりに、このパラメーターは(オプションでカスタム)primitive gradientを期待します。 sampling
option は、現在samplerが公開していない情報であり、将来の低レベルprimitiveに対応する可能性があるため、当面の間、削除されました。
`CircuitQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.CircuitQNN.html>`__をベースとした`VQC <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.algorithms.VQC.html>`__のような既存の学習アルゴリズムは、両方の実装を受け入れるように更新されました。`NeuralNetworkClassifier <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.algorithms.NeuralNetworkClassifier.html>`__の実装は変更されていません。
既存の`CircuitQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.CircuitQNN.html>`__は、現在 保留中の非推奨 となっており、将来のリリースで非推奨となり、その後削除される予定です。
We’ll show how to train a variational quantum classifier using both networks. For this purposes we re-use the dataset generated for the quantum kernel. For both quantum neural networks we still have to construct a feature map, an ansatz and combine them into a single quantum circuit.
[9]:
from qiskit import QuantumCircuit
from qiskit.circuit.library import RealAmplitudes
num_inputs = 2
feature_map = ZZFeatureMap(num_inputs)
ansatz = RealAmplitudes(num_inputs, reps=1)
circuit = QuantumCircuit(num_inputs)
circuit.compose(feature_map, inplace=True)
circuit.compose(ansatz, inplace=True)
同様に、解釈関数も必要です。ここでは、ビット列を:math:0 または \(1\) にマップする、通常のパリティ関数を定義します。
[10]:
def parity(x):
return "{:b}".format(x).count("1") % 2
両方のネットワークから同じ結果が得られるように、初期点を固定します。
[11]:
initial_point = algorithm_globals.random.random(ansatz.num_parameters)
``CircuitQNN``を用いた分類器の構築¶
``CircuitQNN``のインスタンスを作成し、量子カーネル用に作成した量子インスタンスを再利用します。
[12]:
from qiskit_machine_learning.neural_networks import CircuitQNN
circuit_qnn = CircuitQNN(
circuit=circuit,
input_params=feature_map.parameters,
weight_params=ansatz.parameters,
interpret=parity,
output_shape=2,
quantum_instance=sv_qi,
)
ネットワークから分類器を構築し、それを訓練し、スコアをつけます。良い結果を目指しているわけではないので、全体の実行時間を短縮するために、反復回数は少なめに設定されています。
[13]:
from qiskit.algorithms.optimizers import COBYLA
from qiskit_machine_learning.algorithms import NeuralNetworkClassifier
classifier = NeuralNetworkClassifier(
neural_network=circuit_qnn,
loss="cross_entropy",
one_hot=True,
optimizer=COBYLA(maxiter=40),
initial_point=initial_point,
)
classifier.fit(features, labels)
classifier.score(features, labels)
[13]:
0.6
``SamplerQNN``を用いた分類器の構築¶
``QuantumInstance``の代わりに参照元``Sampler``のインスタンスを作成します。
[14]:
from qiskit.primitives import Sampler
sampler = Sampler()
ここで、SamplerQNN``のインスタンスを作成します。 ``CircuitQNN
との違いは、量子インスタンスではなく、samplerを渡すことです。
[15]:
from qiskit_machine_learning.neural_networks import SamplerQNN
sampler_qnn = SamplerQNN(
circuit=circuit,
input_params=feature_map.parameters,
weight_params=ansatz.parameters,
interpret=parity,
output_shape=2,
sampler=sampler,
)
通常通り分類器を構築し、フィットさせます。 neural_network
として、作成した``SamplerQNN`` を渡していますが、これだけの違いです。
[16]:
classifier = NeuralNetworkClassifier(
neural_network=sampler_qnn,
loss="cross_entropy",
one_hot=True,
optimizer=COBYLA(maxiter=40),
initial_point=initial_point,
)
classifier.fit(features, labels)
classifier.score(features, labels)
[16]:
0.6
量子ニューラルネットワークを手動で構築する代わりに、 VQC``をトレーニングすることができます。 ``VQC``は、量子インスタンスとsamplerを受け取り、渡された内容に応じて、``CircuitQNN
と SamplerQNN
をそれぞれ自動的に構築します。
EstimatorQNN¶
新しい`Estimator quantum neural network <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.EstimatorQNN.html>`__は、Estimator primitive、Estimator gradientsを活用し、`OpflowQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.OpflowQNN.html>`__を **直接置き換える ** ものです。
新しい EstimatorQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.EstimatorQNN.html>`__は、既存の`OpflowQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.OpflowQNN.html>`__と同様のインターフェースを公開しますが、いくつかの相違点があります。1つは`quantum_instance` パラメーターです。このパラメーターには直接的な代替がなく、代わりに``estimator`` パラメーターを使用する必要があります。gradient
パラメーターは OpflowQNN の実装と同じ名前を持ちますが、入力としてOpflow gradientクラスを受け付けなくなりました。代わりに、このパラメーターは(オプションでカスタム)primitive gradientを期待するものです。
`VQR <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.algorithms.VQR.html>`__のような`TwoLayerQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.TwoLayerQNN.html>`__に基づく既存の学習アルゴリズムは、両方の実装を受け入れるように更新されます。`NeuralNetworkRegressor <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.algorithms.NeuralNetworkRegressor.html>`__の実装は変更されていません。
既存の`OpflowQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.OpflowQNN.html>`__は、現在 保留中の非推奨 となっており、将来のリリースで非推奨となり、その後削除される予定です。
We’ll show how to train a variational quantum regressor using both networks. We start from generating a simple regression dataset.
[17]:
import numpy as np
num_samples = 20
eps = 0.2
lb, ub = -np.pi, np.pi
features = (ub - lb) * np.random.rand(num_samples, 1) + lb
labels = np.sin(features[:, 0]) + eps * (2 * np.random.rand(num_samples) - 1)
まだ、量子ニューラルネットワークともに、特徴量マップ、ansatzを構築し、それらを組み合わせて一つの量子回路にする必要があります。
[18]:
from qiskit.circuit import Parameter
num_inputs = 1
feature_map = QuantumCircuit(1)
feature_map.ry(Parameter("input"), 0)
ansatz = QuantumCircuit(1)
ansatz.ry(Parameter("weight"), 0)
circuit = QuantumCircuit(num_inputs)
circuit.compose(feature_map, inplace=True)
circuit.compose(ansatz, inplace=True)
両方のネットワークから同じ結果が得られるように、初期点を固定します。
[19]:
initial_point = algorithm_globals.random.random(ansatz.num_parameters)
``OpflowQNN``を用いた回帰器の構築¶
OpflowQNN
のインスタンスを作成し、量子カーネル用に作成した量子インスタンスを再利用します。
[20]:
from qiskit.opflow import PauliSumOp, StateFn
from qiskit_machine_learning.neural_networks import OpflowQNN
observable = PauliSumOp.from_list([("Z", 1)])
operator = StateFn(observable, is_measurement=True) @ StateFn(circuit)
opflow_qnn = OpflowQNN(
operator=operator,
input_params=feature_map.parameters,
weight_params=ansatz.parameters,
quantum_instance=sv_qi,
)
ネットワークから回帰器を構築し、それを訓練し、スコアをつけます。この場合、勾配ベースのオプティマイザーを使用するため、ネットワークは勾配の枠組みを利用し、データセットの性質上、非常に早く収束します。
[21]:
from qiskit.algorithms.optimizers import L_BFGS_B
from qiskit_machine_learning.algorithms import NeuralNetworkRegressor
regressor = NeuralNetworkRegressor(
neural_network=opflow_qnn,
optimizer=L_BFGS_B(maxiter=5),
initial_point=initial_point,
)
regressor.fit(features, labels)
regressor.score(features, labels)
[21]:
0.9609133430994375
EstimatorQNN
を用いた回帰器の構築¶
リファレンスであるEstimatorのインスタンスを作成します。Qiskitのruntimeサービスを活用するため、`QiskitRuntimeService <https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.QiskitRuntimeService.html>`__からEstimatorのインスタンスを作成することもできます。
[22]:
from qiskit.primitives import Estimator
estimator = Estimator()
ここで、EstimatorQNN
のインスタンスを作成する。このネットワークは \(Z^{\otimes n}\) という観測量をします。ここで \(n\) は量子ビットの数です。
[23]:
from qiskit_machine_learning.neural_networks import EstimatorQNN
estimator_qnn = EstimatorQNN(
circuit=circuit,
input_params=feature_map.parameters,
weight_params=ansatz.parameters,
estimator=estimator,
)
変量量子回帰器を構築し、それをフィッティングします。この場合、勾配ベースのオプティマイザーを使用するため、ネットワークは自動的に作成される`default estimator gradient <https://qiskit.org/documentation/stubs/qiskit.algorithms.gradients.ParamShiftEstimatorGradient.html>`__を使用します。
[24]:
from qiskit.algorithms.optimizers import L_BFGS_B
from qiskit_machine_learning.algorithms import VQR
regressor = NeuralNetworkRegressor(
neural_network=estimator_qnn,
optimizer=L_BFGS_B(maxiter=5),
initial_point=initial_point,
)
regressor.fit(features, labels)
regressor.score(features, labels)
[24]:
0.9609133430994375
量子ニューラルネットワークを手動で構築する代わりに、 VQR``をトレーニングすることができます。 ``VQR``は、量子インスタンスとestimatorを受け取り、渡された内容に応じて、 ``TwoLayerQNN
と EstimatorQNN
をそれぞれ自動的に構築します。
その他の注意すべき非推奨事項¶
上記で明確に言及されていない他のいくつかのコンポーネントも、非推奨または非推奨保留となっています:
`TwoLayerQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.TwoLayerQNN.html>`__は非推奨です。ユーザーは代わりにEstimatorQNN <https://qiskit.org/documentation/machine-learning/stubs/qiskit_machine_learning.neural_networks.EstimatorQNN.html>`__を使うべきです。
Distribution Learners パッケージは完全に非推奨です.このパッケージは DiscriminativeNetwork, GenerativeNetwork, NumPyDiscriminator, PyTorchDiscriminator, QuantumGenerator, QGAN などのクラスが含まれています。代わりに、`新しいQGANチュートリアル <../tutorials/04_torch_qgan.ipynb>`__を参照してください。このチュートリアルでは、量子ニューラルネットワークを用いたPyTorchベースのQGANの構築方法をステップバイステップで紹介しています。
Runtimeパッケージは非推奨です。このパッケージには、アルゴリズムインターフェイスにQiskit Runtimeを組み込み、クラウドでのアルゴリズムやスクリプトの使用を容易にするQiskit Programsへのクライアントが含まれています。Primitiveやruntimeを活用するには、QiskitRuntimeService を使用する必要があります。
[25]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.22.1 |
qiskit-aer | 0.11.1 |
qiskit-ignis | 0.7.0 |
qiskit | 0.33.0 |
qiskit-machine-learning | 0.5.0 |
System information | |
Python version | 3.7.9 |
Python compiler | MSC v.1916 64 bit (AMD64) |
Python build | default, Aug 31 2020 17:10:11 |
OS | Windows |
CPUs | 4 |
Memory (Gb) | 31.837730407714844 |
Mon Nov 07 23:08:59 2022 GMT Standard Time |
This code is a part of Qiskit
© Copyright IBM 2017, 2022.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.