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

PyTorch与PennyLane混合模型loss.backward()报错求助

PyTorch+PennyLane混合模型反向传播报错问题排查

问题背景

使用PyTorch与PennyLane构建的混合深度学习模型,前向传播可正常执行并输出loss值,但调用loss.backward()时触发RuntimeError。

模型代码

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv1d(1, 8, 30, 2)
        self.conv2 = nn.Conv1d(8, 16, 20, 2)
        self.conv3 = nn.Conv1d(16, 32, 10, 2)
        self.dropout = nn.Dropout1d()
        self.fc1 = nn.Linear(160, 64)
        self.fc2 = nn.Linear(64, 16)

    def forward(self, x):
        x = nn.functional.tanh(self.conv1(x))
        x = nn.functional.tanh(self.conv2(x))
        x = nn.functional.tanh(self.conv3(x))
        x = self.dropout(x)
        x = x.view(1, -1)
        x = nn.functional.tanh(self.fc1(x))
        x = self.fc2(x)
        x = qlayer(x)
        #print("output of qlayer:", x)

        return x

报错信息

loss: tensor(-0.6875, grad_fn=<NllLossBackward0>)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[15], line 16
     13 train_loader = DataLoader(tr_dataset,batch_size=1,shuffle=True,drop_last=True)
     14 test_loader = DataLoader(te_dataset,batch_size=1,shuffle=False,drop_last=False)
---> 16 loss_list_train = train(train_loader=train_loader, epochs=epochs)
     18 train_loss_df = pd.DataFrame(loss_list_train)
     19 train_loss_df.to_csv('F:/Student/CJG/220916_QC/3_IBM_QLAB/2_result/0_hybrid/1_loss/Train_loss(ROI_'+str(ROI_info)+').csv', index=False, header=None)

Cell In[12], line 16, in train(epochs, train_loader)
     14 print("loss:",loss)
     15 # Backward pass
---> 16 loss.backward()
     17 # Optimize the weights
     18 optimizer.step()

File ~\anaconda3\envs\pennylane\lib\site-packages\torch\_tensor.py:488, in Tensor.backward(self, gradient, retain_graph, create_graph, inputs)
    478 if has_torch_function_unary(self):
    479     return handle_torch_function(
    480         Tensor.backward,
    481         (self,),
   (...)
    486         inputs=inputs,
    487     )
---> 488 torch.autograd.backward(
    489     self, gradient, retain_graph, create_graph, inputs=inputs
    490 )

File ~\anaconda3\envs\pennylane\lib\site-packages\torch\autograd\__init__.py:197, in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)
    192     retain_graph = create_graph
    194 # The reason we repeat same the comment below is that
    195 # some Python versions print out the first line of a multi-line function
    196 # calls in the traceback and some print out the last line
---> 197 Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
    198     tensors, grad_tensors_, retain_graph, create_graph, inputs,
    199     allow_unreachable=True, accumulate_grad=True)

RuntimeError: function ExecuteTapesBackward returned a gradient different than None at position 26, but the corresponding forward input was not a Variable

错误原因与修复方案

核心原因

报错本质是量子层qlayer与PyTorch自动求导机制不兼容,导致反向传播时梯度无法匹配到对应的可训练变量,具体包含以下几个可能的诱因:

  1. 量子层未正确适配PyTorch模块
    若qlayer没有通过PennyLane提供的qml.qnn.TorchLayer包装量子电路,会导致它无法被PyTorch的自动求导系统识别,反向传播时无法生成合法的梯度映射。

  2. 硬编码张量维度破坏求导追踪
    前向传播中x = x.view(1, -1)强制固定batch size为1,这种硬编码操作可能破坏张量的求导追踪链路,使得传入量子层的张量不再是PyTorch可识别的可导Variable。

  3. 量子层参数未纳入优化器
    若qlayer的可训练参数没有被添加到PyTorch优化器的参数列表中,反向传播时会出现梯度无法找到对应参数更新的情况,触发不匹配错误。

修复步骤

  • 用TorchLayer包装量子层
    定义量子电路后,必须通过qml.qnn.TorchLayer将其转换为PyTorch兼容层,示例代码:

    def qnode_func(inputs, weights):
        # 定义你的量子电路逻辑
        qml.templates.AngleEmbedding(inputs, wires=range(4))
        qml.templates.BasicEntanglerLayers(weights, wires=range(4))
        return [qml.expval(qml.PauliZ(w)) for w in range(4)]
    
    weight_shapes = {"weights": (2, 4)}  # 根据你的电路参数调整
    qlayer = qml.qnn.TorchLayer(qml.QNode(qnode_func, qml.device("default.qubit", wires=4)), weight_shapes=weight_shapes)
    
  • 修正张量维度处理
    替换硬编码的view操作,自动适配batch size:

    x = x.view(x.size(0), -1)  # 替代x.view(1, -1)
    
  • 确保所有参数纳入优化器
    初始化优化器时,传入模型的全部参数(包括量子层):

    model = Net()
    optimizer = torch.optim.Adam(list(model.parameters()) + list(qlayer.parameters()), lr=0.001)
    # 或者如果qlayer已作为模型成员变量,直接用model.parameters()即可
    

内容的提问来源于stack exchange,提问作者Junggu Choi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:03:19