Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ja/quantum/tutorials/noise.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

ノイズ

現代の量子コンピュータにはノイズが存在します。量子ビットは、周囲の環境からの干渉、不完全な製造、TLS、場合によってはガンマ線による影響を受けやすくなっています。大規模にエラー訂正が行われるまで、現在のアルゴリズムはノイズが存在する場合でも機能する必要があります。そのため、現在のノイズがある量子コンピュータでの量子アルゴリズムとモデルの機能の検証は、重要なステップです。

このチュートリアルでは、高レベルの tfq.layers API を介して、TFQ でのノイズの多い回路のシミュレーションの基本を見ていきます。

セットアップ

!pip install tensorflow==2.7.0 tensorflow-quantum==0.7.2
!pip install -q git+https://github.com/tensorflow/docs
# Update package resources to account for version changes. import importlib, pkg_resources importlib.reload(pkg_resources)
import random import cirq import sympy import tensorflow_quantum as tfq import tensorflow as tf import numpy as np # Plotting import matplotlib.pyplot as plt import tensorflow_docs as tfdocs import tensorflow_docs.plots

1. 量子ノイズを理解する

1.1 基本的な回路ノイズ

量子コンピュータのノイズは、そこから測定されるビット文字列サンプルに影響を与えます。直感的には、ノイズの多い量子コンピュータは、下の図のようにランダムな場所でゲートを「挿入」、「削除」、または「置換」すると考えてみてください。

ノイズに対処するには、単一の純粋な状態 ψ|\psi \rangle を使用せず、使用する回路で発生する可能性のあるすべてのノイズのアンサンブルρ=jpjψjψj\rho = \sum_j p_j |\psi_j \rangle \langle \psi_j | を処理すると考えます。ここで、pjp_j は、システムが ψj|\psi_j \rangle にある確率を示します。

上の図を再度検討してみましょう。90% の場合にシステムが完全に実行され、つまり、10% の場合にこの 1 つの障害モードだけでエラーが発生したことが事前にわかっていた場合、アンサンブルは次のようになります。

$\rho = 0.9 |\psi_\text{desired} \rangle \langle \psi_\text{desired}| + 0.1 |\psi_\text{noisy} \rangle \langle \psi_\text{noisy}| $

回路でエラーが発生する可能性のある場合が 1 つ以上ある場合、アンサンブル ρ\rho には 2 つ以上の項が含まれます(発生する可能性のあるノイズごとに 1 つ)。ρ\rho は、ノイズの多いシステムを表す密度行列と呼ばれます。

1.2 チャネルを使用して回路ノイズをモデル化する

残念ながら、実際には、回路でエラーが発生する可能性のあるすべての場合とその正確な確率を知ることはほぼ不可能です。単純には、回路の各演算後に、その演算がどのようなエラーを発生するかをを大まかに捕らえるチャンネルがあると考えることができます。簡単なノイズのある回路を作成します。

def x_circuit(qubits): """Produces an X wall circuit on `qubits`.""" return cirq.Circuit(cirq.X.on_each(*qubits)) def make_noisy(circuit, p): """Add a depolarization channel to all qubits in `circuit` before measurement.""" return circuit + cirq.Circuit(cirq.depolarize(p).on_each(*circuit.all_qubits())) my_qubits = cirq.GridQubit.rect(1, 2) my_circuit = x_circuit(my_qubits) my_noisy_circuit = make_noisy(my_circuit, 0.5) my_circuit
my_noisy_circuit

以下のようにノイズのない密度行列 ρ\rho を調べます。

rho = cirq.final_density_matrix(my_circuit) np.round(rho, 3)

以下のようにノイズのある密度行列 ρ\rho を調べます。

rho = cirq.final_density_matrix(my_noisy_circuit) np.round(rho, 3)

2 つの異なる ρ \rho を比較すると、ノイズが状態の振幅(結果としてサンプリング確率)に影響を与えていることがわかります。ノイズのない場合は、常に 11 |11\rangle 状態をサンプリングすることを期待します。しかし、ノイズの多い状態では、00 |00\rangle または 01 |01\rangle または 10 |10\rangle もサンプリングする確率がゼロ以外になります。

"""Sample from my_noisy_circuit.""" def plot_samples(circuit): samples = cirq.sample(circuit + cirq.measure(*circuit.all_qubits(), key='bits'), repetitions=1000) freqs, _ = np.histogram(samples.data['bits'], bins=[i+0.01 for i in range(-1,2** len(my_qubits))]) plt.figure(figsize=(10,5)) plt.title('Noisy Circuit Sampling') plt.xlabel('Bitstring') plt.ylabel('Frequency') plt.bar([i for i in range(2** len(my_qubits))], freqs, tick_label=['00','01','10','11']) plot_samples(my_noisy_circuit)

ノイズのない場合は常に 11|11\rangle になります。

"""Sample from my_circuit.""" plot_samples(my_circuit)

ノイズをもう少し増やすと、希望する動作(11|11\rangle のサンプリング)とノイズを区別するのがますます難しくなります。

my_really_noisy_circuit = make_noisy(my_circuit, 0.75) plot_samples(my_really_noisy_circuit)

注意: 回路内のさまざまなチャネルを試して、ノイズを生成してみてください。Cirq と TFQ の両方でサポートされている共通チャネルはこちらをご覧ください。

2. TFQ の基本ノイズ

ノイズが回路の実行にどのように影響するかを理解することで、TFQ でノイズがどのように機能するかを調べることができます。TensorFlow Quantum は、密度行列シミュレーションの代わりに、モンテカルロ/軌道ベースのシミュレーションを使用します。これは、密度行列シミュレーションのメモリの複雑さにより、従来の完全密度行列シミュレーション方法では、大規模なシミュレーションが 20 キュービット未満に制限されるためです。モンテカルロ/軌道では、メモリコストを増やす代わりに時間コストを低減します。backend='noisy' オプションは、すべての tfq.layers.Sampletfq.layers.SampledExpectation、および tfq.layers.Expectation で使用できます。(Expectation の場合、これは必要な repetitions パラメータを追加します)。

2.1 TFQ でのノイズの多いサンプリング

TFQ と軌道シミュレーションを使用して上記のプロットを再作成するには、tfq.layers.Sample を使用します。

"""Draw bitstring samples from `my_noisy_circuit`""" bitstrings = tfq.layers.Sample(backend='noisy')(my_noisy_circuit, repetitions=1000)
numeric_values = np.einsum('ijk,k->ij', bitstrings.to_tensor().numpy(), [1, 2])[0] freqs, _ = np.histogram(numeric_values, bins=[i+0.01 for i in range(-1,2** len(my_qubits))]) plt.figure(figsize=(10,5)) plt.title('Noisy Circuit Sampling') plt.xlabel('Bitstring') plt.ylabel('Frequency') plt.bar([i for i in range(2** len(my_qubits))], freqs, tick_label=['00','01','10','11'])

2.2 ノイズの多いサンプルベースの期待値

ノイズの多いサンプルベースの期待値計算を行うには、tfq.layers.SampleExpectation を使用します。

some_observables = [cirq.X(my_qubits[0]), cirq.Z(my_qubits[0]), 3.0 * cirq.Y(my_qubits[1]) + 1] some_observables

回路からのサンプリングを介して、ノイズのない期待値の推定値を計算します。

noiseless_sampled_expectation = tfq.layers.SampledExpectation(backend='noiseless')( my_circuit, operators=some_observables, repetitions=10000 ) noiseless_sampled_expectation.numpy()

ノイズの多いバージョンと比較します。

noisy_sampled_expectation = tfq.layers.SampledExpectation(backend='noisy')( [my_noisy_circuit, my_really_noisy_circuit], operators=some_observables, repetitions=10000 ) noisy_sampled_expectation.numpy()

ノイズが特に ψZψ\langle \psi | Z | \psi \rangle に影響を与えていることがわかります。my_really_noisy_circuit は 0 に向かって非常に速く集中します。

2.3 ノイズの多い分析的期待値の計算

ノイズの多い分析的期待値の計算は、上記とほぼ同じです。

noiseless_analytic_expectation = tfq.layers.Expectation(backend='noiseless')( my_circuit, operators=some_observables ) noiseless_analytic_expectation.numpy()
noisy_analytic_expectation = tfq.layers.Expectation(backend='noisy')( [my_noisy_circuit, my_really_noisy_circuit], operators=some_observables, repetitions=10000 ) noisy_analytic_expectation.numpy()

3. ハイブリッドモデルと量子データノイズ

TFQ でいくつかのノイズの多い回路シミュレーションを実装したので、ノイズのあるパフォーマンスとノイズのないパフォーマンスを比較対照し、ノイズが量子およびハイブリッド量子の古典的モデルにどのように影響するかを実験できます。モデルまたはアルゴリズムがノイズに対してロバストであるかどうかを確認するためには、まず、次のような回路全体の脱分極モデルでテストしてみます。

回路の各タイムスライス(モーメントと呼ばれることもあります)には、そのタイムスライスの各ゲート演算の後に脱分極チャネルが追加されています。脱分極チャネルは、確率 ppX,Y,Z{X, Y, Z } のいずれかを適用するか、確率 1p1-p で何も適用しません(元の演算を維持する)。

3.1 データ

この例では、tfq.datasets モジュールで準備された回路をトレーニングデータとして使用できます。

qubits = cirq.GridQubit.rect(1, 8) circuits, labels, pauli_sums, _ = tfq.datasets.xxz_chain(qubits, 'closed') circuits[0]

小さなヘルパー関数を作成すると、ノイズの多い場合とノイズのない場合のデータを生成するのに役立ちます。

def get_data(qubits, depolarize_p=0.): """Return quantum data circuits and labels in `tf.Tensor` form.""" circuits, labels, pauli_sums, _ = tfq.datasets.xxz_chain(qubits, 'closed') if depolarize_p >= 1e-5: circuits = [circuit.with_noise(cirq.depolarize(depolarize_p)) for circuit in circuits] tmp = list(zip(circuits, labels)) random.shuffle(tmp) circuits_tensor = tfq.convert_to_tensor([x[0] for x in tmp]) labels_tensor = tf.convert_to_tensor([x[1] for x in tmp]) return circuits_tensor, labels_tensor

3.2 モデル回路を定義する

回路の形状で量子データができたので、このデータをモデル化するための回路が必要になります。データと同様に、オプションでノイズを含むこの回路を生成するヘルパー関数を記述します。

def modelling_circuit(qubits, depth, depolarize_p=0.): """A simple classifier circuit.""" dim = len(qubits) ret = cirq.Circuit(cirq.H.on_each(*qubits)) for i in range(depth): # Entangle layer. ret += cirq.Circuit(cirq.CX(q1, q2) for (q1, q2) in zip(qubits[::2], qubits[1::2])) ret += cirq.Circuit(cirq.CX(q1, q2) for (q1, q2) in zip(qubits[1::2], qubits[2::2])) # Learnable rotation layer. # i_params = sympy.symbols(f'layer-{i}-0:{dim}') param = sympy.Symbol(f'layer-{i}') single_qb = cirq.X if i % 2 == 1: single_qb = cirq.Y ret += cirq.Circuit(single_qb(q) ** param for q in qubits) if depolarize_p >= 1e-5: ret = ret.with_noise(cirq.depolarize(depolarize_p)) return ret, [op(q) for q in qubits for op in [cirq.X, cirq.Y, cirq.Z]] modelling_circuit(qubits, 3)[0]

3.3 モデルの構築とトレーニング

データとモデル回路を構築しました。必要な最後のヘルパー関数は、ノイズの多いまたはノイズのないハイブリッド量子 tf.keras.Model の両方をアセンブルできる関数です。

def build_keras_model(qubits, depolarize_p=0.): """Prepare a noisy hybrid quantum classical Keras model.""" spin_input = tf.keras.Input(shape=(), dtype=tf.dtypes.string) circuit_and_readout = modelling_circuit(qubits, 4, depolarize_p) if depolarize_p >= 1e-5: quantum_model = tfq.layers.NoisyPQC(*circuit_and_readout, sample_based=False, repetitions=10)(spin_input) else: quantum_model = tfq.layers.PQC(*circuit_and_readout)(spin_input) intermediate = tf.keras.layers.Dense(4, activation='sigmoid')(quantum_model) post_process = tf.keras.layers.Dense(1)(intermediate) return tf.keras.Model(inputs=[spin_input], outputs=[post_process])

4. パフォーマンスを比較する

4.1 ノイズのないベースライン

データ生成とモデル構築コードを使用して、ノイズのない設定とノイズの多い設定でモデルのパフォーマンスを比較対照できるようになりました。最初に、ベースラインとなるノイズのないトレーニングを実行します。

training_histories = dict() depolarize_p = 0. n_epochs = 50 phase_classifier = build_keras_model(qubits, depolarize_p) phase_classifier.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.02), loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy']) # Show the keras plot of the model tf.keras.utils.plot_model(phase_classifier, show_shapes=True, dpi=70)
noiseless_data, noiseless_labels = get_data(qubits, depolarize_p) training_histories['noiseless'] = phase_classifier.fit(x=noiseless_data, y=noiseless_labels, batch_size=16, epochs=n_epochs, validation_split=0.15, verbose=1)

結果と精度を調べます。

loss_plotter = tfdocs.plots.HistoryPlotter(metric = 'loss', smoothing_std=10) loss_plotter.plot(training_histories)
acc_plotter = tfdocs.plots.HistoryPlotter(metric = 'accuracy', smoothing_std=10) acc_plotter.plot(training_histories)

4.2 ノイズの多いモデルを比較する

ノイズの多い構造を持つ新しいモデルを作成し、上記と比較します。コードはほぼ同じです。

depolarize_p = 0.001 n_epochs = 50 noisy_phase_classifier = build_keras_model(qubits, depolarize_p) noisy_phase_classifier.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.02), loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy']) # Show the keras plot of the model tf.keras.utils.plot_model(noisy_phase_classifier, show_shapes=True, dpi=70)

注意: モデル図では、脱分極確率がゼロではなくなったため、tfq.layers.PQC の代わりに tfq.layers.NoisyPQC が表示されます。 ノイズの多いシミュレーションはノイズのないシミュレーションよりもはるかにコストがかかるため、トレーニングにはかなり長い時間がかかります。

noisy_data, noisy_labels = get_data(qubits, depolarize_p) training_histories['noisy'] = noisy_phase_classifier.fit(x=noisy_data, y=noisy_labels, batch_size=16, epochs=n_epochs, validation_split=0.15, verbose=1)
loss_plotter.plot(training_histories)
acc_plotter.plot(training_histories)

成功: ノイズの多いモデルは、軽度の脱分極ノイズの下でトレーニングを行うことができました。さまざまなノイズモデルを試して、トレーニングがいつどのように失敗するかを確認してください。また、tfq.layerstfq.noise の下のノイズの多い機能にも注意してください。