量子神经网络


1. 经典神经网络核心概念复习

在我们构建量子版本之前,先快速回顾一下经典神经网络的运作方式。

1.1 组件:参数、算符与损失函数

一个最简单的算子可以被看作是一个数学函数:y = f(w * x + b)

  • 输入 (x): 喂给网络的数据。
  • 参数 (w, b): 网络的“知识”,即权重 (weight) w 和偏置 (bias) b。它们是可学习的
  • 线性算符: w * x + b,对输入进行线性变换。
  • 非线性算符 (激活函数 f): 如 Sigmoid, ReLU。这是网络能学习复杂模式的关键。没有非线性,多层网络也只相当于一个单层网络。
  • 输出 (y): 网络的预测值。
  • 损失函数 (Loss Function): 如均方误差 L = (y_true - y_pred)²,它衡量了预测的好坏。我们的目标就是最小化损失函数

1.2 前馈与反向传播

  • 前馈网络 (Feedforward): 数据从输入层开始,逐层向前传递,经过一系列线性和非线性变换,最终在输出层得到结果。这个过程就是简单的函数调用。
  • 反向传播 (Backpropagation): 为了最小化损失,我们需要知道如何调整参数 wb。反向传播本质上是利用链式法则高效计算损失函数 L 对每一个参数的梯度 (gradient),即 ∂L/∂w∂L/∂b。然后,我们使用梯度下降等优化算法,沿着梯度的反方向微调参数,从而降低损失。

2. 量子神经网络 (Quantum Neural Network, QNN)

现在,让我们用量子力学的语言来“翻译”经典神经网络的每一个组件。

核心类比

  • 经典比特 → 量子比特 (Qubit)
  • 经典逻辑门 → 量子逻辑门 (Quantum Gate)
  • 可学习的参数 (w, b)可学习的旋转门角度 θ
  • 线性+非线性函数 f(wx+b)含参数的量子电路 U(θ)
  • 网络的输出 y_pred可观测量 M 的期望值 <M>

2.1 含参数量子逻辑门

我们之前学过的 X, Z, H 门是固定的。现在,我们引入可以旋转任意角度的门,这些角度就是我们要学习的参数 θ

  • 旋转门 (Rotation Gates):

    • $ R_x(\theta) = e^{-i\theta X/2} = \begin{pmatrix} \cos(\theta/2) & -i\sin(\theta/2) \\ -i\sin(\theta/2) & \cos(\theta/2) \end{pmatrix} $ (绕X轴旋转θ角)
    • $ R_y(\theta) = e^{-i\theta Y/2} = \begin{pmatrix} \cos(\theta/2) & -\sin(\theta/2) \\ \sin(\theta/2) & \cos(\theta/2) \end{pmatrix} $ (绕Y轴旋转θ角)
    • $ R_z(\theta) = e^{-i\theta Z/2} = \begin{pmatrix} e^{-i\theta/2} & 0 \\ 0 & e^{i\theta/2} \end{pmatrix} $ (绕Z轴旋转θ角)

这些门的旋转角度 θ 就是我们的“旋钮”,是QNN中可以被优化的参数。

2.2 构建含参数量子电路 (PQC)

一个量子神经网络,在结构上就是一个由三部分组成的量子电路:

  1. 数据编码 (Data Encoding): 将经典数据 x 编码到量子态中。例如,可以用一个旋转门将数据作为角度编码进去:$|ψ_{in}\rangle = R_y(x)|0\rangle$。
  2. 模型电路 (Model Circuit / Ansatz): 这就是网络的主体,由一系列固定的门 (如CNOT) 和含参数的旋转门 R(θ) 组成。这部分电路的结构,被称为 Ansatz
  3. 测量 (Measurement): 在电路的最后,我们选择一个或多个可观测量 (如 $Z_0$, $Z_1$, $Z_0Z_1$),并计算其期望值。这个期望值就是QNN的输出。

一个典型的“硬件高效型”(Hardware-efficient) Ansatz 结构如下:

它由重复的“旋转层”和“纠缠层”构成。

  • 旋转层: 对每个量子比特应用可学习的旋转门 $R_x(\theta_1), R_y(\theta_2), R_z(\theta_3)$。
  • 纠缠层: 用一系列 CNOT 门将量子比特纠缠起来。

2.3 量子神经网络的前馈过程

  1. 准备初态:通常是 $|00\dots0\rangle$。
  2. 编码输入 x:通过 R(x) 等门将数据加载到量子态中。
  3. 执行模型电路 U(θ):将当前的一组参数 θ 应用到电路的旋转门上,让量子态进行演化。
  4. 计算期望值:测量某个可观测量 M,得到输出 $y_{pred} = \langle\psi_{out}| M |\psi_{out}\rangle = \langle0| U^\dagger(x, \theta) M U(x, \theta) |0\rangle$。
  5. 计算损失:使用经典计算机,根据预测值 $y_{pred}$ 和真实值 $y_{true}$ 计算损失 L

2.4 量子神经网络的梯度计算:参数平移法则

好了,最神奇的部分来了。我们如何计算梯度 ∂L/∂θ 来更新参数呢?难道要像经典反向传播那样复杂吗?

答案是:不需要! 量子力学为我们提供了一个优雅得多的方法——参数平移法则 (Parameter-Shift Rule)

对于一个由旋转门 $U = e^{-i\theta G/2}$(其中G是泡利矩阵X,Y或Z)产生的参数 θ,其对于最终期望值 $\langle M \rangle$ 的梯度可以被精确地计算:

$$ \frac{\partial \langle M \rangle}{\partial \theta_k} = \frac{1}{2} \left( \langle M \rangle_{\theta_k + \pi/2} - \langle M \rangle_{\theta_k - \pi/2} \right) $$

这是什么意思?

  • 要计算第 k 个参数 $\theta_k$ 的梯度...
  • 你只需要运行完全相同的量子电路两次!

    1. 第一次,将参数 $\theta_k$ 增加一个 $\pi/2$ (90度),得到期望值 $\langle M \rangle_{\theta_k + \pi/2}$。
    2. 第二次,将参数 $\theta_k$ 减少一个 $\pi/2$ (90度),得到期望值 $\langle M \rangle_{\theta_k - \pi/2}$。
  • 将两个结果相减再除以2,就得到了解析梯度 (analytical gradient),而不是数值近似!

这个强大的法则是变分量子算法(包括QNN)能够有效训练的核心。它意味着我们可以利用量子计算机本身来计算梯度。


3. PennyLane 实战:搭建你的第一个QNN

PennyLane 是一个专为量子机器学习设计的Python库。它将量子电路的搭建、自动微分(使用参数平移法则)和经典机器学习框架(如PyTorch, TensorFlow)无缝集成。

任务: 让我们构建一个简单的QNN,学习一个一维函数,比如 y = sin(x)

步骤:

  1. 定义量子设备: 我们可以使用模拟器。
  2. 构建QNN电路 (QNode):

    • 编码层: 将输入 xRY(x) 门编码。
    • 模型层: 添加几个带参数 params 的旋转门和CNOT门。
    • 测量层: 返回第一个量子比特的 PauliZ 期望值。
  3. 定义损失函数: 使用均方误差。
  4. 选择优化器: 使用 AdamOptimizer
  5. 训练循环: 多次迭代,计算梯度并更新参数。
import pennylane as qml
from pennylane import numpy as np # 使用pennylane自带的numpy,以支持自动微分

# 1. 定义量子设备
# 我们使用2个量子比特的默认模拟器
dev = qml.device("default.qubit", wires=2)

# 2. 构建QNN电路 (QNode)
# @qml.qnode(...) 是一个装饰器,它将一个python函数转换为一个可以在设备上运行的量子电路
@qml.qnode(dev)
def quantum_neural_net(params, x):
    """一个简单的量子神经网络"""
    
    # --- 编码层 ---
    # 将经典数据x编码到第一个量子比特上
    qml.RY(x, wires=0)
    
    # --- 模型层 (Ansatz) ---
    # 这就是我们的“神经网络”,由可学习的参数params控制
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=0)
    qml.CNOT(wires=[0, 1])
    qml.RX(params[2], wires=1)
    qml.RY(params[3], wires=1)
    
    # --- 测量层 ---
    # 返回第一个量子比特的Z算符期望值作为输出
    return qml.expval(qml.PauliZ(0))

# 3. 定义损失函数
def square_loss(labels, predictions):
    """计算均方误差"""
    return np.mean((labels - predictions) ** 2)

# --- 准备数据和参数 ---
# 生成一些sin(x)的数据
X_train = np.linspace(0, 2 * np.pi, 20)
Y_train = np.sin(X_train)

# 随机初始化QNN的参数
num_params = 4
params = np.random.uniform(0, 2 * np.pi, num_params, requires_grad=True)

# 4. 选择优化器
opt = qml.AdamOptimizer(stepsize=0.1)

# 5. 训练循环
epochs = 50
for i in range(epochs):
    
    # 定义一个函数,它只接受参数,并返回损失。这是优化器需要的格式。
    def cost_fn(p):
        predictions = np.array([quantum_neural_net(p, x) for x in X_train])
        return square_loss(Y_train, predictions)

    # 优化器会自动计算梯度(使用参数平移法则)并更新参数
    params, cost = opt.step_and_cost(cost_fn, params)
    
    if (i + 1) % 10 == 0:
        print(f"Epoch {i+1:2d}: Cost = {cost:.6f}")

print("\n训练完成! 最终参数:", params)

# --- 测试和可视化 ---
import matplotlib.pyplot as plt

X_test = np.linspace(0, 2 * np.pi, 100)
predictions_test = [quantum_neural_net(params, x) for x in X_test]

plt.plot(X_train, Y_train, 'bo', label="Training data")
plt.plot(X_test, predictions_test, 'r-', label="QNN predictions")
plt.legend()
plt.show()

当你运行这段代码时,你会看到损失值随着迭代逐渐减小,并且最终QNN的预测曲线能够很好地拟合 sin(x) 函数。这证明了我们的量子神经网络确实“学会”了模式!

3.2 增强QNN:作为“即插即用”模块的混合模型

我们刚刚学会了如何使用参数平移法则(PSR)来获取量子电路的梯度。这个发现的意义远不止于训练一个独立的QNN。它意味着,一个含参数的量子电路(PQC)现在可以被看作是一个完全可微的黑盒

既然它是可微的,我们是否可以将它像乐高积木一样,插入到已经非常成熟的经典深度学习模型中呢?

答案是肯定的!这就是量子-经典混合模型 (Quantum-Classical Hybrid Model) 的核心思想,也是一种强大的“即插即用”(Plug-and-Play) 策略。

混合模型的架构

一个典型的混合模型(例如用于图像分类)的流程如下:

  1. 经典预处理层 (Classical Pre-processing):

    • 一个大的输入(如一张 28x28 的图片)首先通过几层经典的CNN。
    • CNN的作用是将图片降维,提取出关键的特征,输出一个小的特征向量(例如,一个长度为4或8的向量)。
  2. 量子层 (Quantum Layer):

    • 这个从经典层输出的特征向量,被用作量子电路的输入。通常,这些特征值会作为旋转门的角度,将信息编码到量子态中。
    • 这个量子电路(PQC)本身也包含可学习的参数 θ
    • 电路演化后,测量一个或多个可观测量,其期望值作为该量子层的输出。
  3. 经典后处理层 (Classical Post-processing):

    • 从量子层输出的期望值(现在是普通的经典数值)可以被送入一个或多个经典的神经元(全连接层),进行最终的分类或回归。

端到端的训练:无缝的梯度流

这个混合模型最美妙的地方在于,整个系统是端到端可训练的
当计算损失函数关于所有参数的梯度时:

  • 对于经典层的参数,梯度通过反向传播计算。
  • 当梯度流“到达”量子层时,框架(如PennyLane)会自动切换到参数平移法则来计算损失关于量子参数 θ 的梯度。
  • 更神奇的是,框架还能计算出损失关于输入到量子层的数据的梯度,并将这个梯度继续向前传播给更早的经典层。

这意味着,我们可以像训练一个纯经典网络一样,调用 loss.backward()optimizer.step(),整个混合模型的参数(包括经典的权重和量子的旋转角)都会被自动、协同地优化。

以 PennyLane 和 PyTorch 为例

PennyLane 与 PyTorch、TensorFlow 等主流框架的集成让这种“即-插即用”变得异常简单。我们可以将一个 QNode 包装成一个标准的 PyTorch 层。

让我们修改一下之前的代码,构建一个简单的混合模型。

任务: 用一个经典线性层对数据进行预处理,然后送入QNN。

import torch
import pennylane as qml
from pennylane import numpy as np

# --- 1. 定义量子设备和QNode (与之前相同) ---
dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev)
def quantum_circuit(params, x):
    # 我们假设x是一个有4个元素的向量
    # 编码层:用输入x来参数化
    qml.RY(x[0], wires=0)
    qml.RY(x[1], wires=1)
    
    # 模型层:可学习的参数params
    qml.CNOT(wires=[0, 1])
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=1)
    
    # 测量层
    return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1)) # 测量一个关联算符


# --- 2. 构建混合模型 ---
# a. 定义经典部分
# 一个从1维输入到4维输出的线性层
classical_layer = torch.nn.Linear(1, 4) 

# b. 将QNode包装成一个PyTorch层
# weight_shapes定义了QNode中可学习参数的形状
weight_shapes = {"params": (2,)} 
quantum_layer = qml.qnn.TorchLayer(quantum_circuit, weight_shapes)

# c. 使用torch.nn.Sequential将它们“即插即用”地连接起来
hybrid_model = torch.nn.Sequential(
    classical_layer,
    quantum_layer
)

# --- 3. 训练循环 (标准的PyTorch流程) ---
# 准备数据
X_train = torch.linspace(0, 2 * np.pi, 20).reshape(-1, 1)
Y_train = torch.sin(X_train)

# 定义优化器,它会同时看到经典和量子的参数!
opt = torch.optim.Adam(hybrid_model.parameters(), lr=0.1)
loss_fn = torch.nn.MSELoss()

epochs = 50
for i in range(epochs):
    opt.zero_grad() # 清空梯度
    
    predictions = hybrid_model(X_train).reshape(-1) # 前向传播
    loss = loss_fn(predictions, Y_train.reshape(-1)) # 计算损失
    
    loss.backward() # 反向传播 (神奇之处:PyTorch和PennyLane在此协同工作)
    opt.step()      # 更新所有参数
    
    if (i + 1) % 10 == 0:
        print(f"Epoch {i+1:2d}: Loss = {loss.item():.6f}")
        
# --- 4. 可视化结果 ---
import matplotlib.pyplot as plt
X_test = torch.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
predictions_test = hybrid_model(X_test).detach().numpy() # 使用detach()来切断梯度追踪

plt.plot(X_train.numpy(), Y_train.numpy(), 'bo', label="Training data")
plt.plot(X_test.numpy(), predictions_test, 'r-', label="Hybrid QNN predictions")
plt.legend()
plt.show()

在这个例子中,qml.qnn.TorchLayer 就是那个神奇的“适配器”,它让量子电路完美地融入了PyTorch的生态系统。整个训练流程与纯经典模型的训练流程几乎完全一样,充分体现了“即插即用”的便利性。

总结:混合模型的潜力

  • 发挥各自优势:结合了经典网络强大的特征提取能力和量子电路潜在的更强表达能力。
  • 适应NISQ硬件:使得在小规模量子设备上解决有意义的现实问题成为可能。
  • 灵活性:可以方便地将量子层插入到任何经典深度学习架构的任何位置,为模型设计提供了巨大的灵活性。
  • 活跃的研究方向:探索何种问题、何种架构最能从这种混合模式中获益,是当前量子机器学习领域最前沿的研究方向之一。

本课总结

  1. QNN 的核心思想是用含参数的量子电路来替代经典神经网络的层
  2. 旋转门的角度 θ 是QNN的可学习参数
  3. QNN的输出是某个可观测量 M 的期望值,它是一个关于 θ 的连续、可微函数。
  4. 我们可以使用高效的参数平移法则来精确计算梯度,从而利用经典优化算法(如梯度下降)来训练QNN。
  5. PennyLane 等框架极大地简化了QNN的构建和训练过程,让我们能专注于模型设计本身。

在下一节课,我们将探讨更复杂的QNN结构、不同的数据编码方法,以及QNN在分类、强化学习等领域的潜在应用。

声明:Zhaoyun's Quantum Lab|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 量子神经网络


With code, we create everything