4. 混合网络的前向传播实现
混合量子经典网络的前向传播,本质上是把一次经典张量计算与一次量子线路执行拼接成一条可微(或可近似求导)的链路。与纯经典网络不同,这条链路里存在一个“经典数值 → 量子门角度 → 量子测量期望值 → 经典数值”的转换环节,它决定了数据如何进入量子态、参数如何影响输出,也决定了反向传播时梯度从哪里来。本节围绕这条链路,从经典预处理一路走到经典后处理,给出可直接落地的实现思路与示例参数。
一、链路全景与张量形状约定
先明确本节采用的约定,后续正文与图示保持一致:输入样本为长度为 d 的实向量,经典预处理把它压缩为 n 个特征(n 等于量子比特数),每个特征经缩放后作为对应量子比特的旋转角;量子线路采用“数据编码层 + L 层可训练强纠缠层”的结构;测量取每个量子比特的 Pauli-Z 期望值,得到长度 n 的实向量;经典后处理把它映射为任务输出。以二分类为例,输出为单个标量 logit,经 sigmoid 得到概率。
二、经典预处理:把原始特征变成可编码的角度
量子线路能接受的输入是门参数,因此预处理的核心任务是把任意实数特征映射到有界角度区间。常见做法是:先对原始特征做标准化(零均值、单位方差),再用一个线性层把维度从 d 降到 n,最后用 tanh 压缩到 (-1, 1) 并乘以 π/2,得到每个比特的编码角 θ_i ∈ (-π/2, π/2)。选择 π/2 而非 π 是为了让编码角避开 RY 在 π 附近对输入不敏感的区域,同时保留足够的表达范围。
示例参数:设 d=8、n=4,线性层权重 W_e 形状为 4×8,偏置 b_e 为长度 4 的向量。若某样本标准化后为 [0.5, -1.2, 0.3, 0.8, -0.4, 1.1, -0.9, 0.2],经线性层与 tanh 后得到 [0.42, -0.31, 0.67, 0.05],乘以 π/2 后编码角约为 [0.66, -0.49, 1.05, 0.08] 弧度。这一步的权重 W_e 既可以固定(如用 PCA 初始化),也可以作为可训练参数参与优化,前者更稳定、后者更灵活,实践中常先固定、待量子层收敛后再解冻微调。
三、量子态制备与参数化演化
态制备从 |0⟩^⊗n 出发,对第 i 个比特施加 RY(θ_i),得到各比特的独立叠加态。若数据本身存在强相关结构,可在编码后追加一层固定的 CNOT 链,把特征间的相关性“写入”纠缠结构,但要注意这会增加线路深度,在含噪声设备上需权衡。
参数化层是网络真正“学习”的部分。以 L=2 层、n=4 比特为例,每层包含:每个比特一个 RY(φ) 和一个 RZ(φ),随后是环形 CNOT(0→1、1→2、2→3、3→0)。这样每层可训练参数为 2n=8 个,两层共 16 个,加上编码层若可训练则再加 4 个。环形 CNOT 保证任意两个比特间存在纠缠路径,同时深度仅为 n,适合当前中等规模设备。实现时建议用参数化电路框架(如 Qiskit 的 TwoLocal 或 PennyLane 的 StronglyEntanglingLayers)声明结构,避免手工拼接门序列出错。
# 伪代码:一次前向的量子部分(PennyLane 风格)
dev = qml.device("default.qubit", wires=4, shots=1024)
@qml.qnode(dev)
def quantum_forward(theta, phi):
# 态制备:逐比特 RY 编码
for i in range(4):
qml.RY(theta[i], wires=i)
# 参数化演化:2 层强纠缠块
for l in range(2):
for i in range(4):
qml.RY(phi[l, i, 0], wires=i)
qml.RZ(phi[l, i, 1], wires=i)
for i in range(4):
qml.CNOT(wires=[i, (i + 1) % 4])
# 测量:每比特 Pauli-Z 期望
return [qml.expval(qml.PauliZ(i)) for i in range(4)]
四、测量输出与经典后处理
测量环节有两个关键选择:测什么、怎么估。测 Pauli-Z 期望值得到 [-1, 1] 区间的连续量,适合作为可微链路的中间表示;若用 shots 采样估计,则期望值带有统计噪声,噪声随 1/√shots 衰减。示例中 shots=1024,单比特期望的标准误约为 1/√1024 ≈ 0.03,对多数分类任务可接受;若后处理层对噪声敏感,可提高到 4096 或改用解析期望(模拟器场景)。
后处理把 n 维期望向量映射为任务输出。二分类时用 logit = w·⟨Z⟩ + b,再经 sigmoid 得概率;多分类时用 softmax(W·⟨Z⟩ + b)。这里的 W、b 是纯经典可训练参数,与量子参数 φ 一起构成完整参数集。一个值得注意的细节是:⟨Z⟩ 的取值范围天然有界,后处理层的初始化尺度应相应缩小(如 W 用 1/√n 缩放的高斯初始化),否则初始 logit 过大、sigmoid 饱和,梯度会很小。
五、结果观察与链路自检
前向链路写完后,不要急着训练,先做三项自检。第一,形状自检:输入 (batch, d) → 编码角 (batch, n) → 期望值 (batch, n) → 输出 (batch, 1),任何一步维度对不上都说明拼接有误。第二,数值范围自检:编码角应落在 (-π/2, π/2),期望值应落在 [-1, 1],概率应落在 (0, 1),越界通常意味着缩放系数或激活函数用错。第三,敏感性自检:固定输入,把某个量子参数 φ 增加 0.1,观察输出是否发生可测量的变化;若几乎不变,可能是该参数所在的门被后续操作抵消,或测量基选择不当导致信息丢失。
shots=None),排除统计噪声干扰后再回到采样模式,这样能更快定位是结构问题还是噪声问题。完成以上步骤后,一条完整的前向链路就建立起来了:经典预处理负责“把数据变成角度”,态制备与参数化演化负责“把角度变成量子态并施加可训练变换”,测量负责“把量子态变成经典可读的期望值”,后处理负责“把期望值变成任务输出”。这条链路的每一段都有明确的输入输出契约,后续实现反向传播时,只需在量子段使用参数移位规则、在经典段使用标准链式法则,即可把梯度从输出端一路回传到编码层与后处理层。