1. 项目概述:当量子计算遇见噪声与架构挑战
最近在折腾量子机器学习(QML)的项目,特别是量子神经网络(QNN),一个绕不开的坎就是“噪声”。无论是超导、离子阱还是光子平台,当前的含噪声中等规模量子(NISQ)设备都深受其扰。你精心设计的量子线路,在模拟器上跑得风生水起,一旦部署到真机,性能就可能断崖式下跌。这感觉就像在理想实验室里调教出的赛车手,一上真实赛道就晕头转向。
我一直在寻找一种方法,不是被动地忍受噪声,或者寄希望于未来更“干净”的硬件,而是主动地在算法层面增强QNN的“抗噪”能力。这就是“CNL-QNN”这个项目的核心出发点。它试图解决一个非常实际的问题:如何让QNN在充满噪声的现实量子硬件上,依然保持可靠且优越的性能?
CNL-QNN这个名字拆解开来,就是“Classical Noise Layer - Quantum Neural Network”。它的核心思想颇具巧思:在经典的数据预处理阶段,主动引入可控的、模拟量子噪声特性的“经典噪声层”(CNL),对输入数据进行“污染”或“增强”。然后,利用可微架构搜索(Differentiable Architecture Search, DARTS)技术,自动为这个“噪声增强版”的数据,寻找一个最优的量子神经网络架构。简单说,就是“以毒攻毒”加上“智能设计”。我们先在经典域用可控的噪声给模型“打疫苗”,让它提前适应嘈杂环境,再让算法自己找到最能抵抗这种噪声的量子电路结构。
这个方法的价值在于,它巧妙地将硬件限制转化为算法设计的先验知识。我们不再把噪声视为纯粹的敌人,而是将其作为一种训练信号和架构搜索的约束条件。这对于希望在近期NISQ设备上验证和应用QML的研究者和开发者来说,是一条非常务实的路径。无论你是刚接触量子计算想理解噪声影响,还是已经在部署QML模型遇到瓶颈,这个思路都能提供新的工具和视角。
2. 核心思路拆解:为何是“经典噪声层”与“可微搜索”的联姻?
要理解CNL-QNN,不能只看它做了什么,更要理解它为什么选择这么做。这背后是对NISQ时代QML面临的核心挑战的深刻回应。
2.1 量子噪声的本质与经典模拟的可行性
量子噪声并非单一现象,而是一系列非理想操作的集合,主要来源于量子比特与环境的不完美耦合。常见类型包括:
- 退相干噪声:量子比特失去量子叠加态,退化到经典状态,包括弛豫(T1过程)和退相位(T2过程)。这好比你的存储设备会随时间慢慢丢失数据。
- 门操作误差:执行量子逻辑门(如旋转门、受控非门)时产生的偏差。这类似于经典计算机的CPU运算会有舍入误差,但量子门误差通常更大且更复杂。
- 测量误差:读取量子比特状态时产生的错误。好比用一把不准的尺子去测量长度。
直接在量子硬件上研究这些噪声对模型的影响,成本高昂且不灵活。CNL-QNN的关键洞见在于:许多量子噪声对数据的影响,可以在经典计算机上,通过精心设计的数学变换进行高保真度的模拟。例如,退相位噪声可以模拟为在数据表示的布洛赫球面上施加一个随机旋转;测量误差可以模拟为对模型输出概率分布施加一个混淆矩阵。
因此,“经典噪声层”的本质,是一个可编程的、参数化的噪声模拟器。它被插入在经典输入数据送入量子线路之前。在训练阶段,我们以一定的概率或强度激活这些噪声层,让模型“看到”的是经过各种噪声污染的数据。这样做的直接好处是:
- 成本极低:所有噪声模拟都在经典计算机上完成,无需消耗宝贵的量子计算资源。
- 完全可控:我们可以精确控制噪声的类型、强度和关联性,这是真实硬件难以做到的,便于进行系统性研究。
- 增强泛化:模型在训练时见识了各种“可能的糟糕情况”,相当于进行了大规模的数据增强,有望提升在真实嘈杂硬件上的泛化能力。
注意:经典噪声层是对量子噪声效应的“功能性模拟”,而非物理机制的完全复现。其目标是让模型学习到噪声扰动下的不变特征,而不是精确模拟量子动力学。因此,噪声层参数的设计需要基于对目标硬件噪声谱的粗略估计或经验。
2.2. 可微架构搜索:为噪声环境定制量子电路
传统的QNN设计大多依赖人工经验,比如选择固定的纠缠层结构、旋转门集合等。但在噪声环境下,什么样的架构最鲁棒?是更深的线路配合更强的表达能力,还是更浅的线路以减少噪声累积?是全局纠缠更有效,还是局部纠缠更抗噪?这些问题很难凭直觉回答。
这就是引入可微架构搜索(DARTS)的原因。DARTS的核心是将离散的架构选择(比如,两个量子比特之间是采用CNOT门还是CZ门?或者是否要插入一个特定的旋转门?)松弛化为连续的权重参数。整个搜索空间(一个包含所有可能候选操作的“超网络”)变得可微,因此我们可以使用基于梯度的优化方法(如SGD),同时优化网络架构的权重和模型本身的参数。
在CNL-QNN的框架下,DARTS扮演了“智能架构师”的角色:
- 搜索空间定义:我们为量子电路的每个可能插入操作的位置(例如,每一层后的纠缠方式),定义一组候选操作。这些操作可以包括不同类型的双比特门(CNOT, CZ, iSWAP等)、单比特门组合、甚至包括“零操作”(即跳过该连接)。
- 联合训练:在训练过程中,我们不仅用带有经典噪声的数据来更新QNN的参数(如旋转角度),同时也通过梯度更新每个候选操作的架构权重。经过充分训练后,对于每个位置,权重最大的那个候选操作就被认为是该位置的最优选择。
- 噪声感知的架构:由于整个训练过程是在“经典噪声层”提供的扰动数据下进行的,DARTS所搜索到的最优架构,天生就是针对这种噪声环境进行优化的。它自动学会了避开在噪声下不稳定的复杂操作,倾向于选择那些在噪声干扰下仍能保持信息传递效率的结构。
两者的协同效应:经典噪声层为训练提供了一个“嘈杂但可控”的环境,相当于设置了考题。可微架构搜索则在这个特定考场中,寻找最能解题(即最鲁棒)的“思维模式”(电路架构)。两者结合,实现了从“数据增强”到“架构自适应”的闭环优化,这是单纯使用其中任何一种技术都难以达到的效果。
3. 核心组件深度解析:从理论到实现细节
理解了核心思路,我们深入到具体实现层面。CNL-QNN不是一个黑箱,它的有效性建立在几个精心设计的组件之上。
3.1 经典噪声层的设计与实现策略
设计一个有效的CNL,关键在于选取能恰当反映目标量子噪声统计特性的变换。以下是一些常见且易于实现的经典噪声层方案:
3.1.1 加性高斯噪声层这是最直接的模拟方式,特别适用于近似退相干或门误差导致的微小、随机扰动。
- 操作:对输入的经典特征向量
x(通常已被归一化),添加一个从高斯分布N(0, σ^2)中采样的噪声向量ε,即x' = x + ε。 - 参数:噪声标准差
σ是可控参数。在训练中,可以采用退火策略,初期σ较小,让模型先学习基础特征;后期逐渐增大σ,提升其鲁棒性。 - 物理对应:粗略模拟门操作中的随机过旋转或欠旋转误差。
- 实现示例(Python/PyTorch风格):
import torch import torch.nn as nn class AdditiveGaussianNoise(nn.Module): def __init__(self, sigma=0.1, active_during_training=True): super().__init__() self.sigma = sigma self.active_during_training = active_during_training def forward(self, x): if self.training and self.active_during_training: # 生成与x同形状的噪声 noise = torch.randn_like(x) * self.sigma return x + noise else: # 推理阶段或训练未激活时,直接返回原数据 return x实操心得:
sigma的初始值设置很重要。可以从一个非常小的值(如0.01)开始,根据验证集在干净数据和噪声数据上的性能差距来调整。差距过大说明模型过拟合干净数据,需增大sigma;差距过小或模型性能整体太差,则需减小sigma。
3.1.2 随机丢弃层受经典深度学习Dropout的启发,但在这里有新的含义。
- 操作:以概率
p随机将输入特征向量的某些维度置零。 - 参数:丢弃概率
p。 - 物理对应:可以非常抽象地模拟量子比特完全退相干(弛豫到基态)或测量误差中完全丢失信号的情况。它强制模型不依赖于任何单个特征,从而学习更冗余、更鲁棒的表征。
- 注意:在量子计算中,信息的表示方式与经典不同,因此这种模拟是高度抽象的。但其正则化效果对于防止QNN过拟合训练数据中的特定模式可能非常有效。
3.1.3 相位随机化层这是更贴近量子噪声特性的模拟。
- 操作:假设输入数据已编码为量子态的角度信息(例如,通过角度编码将特征
x_i映射为旋转角φ_i)。该层在训练时,对每个样本的编码角度附加一个随机相位偏移δ_i,δ_i可以从一个均匀分布U(-θ, θ)中采样。 - 参数:最大相位扰动幅度
θ。 - 物理对应:直接模拟退相位噪声(T2过程),这是当前量子比特最主要的噪声源之一。
- 实现考量:这要求数据编码方式是基于相位的。对于振幅编码等其他方式,需要设计相应的扰动形式。
3.1.4 组合噪声层最实用的策略。单一的噪声模型很难覆盖真实硬件的复杂性。因此,可以串联或并联多个上述基础噪声层,形成一个“噪声管道”。
- 例如:
输入 -> 加性高斯噪声 -> 随机丢弃 -> 相位随机化 -> 输出。 - 优势:可以模拟更复杂的噪声关联效应。通过调整不同层的激活概率和强度,可以拟合特定量子处理器的噪声谱。
3.2 可微量子架构搜索的具体化
将DARTS应用于量子电路,需要解决如何将离散的量子门选择连续化的问题。
3.2.1 搜索空间定义假设我们有一个相对通用的量子电路模板,由L层组成。每一层包含可参数化的单比特旋转操作和固定的双比特纠缠操作。我们将DARTS应用于双比特纠缠操作的选型。
候选操作集 O:对于电路中每一对需要纠缠的量子比特(例如,按线性链或环状连接),我们定义一组候选的双比特门操作,例如:
o1: CNOT门(控制-非门)o2: CZ门(控制-相位门)o3: iSWAP门(等概率交换门)o4: XX+YY耦合门(常用于超导量子比特)o5: None(无操作,即跳过纠缠)
架构参数 α:为每一对纠缠比特的每一个候选操作
o,分配一个可训练的架构权重α_{edge, o}。初始时,这些权重可以均匀分布或随机初始化。
3.2.2 连续松弛与混合操作DARTS的关键步骤是将离散选择(从O中选一个)松弛为所有候选操作的加权混合。
- 对于一对特定的纠缠比特,其实际执行的操作
\bar{o}被定义为所有候选操作的加权和:\bar{o} = Σ_{o∈O} (softmax(α)_{o}) * o - 这里,
softmax函数作用于该位置的所有候选操作的权重α上,将其转化为一个概率分布。在训练阶段,我们实际执行的是这个“混合门”,它是一个由连续参数定义的、可微的运算。 - 在最终推理架构确定阶段(搜索完成后),我们进行离散化:对于每个位置,选择
softmax(α)中概率最大的那个候选操作,即o* = argmax_o (softmax(α)_o),并丢弃其他操作。
3.2.3 联合优化流程整个CNL-QNN模型的训练损失函数包含两部分:
- 任务损失:如分类任务的交叉熵损失,基于QNN的最终输出计算。
- 架构正则化损失(可选):为了鼓励架构的稀疏性和简单性(这在NISQ时代很重要),可以加入对架构参数
α的L1或L2正则化。
优化过程使用梯度下降同时更新:
- 模型参数:量子电路中所有可旋转的角度
θ。 - 架构参数:所有边缘的候选操作权重
α。
重要提示:由于架构参数
α的数量可能很大,且其梯度是通过量子线路的期望值计算间接传递的,噪声较大。因此,通常建议使用性能更稳定的优化器(如Adam)来更新α,并使用比模型参数更小的学习率。
4. 完整实现流程与核心代码剖析
让我们以一个具体的例子——使用QNN进行简单的二分类任务,来串联CNL-QNN的整个实现流程。我们将使用PyTorch和常用的量子机器学习库PennyLane来演示核心步骤。
4.1 环境准备与数据预处理
首先,定义问题。我们使用一个经典的非线性数据集(如Moons数据集),并通过经典噪声层进行增强。
import torch import torch.nn as nn import torch.optim as optim import pennylane as qml from sklearn.datasets import make_moons from sklearn.preprocessing import StandardScaler import numpy as np # 1. 生成并预处理数据 X, y = make_moons(n_samples=1000, noise=0.1, random_state=42) scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 转换为PyTorch张量 X_tensor = torch.tensor(X_scaled, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.long) # 划分训练集和验证集 from torch.utils.data import DataLoader, TensorDataset dataset = TensorDataset(X_tensor, y_tensor) train_size = int(0.8 * len(dataset)) val_size = len(dataset) - train_size train_dataset, val_dataset = torch.utils.data.random_split(dataset, [train_size, val_size]) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=32)4.2 构建经典噪声层
我们实现一个组合噪声层,包含加性高斯噪声和随机丢弃。
class CompositeNoiseLayer(nn.Module): def __init__(self, gaussian_sigma=0.05, dropout_p=0.1): super().__init__() self.gaussian_sigma = gaussian_sigma self.dropout = nn.Dropout(p=dropout_p) def forward(self, x): if self.training: # 添加高斯噪声 if self.gaussian_sigma > 0: noise = torch.randn_like(x) * self.gaussian_sigma x = x + noise # 应用随机丢弃 x = self.dropout(x) return x4.3 定义可微搜索的量子节点
这是最核心的部分。我们定义一个量子设备,并创建一个支持架构搜索的量子层。
n_qubits = 2 # 使用2个量子比特来处理2维特征 dev = qml.device("default.qubit", wires=n_qubits) # 定义候选操作集 def cnot(wires): qml.CNOT(wires=wires) def cz(wires): qml.CZ(wires=wires) def iswap(wires): qml.ISWAP(wires=wires) def no_op(wires): # 无操作,相当于Identity pass candidate_ops = [cnot, cz, iswap, no_op] n_ops = len(candidate_ops) # 初始化架构参数:对于每一层(这里假设只有一层纠缠),为每个候选操作分配一个权重 # 我们假设在2个量子比特之间进行搜索 arch_alpha = nn.Parameter(torch.randn(1, n_ops)) # 形状: (1 层, n_ops 个候选) @qml.qnode(dev, interface="torch") def quantum_circuit(inputs, circuit_weights, arch_alpha): # 1. 数据编码:将经典数据编码到量子态(这里使用角度编码) for i in range(n_qubits): qml.RY(inputs[i], wires=i) # 2. 可微架构搜索的纠缠层 # 计算当前架构的混合权重 mix_weights = torch.softmax(arch_alpha, dim=-1) # 形状: (1, n_ops) # 执行混合操作(在训练时) # 注意:实际实现中,需要将混合操作分解为可微的形式。 # 一种简化方法是:分别用每个候选操作计算期望值,然后加权求和。 # 这里为了概念清晰,我们展示一个简化的、非严格可微的接口。 # 更严谨的实现需要使用qml.ctrl或自定义可微分操作。 # 以下是一个概念性循环: expvals = [] for op in candidate_ops: # 为每个候选操作临时创建一个量子节点并计算期望值 # 注意:这在实际DARTS中需要更精巧的设计,例如使用超网络。 # 此处仅为示意流程。 pass # 具体实现见下文讨论 # 3. 测量(这里测量第一个量子比特的Z期望值作为输出) return qml.expval(qml.PauliZ(0)) # 由于在PennyLane中直接实现可微的量子架构搜索需要较多定制, # 我们通常将架构搜索放在更高层次的包装中。关于量子DARTS实现的深入讨论: 上述代码中的quantum_circuit函数展示了概念,但真正的可微混合操作实现较为复杂。一个更实用的方法是采用“超网络”思想:
- 我们为每一对纠缠比特定义一组独立的参数化量子电路,每个电路对应一个候选操作。
- 在训练时,我们同时运行所有这些小电路(或高效地一次性计算),得到一组期望值
[expval_o1, expval_o2, ...]。 - 然后使用
softmax(arch_alpha)对这些期望值进行加权求和,得到最终的混合输出。 - 这个加权求和过程是完全可微的,梯度可以流向
arch_alpha。
这种方法避免了在量子级别直接实现“混合门”的困难,将混合转移到了经典的期望值后处理上。
4.4 构建完整的CNL-QNN模型
class CNL_QNN(nn.Module): def __init__(self, n_qubits, n_features, candidate_ops_list): super().__init__() self.n_qubits = n_qubits self.n_features = n_features self.candidate_ops = candidate_ops_list self.n_ops = len(candidate_ops_list) # 经典噪声层 self.noise_layer = CompositeNoiseLayer(gaussian_sigma=0.03, dropout_p=0.05) # 一个经典的全连接层,用于将特征映射到量子比特所需的旋转角度(可选,用于复杂数据) self.pre_net = nn.Linear(n_features, n_qubits) # 架构参数:假设我们只搜索一层中所有可能的双比特门连接 # 对于n_qubits,可能的纠缠对数为 n_qubits-1 (线性连接) 或更多 self.arch_alpha = nn.Parameter(torch.randn(1, self.n_ops)) # 简化示例 # 量子电路的可变参数(旋转角度) self.circuit_weights = nn.Parameter(torch.randn(1, requires_grad=True)) # 示例参数 def forward(self, x): # 1. 应用经典噪声层 (仅在训练时) x = self.noise_layer(x) # 2. 经典预处理 # 将数据维度映射到量子比特数(这里简单处理,假设n_features == n_qubits) # 如果不等,可以使用pre_net if self.n_features != self.n_qubits: angles = self.pre_net(x) else: angles = x # 直接使用特征作为旋转角 # 3. 量子电路计算(这里需要调用一个修改后的、支持架构搜索的量子函数) # 由于完整实现较冗长,此处示意流程 # output = differentiable_quantum_layer(angles, self.circuit_weights, self.arch_alpha) # 为演示,我们返回一个模拟值 # 实际中,output 是量子期望值 output = torch.tensor([0.0]) # 占位符 return output def get_final_architecture(self): """在搜索结束后,根据arch_alpha确定最终离散架构""" with torch.no_grad(): probs = torch.softmax(self.arch_alpha, dim=-1) chosen_op_idx = torch.argmax(probs, dim=-1).item() print(f"最终选择的纠缠操作是: {self.candidate_ops[chosen_op_idx].__name__}") return chosen_op_idx4.5 训练与搜索循环
训练循环需要同时更新模型参数和架构参数。
model = CNL_QNN(n_qubits=2, n_features=2, candidate_ops_list=[cnot, cz, iswap, no_op]) criterion = nn.CrossEntropyLoss() # 通常为架构参数设置更小的学习率 optimizer = optim.Adam([ {'params': model.circuit_weights, 'lr': 0.01}, {'params': model.arch_alpha, 'lr': 0.025} # 架构参数学习率稍高 ]) num_epochs = 50 for epoch in range(num_epochs): model.train() for batch_x, batch_y in train_loader: optimizer.zero_grad() outputs = model(batch_x) # 假设outputs是logits,这里简化处理损失计算 loss = criterion(outputs, batch_y) loss.backward() optimizer.step() # 验证步骤... # 定期打印架构权重 if epoch % 10 == 0: print(f"Epoch {epoch}, Arch Alpha: {torch.softmax(model.arch_alpha, dim=-1)}")5. 实验评估、常见问题与避坑指南
实现之后,如何评估CNL-QNN的有效性?在实际操作中又会遇到哪些坑?
5.1 评估策略:如何证明“鲁棒性”提升了?
不能只比较在干净测试集上的准确率。一个完整的评估应该包含以下几个维度:
噪声环境下的性能衰减对比:
- 基线模型:一个标准的、未使用CNL和DARTS的QNN。
- CNL-QNN模型:我们训练好的模型。
- 测试环境:在模拟器上,向测试数据注入不同强度的噪声(这些噪声类型可以与训练时CNL模拟的相同或不同)。
- 指标:绘制两个模型在“噪声强度 vs. 测试准确率”曲线。鲁棒性更强的模型,其曲线下降应更平缓。
在真实量子硬件上的表现:
- 将基线模型和CNL-QNN模型部署到真实的量子计算机(如通过IBM Quantum Experience或Rigetti Forest)。
- 比较它们在真实噪声下的任务性能。这是最直接的证明,但成本较高,且结果受硬件状态影响大。
架构分析:
- 观察DARTS搜索出的最终架构。它是否倾向于选择在物理上更稳健、门操作时间更短、或对特定噪声不敏感的门(例如,在某些平台上,CZ门可能比CNOT门更原生、误差更小)?
- 一个成功的搜索应该能发现符合物理直觉的鲁棒架构。
消融实验:
- 仅用CNL:只加经典噪声层,固定电路架构。
- 仅用DARTS:只在干净数据上做架构搜索。
- CNL-QNN:两者结合。
- 比较三者的性能,可以清晰展示每个组件的贡献以及协同效应。
5.2 常见问题与排查技巧实录
在实际操作中,我遇到了不少问题,这里总结几个典型的:
问题1:经典噪声层的强度(如sigma,p)如何设置?
- 现象:噪声太弱,模型鲁棒性提升不明显;噪声太强,模型连基础任务都学不会,训练不收敛。
- 排查与解决:
- 从小开始:初始值设置得非常小(
sigma=0.01,p=0.05)。 - 监控验证损失:在干净的验证集和带噪声的验证集上同时监控损失。目标是让两个损失值尽可能接近,且都处于可接受的低水平。如果干净集损失低而噪声集损失高,说明过拟合,需增强噪声。如果两者都高,说明噪声太强或模型容量不足。
- 动态调度:实现噪声强度的“课程学习”。在训练初期使用弱噪声,让模型先学会基础模式;随着训练进行,逐步线性或阶梯式增加噪声强度,迫使模型学习更鲁棒的特征。
- 从小开始:初始值设置得非常小(
问题2:DARTS搜索不稳定,架构参数arch_alpha的优化震荡大。
- 现象:
arch_alpha的softmax概率分布跳动剧烈,无法收敛到一个清晰的选择。 - 排查与解决:
- 学习率调整:这是最常见的原因。为
arch_alpha设置比模型权重更低的学习率(通常是1/2到1/10)。架构搜索需要更“谨慎”。 - 优化器选择:使用Adam等自适应优化器通常比SGD更稳定,因为它们能为每个参数调整学习率。
- 梯度裁剪:量子计算的期望值梯度可能存在异常值,对
arch_alpha的梯度进行裁剪(torch.nn.utils.clip_grad_norm_)可以防止大幅更新。 - 增加正则化:对
arch_alpha施加L1正则化,可以鼓励稀疏性,帮助其更快地聚焦到少数几个操作上。
- 学习率调整:这是最常见的原因。为
问题3:搜索出的架构总是倾向于“无操作”(None/Skip-Connect)。
- 现象:最终
no_op的权重远高于其他门操作。 - 排查与解决:
- 原因分析:这通常意味着,在当前任务和噪声设置下,添加额外的纠缠门带来的收益(表达能力和信息传递)小于其成本(引入的噪声和训练难度)。或者,单比特旋转已经足够完成任务。
- 验证:这不一定是个“问题”。如果这个简单架构在验证集上表现良好,那它可能就是最优解。在NISQ时代,“浅而宽”或“减少纠缠”的电路往往是更实用的。
- 调整搜索空间:如果确信需要纠缠,可以尝试从候选集中移除
no_op,强制搜索选择一种门。或者,为不同的操作引入先验偏置,例如在初始化arch_alpha时,给CNOT或CZ一个稍大的初始值。
问题4:模型在模拟器上表现好,但迁移到真机性能仍不佳。
- 现象:模拟器测试通过,真机部署失败。
- 排查与解决:
- 噪声失配:经典噪声层模拟的噪声与真实硬件噪声分布不一致。解决方法是收集硬件噪声表征数据(如门保真度、T1/T2时间、测量误报矩阵),并以此为基础设计或校准你的经典噪声层参数。例如,根据真实测量误报矩阵来设计一个对应的“经典混淆层”。
- 电路编译差异:模拟器中的门操作是理想的,而真机会将你的逻辑门编译成一组特定的原生门序列。这个编译过程可能引入额外开销和误差。在搜索时,可以将候选操作集限制为目标硬件支持的原生门集合,这样搜索出的架构部署时编译更高效,误差更小。
- 有限的shots:模拟器通常计算精确期望值,而真机基于有限测量次数(shots)。在训练和搜索时,就应该在量子节点中设置有限的
shots来模拟这种统计噪声,让模型提前适应。
问题5:训练时间过长。
- 现象:由于要评估多个候选操作,量子电路评估次数成倍增加。
- 优化技巧:
- 权重共享:DARTS的一个标准技巧。所有候选操作共享大部分参数(例如,共享相同的单比特旋转层),只有核心的门操作不同。这大大减少了参数量和计算量。
- 一阶近似:在DARTS原始论文中,提出了省略二阶导数的简化版优化,可以显著加速,且性能损失通常很小。
- 分阶段搜索:先在一个小的代理任务或子数据集上进行架构搜索,找到有潜力的架构范围后,再固定架构,在完整数据集上训练最终模型参数。
CNL-QNN这个思路,把噪声从“需要克服的障碍”变成了“可以利用的指南针”。它不承诺创造出在噪声中完美运行的模型,而是提供了一套系统的方法,让我们能在给定的、不完美的硬件条件下,尽可能榨取出QML的最佳性能。这套方法的价值会随着量子硬件噪声水平的降低而演变,但在可预见的NISQ时代,它无疑是一种极具现实意义的工程实践。