【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias

这篇具有很好参考价值的文章主要介绍了【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.问题描述

2.问题原因

3.问题解决

3.1思路1——忽视最后一层权重

额外说明:假如载入权重不写strict=False, 直接是model.load_state_dict(pre_weights, strict=False),会报错找不到key?

解决办法是:加上strict=False,这个语句就是指忽略掉模型和参数文件中不匹配的参数

3.2思路2——更改最后一层参数

额外说明:假如原有的model默认类别数 和 载入权重类别数不一致,代码如何更改?


1.问题描述

训练一个CNN时,比如ResNet, 借助迁移学习的方式使用预训练好的权重,在导入权重后报错:

RuntimeError: Error(s) in loading state_dict for ResNet:
        size mismatch for linear.weight: copying a param with shape torch.Size([100, 2048]) from checkpoint, the shape in current model is torch.Size([10, 2048]).
        size mismatch for linear.bias: copying a param with shape torch.Size([100]) from checkpoint, the shape in current model is torch.Size([10]).

RuntimeError: Error(s) in loading state_dict for ResNet:
        size mismatch for linear.weight: copying a param with shape torch.Size([100, 2048]) from checkpoint, the shape in current model is torch.Size([10, 2048]).
        size mismatch for linear.bias: copying a param with shape torch.Size([100]) from checkpoint, the shape in current model is torch.Size([10]).

类似的也可以有:

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

导入权重的核心代码为:

    model = model_dict[opt.model](num_classes=10)
    model_path = "./save/models/ResNet50_vanilla/ckpt_epoch_240.pth"
    pre_weights = torch.load(model_path)['model']
    model.load_state_dict(pre_weights, strict=False)

这里的pre_weighets后面还加的有['model']是因为在保存文件的时候出了保存权重,还保存有epoch, acc等等。

【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias

2.问题原因

根本原因在于预训练权重的某一层参数和模型需要的参数对应不上,这里比如就是model.linear层,其实就是相当于全连接层fc, 可以直接model文件中去查看,最后一层的命名。比如进入定义好的ResNet文件中查看最后一层名字为linear。

【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias

 具体的描述:预训练权重中最后一层的输出类别为100, 而现在我们的目标类别是10,所以导致linear层的参数对应不上,进而报错。(更常见的是在imagenet数据上训练分类类别为1000, 目标类别为10,也会是相同的错误)

3.问题解决

3.1思路1——忽视最后一层权重

查阅相关解决办法后,可以使用pop()函数弹出最后一层的参数,这样相当于导入的时候,只有前面网络层参数,就不会报最后一层参数不匹配的问题。所以把权重文件弹出pre_weights.pop('linear.weight')
pre_weights.pop('linear.bias')

核心代码:

    model = model_dict[opt.model](num_classes=10)
    model_path = "./save/models/ResNet50_vanilla/ckpt_epoch_240.pth"
    pre_weights = torch.load(model_path)['model']
    pre_weights.pop('linear.weight')
    pre_weights.pop('linear.bias')
    model.load_state_dict(pre_weights, strict=False)

额外说明:假如载入权重不写strict=False, 直接是model.load_state_dict(pre_weights, strict=False),会报错找不到key?

RuntimeError: Error(s) in loading state_dict for ResNet:
        Missing key(s) in state_dict: "linear.weight", "linear.bias".

解决办法是:加上strict=False,这个语句就是指忽略掉模型和参数文件中不匹配的参数

3.2思路2——更改最后一层参数

因为这里仅仅是最后一层参数不匹配,所以可以获取导入权重的最后一层,然后更改最终的分类类别数目

核心代码:

    model.load_state_dict(pre_weights, strict=False)
    in_channel = model.linear.in_features
    model.linear = nn.Linear(in_channel, n_cls)

代码意思就是:

1.先按照正常的载入模型,如果原来的model文件默认的类别数目和载入权重默认的类别数目一致的话,那么就直接使用上述核心代码就行。

2.获取最后一层的输入特征维度,这里的model.linear.in_features, 是因为在model文件中自定义最后一层为self.linear,要根据实际名称更改

3.更新最后一层的输出特征维度,这里也要使用model.linear

额外说明:假如原有的model默认类别数 和 载入权重类别数不一致,代码如何更改?

举例子:比如model文件中默认分类类别数是10,如下图所示

【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias

但是载入权重文件的的分类类别数是100,如下图所示(这个权重文件训练的数据集就是100个分类类别)

【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias

此时,我想要在一个数据集只有7个类别的数据集上进行迁移学习,载入权重的话,就应该这样写:

    # model
    model = model_dict[opt.model](num_classes=100)
    # print(model)
    model_path = "./save/models/ResNet50_vanilla/ckpt_epoch_240.pth"
    pre_weights = torch.load(model_path)['model']
    # pre_weights.pop('linear.weight')
    # pre_weights.pop('linear.bias')
    # model.load_state_dict(pre_weights, strict=False)
    # # # 更改最后的全连接层
    model.load_state_dict(pre_weights, strict=False)
    in_channel = model.linear.in_features
    model.linear = nn.Linear(in_channel, n_cls)

核心的想法是:实例化模型的时候,需要更改模型的分类类别数100 和 权重文件的类别100数保持一致,也就是如下文章来源地址https://www.toymoban.com/news/detail-412912.html

model = model_dict[opt.model](num_classes=100)

到了这里,关于【Python】解决CNN中训练权重参数不匹配size mismatch for fc.weight,size mismatch for fc.bias的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第56步 深度学习图像识别:CNN梯度权重类激活映射(TensorFlow)

    一、写在前面 类激活映射(Class Activation Mapping,CAM)和梯度权重类激活映射(Gradient-weighted Class Activation Mapping,Grad-CAM) 是两种可视化深度学习模型决策过程的技术。他们都是为了理解模型的决策过程,特别是对于图像分类任务,它们可以生成一种热力图,这种图可以突出显

    2024年02月13日
    浏览(40)
  • 机器学习——python训练CNN模型实战(傻瓜式教学,小学生都可以学会)代码开源

    ​ 第一章 python训练线性模型实战 第二章 python训练决策树模型实战 第三章 python训练神经网络模型实战 第四章 python训练支持向量机模型实战 第五章 python训练贝叶斯分类器模型实战 第六章 python训练集成学习模型实战 第七章 python训练聚类模型实战 第八章 python训练KNN模

    2024年02月04日
    浏览(43)
  • 预训练—冻结权重

    方式:将不更新的参数的requires_grad设置为Fasle,同时不将该参数传入optimizer. (1)不更新的参数的requires_grad设置为Fasle (2)不将该参数传入optimizer 总的代码: 最优写法能够节省显存和提升速度: 节省显存:不将不更新的参数传入optimizer 提升速度:将不更新的参数的requires_g

    2024年02月15日
    浏览(26)
  • [PyTorch]预训练权重的转换

            众所周知,使用大量数据预训练后的骨干网络可以提升整个模型的泛化能力,而我们如果将网络的骨干网络替换后则不能直接使用原来的权重。这个项目的作用是在你替换骨干网络后可以将网络预训练权重一并“偷”过来。         下给结论 :将DeeplabV3+的骨干网

    2023年04月21日
    浏览(27)
  • torch中如何使用预训练权重

    解释说明:目前很多主流的网络模型主要包含backbone+其他结构(分类,回归),那么如何在训练自己的网络模型时使用别人已经训练好的网络模型权重呢??本文以Resnet50为例,构建一个基于resnet50的网络模型预训练过程。 torchvision中封装了Resnet系列、vgg系列、inception系列等网络

    2024年02月07日
    浏览(26)
  • 模型权重和深度学习训练框架之间的关系

    通常我们可以看到有Caffe或Pytorch或TensorFlow的模型参数文件 不同的团队可能会使用不同的深度学习训练框架, 然后使用其 内部的模型权重保存函数 进行保存, 以便之后 自己的复用 或 发布开源 , 让别人使用自己已经训练好的模型权重, 在其基础上进一步做改进或训练 那么该团

    2024年02月11日
    浏览(39)
  • YOLO训练得到权重后无法检测detect目标

    通过自己制造数据集,跑完train.py文件后,得到自己的权重文件 将权重文件带入detect.py文件中,发现可以运行,但是无法识别图片和视频中的目标 3.opencv-python版本太高了,看了一眼,果然版本都到4.6了,猜想opencv-python版本问题,结果——还是不行 https://blog.csdn.net/adai5210/ar

    2024年02月12日
    浏览(30)
  • Yolov8改进模型后使用预训练权重迁移学习训练自己的数据集

    yolov8 github下载 1、此时确保自己的数据集格式是yolo 格式的(不会的去搜教程转下格式)。 你的自制数据集文件夹摆放 主目录文件夹摆放 自制数据集data.yaml文件路径模板 2、把data.yaml放在yolov8–ultralytics-datasets文件夹下面 3、然后模型配置改进yaml文件在主目录新建文件夹v8_

    2024年02月06日
    浏览(37)
  • Stable-Diffusion-Webui部署SDXL0.9报错参数shape不匹配解决

    已经在model/stable-diffusion文件夹下放进去了sdxl0.9的safetensor文件,但是在切换model的时候,会报错model的shape不一致。 update一些web-ui项目就可以,因为当前项目太老了,没有使用最新的版本。

    2024年02月15日
    浏览(33)
  • Pytorch权重初始化/参数初始化

    refer: 【Pytorch】各网络层的默认初始化方法 https://blog.csdn.net/guofei_fly/article/details/105109883 其实Pytorch初始化方法就在各自的层的 def reset_parameters(self) - None: 方法中。 有人可能会问 为什么这个方法和Pytorch直接出来的权重初始值不一样 ?单步调试会发现其实这个方法运行了至少两

    2024年02月11日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包