ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

量子LSTM原理:用相位编码替代门控计算的建模范式

量子LSTM原理:用相位编码替代门控计算的建模范式

简介:这是一份面向量子机器学习初学者与研究者的Jupyter Notebook实践资源,聚焦量子长短期记忆网络(QLSTM)的原理验证与代码实现。资源通过可运行的完整示例,帮助读者理解量子电路如何嵌入经典RNN结构,并对比经典LSTM与量子变分LSTM在词性标注(POS tagging)任务上的训练表现。压缩包共10个文件,涵盖3个核心Python脚本(含量子电路构建、数据下载与主训练逻辑)、3张关键结果图(如经典vs量子训练曲线对比)、2个依赖说明文本及1个交互式Notebook(POS_tagging.ipynb),整体仅84KB,轻量易部署。已有424人学习下载,读者可直接复现论文级实验流程,获取从环境配置(Qiskit+PyTorch)、量子参数化电路设计、到多轮训练可视化的一站式参考,特别适合希望快速上手量子神经网络实操的算法工程师与高校研究生。

1. qlstm:量子LSTM不是“把LSTM塞进量子电路”,而是用量子态编码时序依赖的相位结构

你打开一份标着“qlstm: 量子LSTM的示例”的 Jupyter Notebook,发现里面没有量子硬件调用、没有Qiskit或PennyLane的backend.run(),甚至连量子比特数都固定为4——这和你预想中“运行在超导量子处理器上的LSTM替代方案”完全对不上号。更反直觉的是:它训练速度比经典LSTM快,但参数量却少一个数量级;它在短序列任务上准确率略低,一到长程依赖(比如>50步的符号匹配)就突然反超。这不是工程优化,是机制跃迁。这份资源真正交付的,是一套用量子态的叠加与干涉特性,重定义“记忆门控”物理含义的建模范式:它不模拟LSTM的门控计算流,而是把时间步之间的状态转移,编译成量子线路中受控旋转门的相位累积路径。理解它,不是为了立刻跑通量子云平台,而是看清——当循环神经网络的“记忆”从浮点向量退相干为复振幅分布,梯度传播、长期依赖、甚至过拟合的本质,都会在希尔伯特空间里显现出截然不同的几何约束。这才是值得你花两小时逐行调试这份Notebook的根本原因。


2. 量子LSTM的建模逻辑:为什么必须放弃“门控=矩阵乘+sigmoid”的直觉

2.1 经典LSTM的门控本质是局部非线性投影,而量子版本需要全局相位编码

经典LSTM中,遗忘门 $f_t = \sigma(W_f [h_{t-1}, x_t] + b_f)$ 的作用,是在每个时间步对前一隐藏态 $h_{t-1}$ 和当前输入 $x_t$ 做一次仿射变换,再经Sigmoid压缩到(0,1)区间,实现“选择性擦除”。这个操作本质是在欧氏空间中做局部坐标变换:权重矩阵 $W_f$ 定义了一个超平面,Sigmoid将其映射为软阈值。但量子系统无法直接实现Sigmoid——量子门必须是幺正的(unitary),而Sigmoid是非线性的、不可逆的、非幺正的。因此,qlstm的“遗忘”不再是一个标量擦除系数,而是将遗忘强度编码为受控旋转门 $R_y(\theta_f)$ 的旋转角 $\theta_f$,其中 $\theta_f$ 由经典特征 $[h_{t-1}, x_t]$ 线性映射得到:

# qlstm notebook 中实际出现的门控参数生成逻辑(简化) def compute_forget_angle(h_prev, x_curr, w_f, b_f): # 注意:这里没有 sigmoid!只有线性映射 + clamp 到 [-π, π] raw_angle = np.dot(np.concatenate([h_prev, x_curr]), w_f) + b_f return np.clip(raw_angle, -np.pi, np.pi) # 直接作为 Ry 门的参数

这个clip操作不是近似,而是物理约束:$R_y(\theta)$ 的 $\theta$ 超出 $[-\pi,\pi]$ 会因周期性导致相位歧义。所以,“遗忘强度”在这里被降维为一个可测量的相位偏移量,其效果不是“删掉多少信息”,而是“让对应基态分量在后续干涉中产生多大程度的相消”。

2.2 隐藏态的量子表示:从向量 $h_t$ 到振幅向量 $|\psi_t\rangle$ 的升维映射

经典LSTM的隐藏态 $h_t \in \mathbb{R}^d$ 是一个d维实向量。在qlstm中,它被映射为一个 $2^n$ 维复向量 $|\psi_t\rangle$(n为量子比特数,Notebook中n=4 → 16维)。但这个映射不是简单填充或reshape。关键设计在于:

  • 前 $d$ 个分量承载 $h_t$ 的实部(经归一化);
  • 后 $d$ 个分量承载 $h_t$ 的虚部(同样归一化);
  • 剩余维度补零,并整体施加L2归一化,确保 $\langle \psi_t | \psi_t \rangle = 1$。

这种设计的深层动机,在于保留经典隐藏态的内积结构:若两个经典隐藏态 $h_i, h_j$ 夹角小(相似),则其对应量子态 $|\psi_i\rangle, |\psi_j\rangle$ 的保真度 $|\langle \psi_i | \psi_j \rangle|^2$ 也高。这使得后续的量子门操作能自然放大相似态间的干涉效应——而这正是长程依赖建模的核心:让第1步和第50步的状态在最终测量前发生建设性干涉。

提示:Notebook中state_to_quantum()函数的归一化分母是np.sqrt(np.sum(h**2) + 1e-8),而非np.linalg.norm(h)。那个+1e-8不是防零除,而是防止当 $h_t$ 接近零向量时,量子态坍缩为全零态(物理上不可实现),强制保留微弱但非零的基态权重。

2.3 时间步演化的幺正构造:如何用受控门实现“带记忆的循环”

经典LSTM的循环是 $h_t = \text{LSTMCell}(h_{t-1}, x_t)$,一个确定性函数。量子版本必须用幺正算符 $U_t$ 实现 $|\psi_t\rangle = U_t |\psi_{t-1}\rangle \otimes |x_t\rangle$。Notebook采用分层受控结构:

  1. 输入编码层:用单比特旋转门 $R_y(\alpha x_t^{(i)})$ 将第i维输入 $x_t^{(i)}$ 编码为第i个量子比特的倾角;
  2. 记忆交互层:以隐藏态量子比特为控制,对输入编码比特施加受控-Z门(CZ),制造纠缠;
  3. 状态更新层:用受控-Ry门,以输入比特为控制,旋转隐藏态比特,旋转角 $\theta$ 由前述compute_forget_angle()输出。

这个三段式结构的关键在于:CZ门不改变任何比特的边缘概率,只引入相位关联。这意味着,即使某输入维度 $x_t^{(i)}$ 为0,它仍通过CZ门与隐藏态比特形成相位纠缠——这正是“记忆未被清空”的量子体现。而经典LSTM中,若 $x_t^{(i)}=0$,对应权重项直接消失,信息流被物理切断。


3. Jupyter Notebook中的核心实现:从电路构建到梯度回传的量子-经典混合链路

3.1 量子线路的动态构建:为什么每次前向传播都需重编译线路

Notebook中build_circuit(t, h_prev, x_curr)函数在每个时间步t都重新生成量子线路对象。这不是性能缺陷,而是量子参数化线路(PQC)的固有要求:因为门参数 $\theta_f, \theta_i, \theta_o$ 都依赖于经典隐藏态 $h_{t-1}$ 和输入 $x_t$,而 $h_{t-1}$ 本身是前一步量子测量的期望值(即经典数据)。因此,整个线路是“经典数据驱动的量子电路”,无法预先静态定义。代码中关键片段如下:

def build_circuit(t, h_prev, x_curr): qc = QuantumCircuit(4) # 固定4量子比特 # 步骤1:编码输入 x_curr 到前2个比特(假设x_curr是2维) qc.ry(compute_input_angle(x_curr[0]), 0) qc.ry(compute_input_angle(x_curr[1]), 1) # 步骤2:用h_prev的量子态(存储在比特2,3)控制输入比特 qc.cz(2, 0) # 控制比特2 → 目标比特0 qc.cz(3, 1) # 控制比特3 → 目标比特1 # 步骤3:用输入控制隐藏态更新(关键!) forget_angle = compute_forget_angle(h_prev, x_curr, w_f, b_f) qc.cry(forget_angle, 0, 2) # 输入比特0控制隐藏比特2 qc.cry(forget_angle, 1, 3) # 输入比特1控制隐藏比特3 return qc

注意cry()是受控-Y旋转门,其控制逻辑是:仅当控制比特为 $|1\rangle$ 时,才对目标比特执行 $R_y(\theta)$。这直接对应经典LSTM中“门控信号为1才激活更新”的语义,但实现方式是量子力学的条件演化。

3.2 混合梯度计算:量子部分用参数移位法,经典部分用标准反向传播

由于量子线路不可微(门参数离散、测量随机),Notebook采用参数移位法则(Parameter Shift Rule)计算量子门梯度。对任意含参数 $\theta$ 的门 $R_y(\theta)$,其关于损失函数 $L$ 的梯度为:

$$ \frac{\partial L}{\partial \theta} = \frac{1}{2} \left[ L(\theta + \frac{\pi}{2}) - L(\theta - \frac{\pi}{2}) \right] $$

Notebook中quantum_gradient()函数正是这样实现的:对每个可训练参数 $\theta$,构造两次电路($\theta \pm \pi/2$),运行并获取期望值,差分即得梯度。而经典权重 $w_f, b_f$ 的梯度,则通过链式法则回传:

  • 量子梯度 $\partial L / \partial \theta$ →
  • 传给 $\partial \theta / \partial w_f$(线性映射的雅可比,即 $[h_{t-1}, x_t]$)→
  • 得到 $\partial L / \partial w_f$。

这种混合梯度流在train_step()函数中清晰可见,它证明了:量子部分只负责提供“相位敏感的梯度信号”,经典部分负责将该信号解耦为权重更新。二者缺一不可。

3.3 测量与经典读出:为什么输出层用Pauli-Z期望值而非直接采样

Notebook的最终输出不是对量子态做多次采样取众数,而是计算每个输出比特的 $Z$ 算符期望值 $\langle Z_i \rangle$,再拼接为经典向量。原因有三:

  1. 方差压制:采样1024次的统计误差远大于直接计算 $\langle Z_i \rangle$(后者可通过少量电路运行+后处理获得);
  2. 梯度兼容:$\langle Z_i \rangle$ 是量子态的线性泛函,其对参数的导数可解析求出,适配参数移位法;
  3. 物理意义明确:$\langle Z_i \rangle = P(|0\rangle_i) - P(|1\rangle_i)$,直接表征该比特的“确定性倾向”,比二进制采样更平滑,利于收敛。

这解释了为何Notebook中get_output()返回的是[-0.82, 0.37]这类浮点数,而非[0,1]整数——它本质上是量子态在Z基下的投影坐标,是连续可微的经典接口。


4. 常见问题与避坑指南:那些让初学者调试到凌晨三点的量子细节

4.1 现象:训练loss震荡剧烈,且在某个epoch后突然发散

原因:量子线路中Ry门的参数 $\theta$ 未做裁剪,导致 $\theta$ 超出 $[-\pi,\pi]$ 范围。由于 $R_y(\theta)$ 具有 $2\pi$ 周期性,$\theta=3\pi$ 等价于 $\theta=\pi$,但梯度计算时Parameter Shift Rule在 $\theta \pm \pi/2$ 处的函数值会因周期跳变而产生巨大数值噪声。
解决:在compute_*_angle()所有函数末尾强制添加np.clip(angle, -np.pi, np.pi)。Notebook原始代码漏掉了遗忘门角度的裁剪,这是最常被忽略的坑。

4.2 现象:模型在训练集上准确率99%,测试集上跌至52%(接近随机)

原因:量子态归一化时使用了np.linalg.norm(h),但当 $h_t$ 接近零向量时,归一化分母趋近于0,导致量子态 $|\psi_t\rangle$ 的数值不稳定(浮点溢出或NaN)。后续所有量子门操作失效。
解决:严格采用Notebook修正版中的np.sqrt(np.sum(h**2) + 1e-8),这个1e-8是经验性正则项,保证分母永不为零。不要试图用更大的值(如1e-4),它会人为扭曲小幅度隐藏态的量子表示。

4.3 现象:修改输入维度后报错IndexError: quantum circuit has only 4 qubits

原因:Notebook硬编码了量子比特数为4,且输入编码只分配前2个比特,隐藏态占后2个。若输入维度变为3,qc.ry(..., 2)会越界。
解决:动态分配比特资源。例如,按公式n_qubits = ceil(log2(2 * max(d_input, d_hidden)))重算比特数,并重构build_circuit()中的比特索引映射。切勿暴力增加比特数——每增1比特,希尔伯特空间维数翻倍,模拟开销指数增长。

4.4 现象:使用不同随机种子训练,结果准确率方差极大(±15%)

原因:量子线路初始化权重(如w_f,b_f)的分布未适配量子参数范围。经典LSTM常用He normal初始化,但量子门参数 $\theta$ 有效范围是 $[-\pi,\pi]$,若初始 $\theta$ 集中在 $[0,0.1]$,则大部分门几乎不生效,模型陷入局部极小。
解决:对所有门控角度的线性映射权重,改用均匀分布np.random.uniform(-0.5, 0.5, size=...)初始化,再乘以一个缩放因子(如scale=2.0),确保初始 $\theta$ 覆盖 $[-\pi,\pi]$ 的核心区域。

4.5 现象:开启shots=1024后训练速度暴跌,但shots=1时loss不下降

原因:shots=1时每次测量只采1次,$\langle Z_i \rangle$ 估计值方差极大(伯努利分布),梯度噪声淹没信号;shots=1024时虽方差小,但需重复运行电路1024次,耗时剧增。
解决:采用梯度估计的shot-aware策略:前10个epoch用shots=16快速探索,中间50个epoch用shots=128平衡精度与速度,最后20个epoch用shots=1024精修。Notebook中run_quantum_circuit()函数应支持动态shots参数。


5. 设计取舍的底层权衡:为什么这份qlstm不追求“量子优越性”,而专注教学级可解释性

5.1 量子比特数的刻意限制:4比特不是技术瓶颈,而是认知边界

Notebook固守4量子比特,表面看是为本地模拟器(如AerSimulator)考虑,实则是对“可解释性”的主动让渡。当n=4时,希尔伯特空间为16维,其密度矩阵可完整打印并人工检查;当n=6(64维)时,仅存储密度矩阵就需要4KB内存,而人工追踪单个基态 $|101100\rangle$ 的振幅演化已无可能。作者选择4比特,是为了让学习者能用qc.draw('text')看清每一层门的作用,用statevector_simulator提取完整 $|\psi\rangle$ 并验证:

  • 输入编码后,$|00\rangle$ 分量是否确实被旋转;
  • CZ门后,$|1010\rangle$ 与 $|1000\rangle$ 的相位差是否为 $\pi$;
  • 最终测量前,$|0000\rangle$ 与 $|1111\rangle$ 的振幅比是否与经典隐藏态模长正相关。

这种“肉眼可验”的设计,牺牲了表达能力上限,却换来了对量子-经典接口的肌肉记忆。我曾见过某开发者强行将比特数扩到8,结果花了三天调试才发现:他误以为qc.h(0)会对所有含 $|1\rangle_0$ 的基态统一加相位,而实际上Hadamard门是张量积作用,必须结合具体基态计算。这种错误,在4比特系统里,一行print就能暴露。

5.2 门类型的高度精简:为何只用Ry、CZ、CRy,而不用更“强大”的T门或Toffoli

Notebook中所有量子门均可分解为Ry和CZ的组合(这是通用量子计算的已知结论),但作者坚持只用这三种,理由直指教学本质:

  • Ry门:唯一能直接编码经典实数的单比特门($R_y(\theta)|0\rangle = \cos\frac{\theta}{2}|0\rangle + \sin\frac{\theta}{2}|1\rangle$),角度 $\theta$ 与经典参数一一对应,无歧义;
  • CZ门:最简单的双比特纠缠门,其矩阵形式为 $\text{diag}(1,1,1,-1)$,作用直观——仅当两比特均为 $|1\rangle$ 时引入 $\pi$ 相位,完美对应“控制条件成立”的逻辑;
  • CRy门:Ry的受控版本,直接实现“经典门控信号决定量子更新强度”的语义映射。

若引入T门($\pi/4$ 相位),则需额外处理 $\pi/4$ 的无理数精度问题;若用Toffoli门,则需三级控制,其经典等效逻辑(AND of two bits)与LSTM门控的“加权和+Sigmoid”无直接对应,徒增理解负担。这种克制,不是技术保守,而是把“量子如何服务经典建模”这一命题,锚定在最无争议的数学接口上。

5.3 梯度计算的务实选择:参数移位法 vs. 有限差分 vs. 量子自动微分

Notebook选用参数移位法,而非更通用的有限差分(finite difference),原因在于精度与效率的刚性平衡。有限差分 $\frac{L(\theta+\epsilon)-L(\theta)}{\epsilon}$ 要求 $\epsilon$ 极小(如1e-6),但在量子测量中,$L$ 本身是统计估计值,其方差与 $1/\text{shots}$ 成正比。当 $\epsilon=1e-6$ 时,$L(\theta+\epsilon)$ 与 $L(\theta)$ 的差异可能被测量噪声完全淹没。而参数移位法的 $\pm \pi/2$ 是固定大步长,其差分信号强、信噪比高,且对任意Ry门,该公式严格成立(非近似)。至于量子自动微分(如TensorFlow Quantum),它需要将整个量子线路嵌入计算图,而Notebook的目标是让学习者看到“电路如何一步步构建”,而非黑盒调用。

从那以后我每次带新人看量子机器学习项目,都强制他们先关掉所有高级库,用NumPy手写一个2比特Ry-CZ-Ry线路,手动计算 $\langle Z_0 \rangle$ 对 $\theta_1$ 的解析梯度,再和参数移位法结果比对。只有当这两个数字在小数点后三位一致时,才允许他们打开Qiskit文档。这种“返祖式”训练,看似笨拙,却能瞬间过滤掉所有对量子门物理意义存疑的人。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进