You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PennyLane WireError求助:量子网络处理4D张量时设备无对应线路

问题分析与修复建议

报错pennylane.wires.WireError: Cannot run circuit(s) on default.qubit as they contain wires not found on the device的核心原因及修复点如下:

核心问题

  1. 量子设备wire数量未匹配:默认default.qubit设备未指定足够的wire数,而你设置了n_qubits=32,电路尝试使用32及以上编号的wire但设备不支持。
  2. BatchNorm层类型误用:输入是4维张量(32,32,128,2),经过Linear(2,32)后输出形状为(32,32,128,32),但BatchNorm2d是针对通道在第2维度(dim=1)的张量,此处通道在最后一维,类型不匹配。
  3. 输入维度与量子层不兼容:4维张量直接传入TorchLayer会导致量子层无法正确解析每个样本的输入角度,需要调整维度适配量子电路的输入要求。
  4. 标签形状不匹配:输入总样本数为32*32*128=131072,但标签形状未对应,会导致交叉熵损失计算报错。

修复步骤与完整代码

1. 定义带指定wire数的量子设备与qnode

显式创建支持32个wire的量子设备,并定义匹配输入输出的量子电路。

2. 修正BatchNorm层与维度处理

将BatchNorm2d替换为BatchNorm1d(指定通道维度为最后一维),并在forward中调整张量维度,确保量子层输入为(总样本数, n_qubits)的形状。

3. 匹配标签形状

生成与输入总样本数一致的标签张量。

完整修复代码:

import torch
import torch.nn as nn
import torch.nn.init as init
import pennylane as qml
import numpy as np

# 全局参数定义
feat_dim = 2
n_qubits = 32
q_depth = 2  # 补充原代码未定义的q_depth参数
batch_size_total = 32 * 32 * 128  # 输入总样本数

# 1. 创建带指定wire数的量子设备与qnode
dev = qml.device("default.qubit", wires=n_qubits)

@qml.qnode(dev)
def qnode(inputs, weights):
    # 角度嵌入:将每个输入对应到一个qubit的旋转角度
    qml.AngleEmbedding(inputs, wires=range(n_qubits), rotation='Y')
    # 纠缠层:构建深度为q_depth的纠缠电路
    qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
    # 返回每个qubit的Z期望测量值,共n_qubits个输出
    return [qml.expval(qml.PauliZ(w)) for w in range(n_qubits)]

# 2. 修正量子网络类
class Quantumnet(nn.Module):
    def __init__(self, feat_dim):
        super().__init__()
        self.pre_net = nn.Linear(feat_dim, n_qubits)
        # 使用BatchNorm1d,指定通道维度为最后一维
        self.bn = nn.BatchNorm1d(n_qubits, dim=-1)
        # 初始化TorchLayer,参数形状匹配q_depth和n_qubits
        self.vqc = qml.qnn.TorchLayer(qnode, {"weights": (q_depth, n_qubits)})
        self.post_net = nn.Linear(n_qubits, 2)
        self.ce = nn.CrossEntropyLoss()
        self.initialize_params()

    def initialize_params(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):
                init.xavier_normal_(m.weight.data)
                if m.bias is not None:
                    m.bias.data.fill_(0)
            elif isinstance(m, nn.BatchNorm1d):
                m.running_mean.data.fill_(0)
                m.running_var.data.fill_(1)
                
    def forward(self, input_features, labels=None):
        # 保存原始形状,用于后续恢复
        original_shape = input_features.shape
        # 将4维张量展平为(总样本数, feat_dim),适配Linear层
        flat_input = input_features.flatten(0, -2)
        pre_out = self.pre_net(flat_input)
        pre_out = self.bn(pre_out)
        q_in = torch.tanh(pre_out) * np.pi / 2.0
        # 量子层输出形状为(总样本数, n_qubits)
        q_out = self.vqc(q_in)
        post_out = self.post_net(q_out)
        # 计算损失,标签需与post_out的第一维度匹配
        loss = self.ce(post_out, labels) if labels is not None else None
        # 恢复输出形状为(32,32,128,2),并计算差值
        post_out = post_out.view(original_shape[0], original_shape[1], original_shape[2], 2)
        quantum_output = (post_out[:, :, :, 1] - post_out[:, :, :, 0])
        return loss, quantum_output

# 3. 初始化模型与输入数据
model = Quantumnet(feat_dim)
input_features = torch.randn(32, 32, 128, feat_dim)
# 生成匹配总样本数的标签
labels = torch.randint(2, (batch_size_total,), dtype=torch.long)

# 测试模型
output = model(input_features, labels=labels)
loss, quantum_output = output
print('Quantum Output Tensor Shape:', quantum_output.shape)  # 应为(32,32,128)

额外说明

  • 原代码中q_depth未定义,修复时补充了该参数,你可根据需求调整量子电路深度。
  • 量子电路的结构(AngleEmbedding、BasicEntanglerLayers)可根据任务需求替换为其他电路模板。
  • 若需要保留4维张量的维度处理,也可通过转置操作将通道移至dim=1,再使用BatchNorm2d,但展平后处理更简洁。

内容的提问来源于stack exchange,提问作者baba tnvn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:05:21