PyTorch中'Model'对象无'_backward_hooks'属性的错误排查与修复
错误原因分析与修复方案
错误原因
- 未初始化父类
nn.Module:所有继承自nn.Module的子类,必须在__init__方法开头调用super().__init__(),否则PyTorch无法初始化模块所需的内部属性(如_backward_hooks),这是报错的直接原因。 - 子模块未被正确注册:用普通列表
[]存储nn.Linear层时,PyTorch无法将这些层识别为模型的子模块,无法追踪参数、参与反向传播,也会导致模块状态异常。
修复方案
关键修改点
- 在
__init__中添加super().__init__(),初始化父类的核心结构。 - 将
self.layer_s_list改为nn.ModuleList类型,替代普通列表,让PyTorch管理子模块。 - 调整
get_layer_weights的实现,直接从ModuleList的子模块中获取参数,无需通过state_dict。 - 修正矩阵运算逻辑:原代码的逐元素乘法不符合逆矩阵运算逻辑,改为矩阵乘法并调整维度避免报错。
修改后的完整代码
import torch import torch.nn as nn import torch.nn.functional as F import numpy as np class Model(nn.Module): def __init__(self, q, s): # 初始化父类nn.Module,构建模块核心结构 super().__init__() # 用ModuleList存储子模块,让PyTorch追踪参数 self.layer_s_list = nn.ModuleList([nn.Linear(5, s) for _ in range(q)]) self.inv_w, self.inv_b = self.get_layer_weights() def forward(self, x): output_lst = [] for layer in self.layer_s_list: v, id = torch.max(layer(x), 1) output_lst.append(v.detach().numpy()) output_lst = np.array(output_lst) output_lst = torch.from_numpy(output_lst) out, _ = torch.min(output_lst, 0) allo_out = F.softmax(out) pay_out = nn.ReLU(inplace=True)(out) inv_out_lst = [] for q_idx in range(len(self.inv_w)): # 改为矩阵乘法@,调整维度匹配逆矩阵运算 pay_out_expanded = (pay_out - self.inv_b[q_idx]).unsqueeze(1) y, _ = torch.min(torch.linalg.pinv(self.inv_w[q_idx]) @ pay_out_expanded, 0) inv_out_lst.append(y.detach().numpy().squeeze()) final_out = np.array(inv_out_lst) final_out = torch.from_numpy(final_out) final_out, _ = torch.max(final_out, 1) return final_out, allo_out def get_layer_weights(self): weights_lst = [] bias_lst = [] for layer in self.layer_s_list: # 直接从子模块获取参数,无需通过state_dict weights_lst.append(layer.weight) bias_lst.append(layer.bias) return weights_lst, bias_lst
验证代码
q = 5 s = 10 x = torch.rand((10, 5), requires_grad=True) net = Model(q, s) y, z = net(x) print("final_out shape:", y.shape) print("allo_out shape:", z.shape)
内容的提问来源于stack exchange,提问作者Geeky Coder
相关产品推荐
相关产品推荐

