使用mmdetection时遇到的问题比较多,首先要对自己要使用的预训练模型有一定的了解,并且懂得使用各种分类模型时不同的模型不同任务执行阶段需要参数上的对其。(比如mask-rcnn和它的三个头之间的参数)。
首先,谈谈torch.save()方法保存和加载的.ph文件的格式:
import torch pretrained_weights = torch.load("C:\\Users\\username\\Downloads\\mask_rcnn_x101_32x8d_fpn_mstrain-poly_1x_coco_20220630_170346-b4637974.pth") # 11 是指 数据类别 + 1 print(pretrained_weights)
如上可以得到:
这个meta所保存的是各种类别名、mmdet版本
巴拉巴拉,往下翻还有一个键值对
这里保存的是各个层的参数。
然后,谈一下遇到的两个问题:
1.
The model and loaded state dict do not match exactly
size mismatch for roi_head.bbox_head.fc_cls.weight: copying a param with shape torch.Size([81, 1024]) from checkpoint, the shape in current model is torch.Size([2, 1024]).
还有五个这种参数,笔者较为仔细地看了mask-rcnn文章和另一位博主使用这个商汤的框架去跑DETR时候遇到的类似的问题,得出解决方案。
先说原因:预训练模型在coco上预训练,而coco本身类别是80,所以它的主干网络送到其他的三个头(分类头、mask回归头、bbox头的参数种类对不上),我这个是个1个类别,加上背景。六个错误维数对不上,刚好对应w、b和三个头。(几个头之间权重是不共享的)
解决方案:把load_from中的权重下载下来,resize然后重新保存,即可。
import torch
pretrained_weights = torch.load("C:\\Users\\user\\Downloads\\mask_rcnn_x101_32x8d_fpn_mstrain-poly_1x_coco_20220630_170346-b4637974.pth")pretrained_weights['state_dict']['roi_head.bbox_head.fc_cls.weight'].resize_(2, 1024) pretrained_weights['state_dict']['roi_head.bbox_head.fc_cls.bias'].resize_(2) pretrained_weights['state_dict']['roi_head.bbox_head.fc_reg.weight'].resize_(4, 1024) pretrained_weights['state_dict']['roi_head.bbox_head.fc_reg.bias'].resize_(4) pretrained_weights['state_dict']['roi_head.mask_head.conv_logits.weight'].resize_(1, 256, 1, 1) pretrained_weights['state_dict']['roi_head.mask_head.conv_logits.bias'].resize_(1)
torch.save(pretrained_weights, "mask_rcnn_x101_32x8d_fpn_mstrain-poly_1x_coco_20220630_170346-b4637974_changed.pth")
笔者做的是一个实例分割任务,加载的权重是从mask-rcnn官方提供的微软在coco数据集预训练的以resnext101为主干网络,权重调整策略是1x。
遇到的问题:unexpectde argument:times
显示多传了一个参数times,我没搜到这个issue
解决方案:
然后把继承的配置文件的训练策略改成一样的然后就可以了,有大佬对训练了解的深一些的可以在评论区讲解一下这个框架中的学习率sheduler策略有什么差别:在1x、2x、3x直接,我还在配置文件中看到一个20e.
参考博客:
1.加载并修改权重https://zhuanlan.zhihu.com/p/465657162
2.相似问题的分析:MMdetection3.0 训练DETR问题分析_mmdetection 训练detr-CSDN博客