ssd模型pytorch版fine-tune

最近在做目标检测的相关项目,由于是深度学习小白,所以踩了很多坑,对此做一下总结。

关于fine-tune和迁移学习

ssd.pytorch代码链接:https://github.com/amdegroot/ssd.pytorch
由于对深度学习不了解,所以连fine-tune什么意思都不懂。。。。
查阅了一些资料后,大致有了一些了解,以下若有错误的地方,还烦请指正。

迁移学习

迁移学习(Transfer learning) 顾名思义就是把已训练好的模型参数迁移到新的模型来帮助新模型训练。拿这个代码为例,作者给出了vgg16这个模型,我们可以使用这个模型参数来作为一个基础,通过某种方式将这些参数传递给我们 新的模型,从而加快了模型的学习效率,而不是从零开始学习。一般这些基础的模型都是在较大的数据集上训练过的,比如ImageNet。
在这里插入图片描述
我认为fine-tune其实就是利用了迁移学习的一种思想,让我们不必从头进行训练,可以利用别人已经训练好的模型进行一些修改操作来得到我们想要的模型结构。

ssd fine-tune

跑完ssd.pytorch代码后,由于要对新增的数据集进行训练,所以对作者给出的pretrained model进行微调。
在这里插入图片描述
如果我们以作者给出的这个模型接着这个训练就会报以下错:
在这里插入图片描述大致就是维度不匹配,使用的数据集为VOC07+12并且在此基础上增加了一个种类。由于增加了一个种类,所以网络的结构发生了一点变化,导致了不匹配。所以我们要对其修改。

1.读取模型并输出

我们把模型读取出来,看看到底是哪里出了问题。

pth_file = "../weights/ssd300_mAP_77.43_v2.pth"
net = build_ssd("test", 300, 21)
ssd_dict = net.state_dict()
for k,v in ssd_dict.items():
    print(k, v.shape)

在这里插入图片描述
我们发现是conf层出了问题,因为conf层涉及了分类所以种类变了,导致维度不同。我们进行以下修改。在ssd.py中增加一个finetune_ssd函数用于加载预训练模型。
1.定义模型, 2.加载预训练模型,对网络部分参数进行更新, 3.冻结部分层
1.定义模型
net = build_ssd(“test”, 300, 22) # 种类有21变为22

    def finetune_ssd(self, base_file):
        """fine-tune ssd
            
        Args:
            self: ssd网络
            base_file: 预训练模型
        Returns:

        """
        other, ext = os.path.splitext(base_file)
        if ext == '.pkl' or '.pth':
            print('Loading weights into state dict...')
            # 2.加载并读取预训练模型相应参数
            ssd_dict = self.state_dict()
            pretrained_dict = torch.load(base_file)
            # 增加了种类,conf层的维度与预训练模型维度不同,删除预训练模型跟当前模型层名称相同,层结构却不同的元素
            for k in list(pretrained_dict.keys()):
                if "conf" in k:
                    pretrained_dict.pop(k)
            # 去除不要的一些参数
            pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in ssd_dict}
            # 参数更新
            ssd_dict.update(pretrained_dict)
            # 加载我们需要的参数
            self.load_state_dict(ssd_dict)
            # 3.冻结部分层,使其参数不再更新
            for name, value in self.named_parameters():
                if "conf" not in name:
                    value.requires_grad = False  # 将此属性设为False
            print('Finished!')
        else:
            print('Sorry only .pth and .pkl files supported.')

最后在train.py中将其加载模型的函数换为:
在这里插入图片描述
将优化器接收的参数改为过滤掉requires_grad=Flase后的参数,即使除了conf层其他层的参数都不再进行更新:
在这里插入图片描述

参考:

https://www.jianshu.com/p/d67d62982a24
https://blog.csdn.net/caomin1hao/article/details/105990127

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值