一、描述
在一个项目种使用其他项目训练好的模型权重的时候(加载权重的时候),出现了一个很奇怪的错误:
AttributeError: Can't get attribute 'UWnet' on <module 'model' from ' +地址
或者
ModuleNotFoundError: No module named 'model'
二、原因:
torch.load()的锅,在保存模型权重的时候,使用但是torch.save(model,path),而不是torch.save(model.state_dict(),path)
1.先看第一个错误:ModuleNotFoundError: No module named 'model'
其实这里的'model'就是在保存这个模型权重的时候,模型类的文件名,比如如果你的模型的文件名叫u-net那么这里就会报错: ModuleNotFoundError: No module named 'u-net'。
第二个错误:AttributeError: Can't get attribute 'UWnet' on <module 'model' from ' +地址
意思是无法从地址当中的文件当中获取module的属性:UWnet,这个地址最终指向的是你的模型的文件
那么从报错的信息当中:return super().find_class(mod_name, name)
这里是在获取你创建的模型的类名称,从创建自己模型的时候会继承父类nn.Module当中的属性,这个报错的原因是没有在该文件下找到类'UWnet'的属性(当然这里的'UWnet'根据自己的定义的名称不同二不同)。
三、解决办法
1.第一个错:
去训练保存该模型的问价目录下看看torch.save()与你的模型的文件名所在的相对位置,并按照torch.save()(也就是train.py)与该模型的相抵路径进行一一复制。比如我训练的文件和模型文件所在位置如下图:
那么我就要将model.py复制到相对于在现在这个项目将要运行的文件的相对路径下,比如我现在要运行:ImageDehazingUI.py。
那么就要将model.py复制到与ImageDehazingUI.py同一个路径下
其他情况:如果寻来你项目的路径是这样:
那么就要在ImageDehazingUI.py同目录下创建文件夹model1然后将model.py复制到该文件下。
2.第二个错
只需要将model.py当中的类换成你要调用权重模型的类就好。比如在model.py当中的模型叫u-net,而1.我要调用的模型叫UWnet,所以就把u-net的model.py替换成UWnet的model.py文件
3.其他方法
就是在保存模型的时候直接使用
torch.save(self.model.state_dict(),path),这样在加载模型的时候可以先加载权重,然后模型再读取权重。:data=torch.load()->model.load_state_dict(data).
个人觉得使用torch.save(model,path)的时候,保存的是模型和权重也包括模型的路径,所以再加载权重的时候,使用torch.load()根本不需要model.load_state_dict(data)因为模型和权重都保存了可以直接加载。但.torch.save(self.model.state_dict(),path)只是保存了权重所以是指定模型然后再加载权重。