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自动求导机制不兼容,导致反向传播时梯度无法匹配到对应的可训练变量,具体包含以下几个可能的诱因:
量子层未正确适配PyTorch模块
若qlayer没有通过PennyLane提供的qml.qnn.TorchLayer包装量子电路,会导致它无法被PyTorch的自动求导系统识别,反向传播时无法生成合法的梯度映射。硬编码张量维度破坏求导追踪
前向传播中x = x.view(1, -1)强制固定batch size为1,这种硬编码操作可能破坏张量的求导追踪链路,使得传入量子层的张量不再是PyTorch可识别的可导Variable。量子层参数未纳入优化器
若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
相关产品推荐
相关产品推荐

