size mismatch问题:训练权重不匹配问题

在尝试加载二阶段和三阶段模型时遇到RuntimeError,错误源于fc层权重和偏置尺寸不匹配。解决方案是忽略fc层的权重和偏置,通过`ckpt.pop(fc.bias)`和`ckpt.pop(fc.weight)`移除,同时在加载状态字典时设置`strict=False`。在找到并修正代码位置后,问题得到解决。

在测试二阶段和三阶段模型的时候程序一直报错:

RuntimeError: Error(s) in loading state_dict for Eff:
    size mismatch for fc.weight: copying a param with shape torch.Size([18, 1000]) from checkpoint, the shape in current model is torch.Size([14, 1000]).
    size mismatch for fc.bias: copying a param with shape torch.Size([18]) from checkpoint, the shape in current model is torch.Size([14]).

这个问题是参数的权重输出维度不同,查阅网上很多资料,也就是权重的fc层的参数不同,大佬都说把这个fc层忽略就好了。但是我找了好多感觉看不懂,最终找到了下面博主的博客。

https://blog.youkuaiyun.com/weixin_44966641/article/details/120083303

根据博主说的问题进行操作以后还是发现继续报错。

发现自己添加代码的位置错了:

eff_cls2(inner_model=Eff(num_classes=2),
         ckpt_path="D:\\a\\nzb_test-master\\nzb_test-master\\eff\\cls2.pth",
         data_pool=data_pool)

刚开始加在这里发现继续报错,问题一直得不到解决,然后就继续看自己的报错:

Traceback (most recent call last):
  File "D:/a/nzb_test-master/nzb_test-master/test1.py", line 44, in <module>
    data_pool=data_pool)
  File "D:\a\nzb_test-master\nzb_test-master\process.py", line 318, in __init__
    super().__init__(inner_model, ckpt_path, data_pool)
  File "D:\a\nzb_test-master\nzb_test-master\process.py", line 39, in __init__
    self.prepare()
  File "D:\a\nzb_test-master\nzb_test-master\process.py", line 45, in prepare
    self.inner_model.load_state_dict(ckpt)
  File "D:\ananconda\envs\yolo\lib\site-packages\torch\nn\modules\module.py", line 1498, in load_state_dict
    self.__class__.__name__, "\n\t".join(error_msgs)))

发现错误在process里面的,于是我就进去找到了prepare函数,发现在里面找到了自己需要的东西,就根据博主的方法把下面两行代码加了进去。

ckpt.pop("fc.bias")
ckpt.pop("fc.weight")

你的报错是什么,这里就些什么就好了,这个语句的意思是直接把权重当中的这两个层直接忽略掉,于是就不会进行报错了。

但是我的代码还在报错,没办法就回去继续看,发现我在引用模型的时候没有加strict=False,这个语句就是指忽略掉模型和参数文件中不匹配的参数。我的代码里面并没有,于是就这一句也加在了里面,代码就跑通了。

修改后的代码如下:

def prepare(self):
    self.inner_model.cuda()
    ckpt = torch.load(self.ckpt_path)
    ckpt.pop("fc.bias")
    ckpt.pop("fc.weight")
    self.inner_model.load_state_dict(ckpt,strict=False)
    self.inner_model.eval()

到此,错误完全解决了!!!!!!

在 PyTorch 中加载模型权重时,可能会遇到多种问题,尤其是在模型结构或训练环境发生变化的情况下。以下是一些常见的问题及其解决方案: ### 加载模型权重的基本方法 当使用 `torch.load()` 加载模型权重时,通常需要确保模型的结构与保存权重时的结构一致。可以通过以下方式加载模型权重: ```python model = TheModelClass() # 确保模型类已经定义 model.load_state_dict(torch.load(PATH)) model.eval() # 设置模型为评估模式 ``` 如果模型是在多 GPU 环境下训练并使用 `torch.nn.DataParallel` 进行包装,则保存的权重会包含 `module` 前缀。为了在单个 GPU 或 CPU 上加载这些权重,需要对权重文件进行调整,去除 `module` 前缀: ```python def remove_module_prefix(state_dict): from collections import OrderedDict new_state_dict = OrderedDict() for k, v in state_dict.items(): name = k[7:] # 去除 &#39;module.&#39; 前缀 new_state_dict[name] = v return new_state_dict # 加载权重 checkpoint = torch.load(PATH, map_location=device) model.load_state_dict(remove_module_prefix(checkpoint)) ``` ### 模型训练状态恢复 在恢复模型训练状态时,除了加载模型权重外,还需要加载优化器状态和其他训练相关信息。通常,这些信息会在保存模型时一并保存: ```python checkpoint = torch.load(PATH) model.load_state_dict(checkpoint[&#39;model_state_dict&#39;]) optimizer.load_state_dict(checkpoint[&#39;optimizer_state_dict&#39;]) epoch = checkpoint[&#39;epoch&#39;] loss = checkpoint[&#39;loss&#39;] model.train() # 设置模型为训练模式 ``` ### 处理模型结构一致的情况 如果模型结构发生了变化,导致无法直接加载权重,可以手动匹配权重。例如,如果新模型和旧模型的部分层名称同,可以手动将旧模型的权重赋值给新模型的相应层: ```python model_dict = model.state_dict() pretrained_dict = torch.load(PATH) # 过滤出模型中需要的层 pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict and model_dict[k].size() == v.size()} # 更新模型的权重 model_dict.update(pretrained_dict) model.load_state_dict(model_dict) ``` ### 自定义加载逻辑 在某些情况下,可能需要自定义加载逻辑来处理特定的需求。例如,如果模型中某些层的权重形状匹配,可以选择跳过这些层的加载: ```python model_dict = model.state_dict() pretrained_dict = torch.load(PATH) for k, v in pretrained_dict.items(): if k in model_dict and model_dict[k].size() == v.size(): model_dict[k] = v else: print(f"Skipping {k} due to size mismatch.") model.load_state_dict(model_dict) ``` ###
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值