PyTorch中如何正确注册并训练嵌套列表形式的模型参数?
问题原因
报错核心是nn.ParameterList的元素类型限制:nn.ParameterList仅支持存储nn.Parameter类型对象或None,不支持存入普通Python列表、nn.ParameterList、nn.ModuleList等非Parameter类型的对象,你三次尝试的问题分别是:
- 最初直接用Python原生嵌套列表存
nn.Parameter:PyTorch的nn.Module不会自动注册原生列表内的参数,这些参数不会被model.parameters()捕获,优化器无法更新。 - 第一种ParameterList写法:外层
nn.ParameterList接收的元素是普通Python嵌套列表,不符合类型要求。 - 第二种全嵌套ParameterList写法:外层
nn.ParameterList接收的元素是内层nn.ParameterList实例,ParameterList属于nn.Module子类,不是nn.Parameter类型,因此触发你看到的TypeError。
正确实现方式
嵌套结构的参数容器需要用nn.ModuleList做外层/中间层的容器(nn.ModuleList支持存储任意nn.Module子类实例,包括其他ModuleList、ParameterList,也支持直接存储nn.Parameter),最内层直接存参数的层可以用nn.ParameterList,修改后的参数初始化代码如下:
# 初始化bias_para:二维嵌套结构 [层索引, 该层神经元索引] -> 参数 self.bias_para = nn.ModuleList() for l in range(self.total_num_layers): layer_biases = nn.ParameterList([ nn.Parameter(torch.randn((len(self.t), 1))) for k in range(self.neurons[l]) ]) self.bias_para.append(layer_biases) # 初始化weight_para:三维嵌套结构 [层索引, 输出神经元索引, 输入神经元索引] -> 参数 self.weight_para = nn.ModuleList() for l in range(self.total_num_layers): layer_weights = nn.ModuleList() for k in range(self.neurons[l]): neuron_weights = nn.ParameterList([ nn.Parameter(torch.randn((len(self.t), len(self.t)))) for j in range(self.aug_neurons[l]) ]) layer_weights.append(neuron_weights) self.weight_para.append(layer_weights)
注意事项
- 改完后参数访问逻辑和原写法完全一致:访问第l层第k个偏置用
self.bias_para[l][k],访问第l层第k个输出神经元对应第j个输入的权重用self.weight_para[l][k][j],不需要修改前向传播等后续代码。 - 所有参数会被PyTorch自动注册,调用
model.parameters()可以拿到全部可训练参数,优化器可以正常更新。 - 原代码中
self.neurons = [*neurons, 1]存在长度不匹配风险:默认传入neurons=[10,10,10,10,1]时,拼接后self.neurons长度为6,而total_num_layers=5,遍历range(self.total_num_layers)时虽然不会报错,但逻辑上多了冗余的神经元配置,建议根据网络结构设计核对这部分逻辑。
内容的提问来源于stack exchange,提问作者will_cheuk
相关产品推荐
相关产品推荐

