PyTorch封装ResNet18的自定义模型调用parameters报AttributeError求助
错误原因
你自定义的Model类没有继承PyTorch的nn.Module基类,parameters()、to()、train()等常用模型方法都是nn.Module内置实现的,纯Python自定义类不会自带这些方法,且无法自动注册内部子模块的可训练参数。
解决方案
最标准的修复方式是让你的自定义模型继承nn.Module,同时在构造函数中先调用父类的初始化方法,修改后的代码如下:
import torch.nn as nn import torch.nn.functional as F resnet = resnet18().cuda() #a modified resnet # 继承nn.Module class Model(nn.Module): def __init__(self, model, pool): # 调用父类初始化 super().__init__() self.model = model self.pool= pool # 注意自定义的pool类也需要继承nn.Module,其参数才会被自动注册 def forward(self, sample): output = self.model(sample) output = self.pool(output) output = F.normalize(output, p=2, dim=1) return output
修改后的效果:
- 再执行
model = Model(model=resnet, pool=pool),调用list(model.parameters())就可以正常返回resnet和自定义池化层的所有可训练参数,直接传给优化器即可同时训练两部分参数。 - 额外注意:你自定义的池化类也需要继承
nn.Module,如果池化类是纯Python类没有继承nn.Module,其内部的可训练参数也不会被识别注册。
如果暂时不想修改类的继承关系,也可以手动拼接参数传给优化器,该方案仅作临时兼容使用,不推荐长期使用:
all_params = list(resnet.parameters()) + list(pool.parameters()) optimizer = torch.optim.Adam(all_params, lr=1e-3)
内容的提问来源于stack exchange,提问作者Khabbab Zakaria
相关产品推荐
相关产品推荐

