Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/zh-cn/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% 的时间内出现错误,那么我们的集成算法应为:

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

如果电路可能出错的方式不止一种,那么集成算法 ρ\rho 所包含的项目也不止两个(每个可能发生的新嘈杂实现均有一个)。ρ\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)

比较这两个不同的 ρ \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.SampledExpectationtfq.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 中实现噪声电路模拟,可以通过比较噪声性能与无噪声性能,对噪声如何影响量子和混合量子经典模型进行实验。要想了解模型或算法是否对噪声具有鲁棒性,最好先在电路范围的去极化模型下进行测试,该模型如下所示:

其中,电路的每个时间切片(有时称为时间段)在该时间切片中的每个门操作之后附加了一个去极化通道。去极化通道应用 X,Y,Z{X, Y, Z } 之一,概率为 pp,或不应用(保持原始操作),概率为 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.NoisyPQC,而非 tfq.layers.PQC,因为去极化概率不再为零。由于噪声模拟远比无噪声模拟要花费得多,所以训练需要的时间更长。

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 情况下的噪声功能。