使用MobileNetV3作为预训练模型遇到的问题及解决方法

我参加了kaggle上一个分类比赛,然后决定使用预训练好的MobileNetv3作为基本框架进行修改,然后遇到了一系列的问题,记录一下。

一,目标
原始模型:输入为3 * 224 * 224,输出为1000.
我的目标:输入为3 * 512 * 512,输出为 1.

二、原始模型代码及参数
我是在这里找的mobilenetv3代码使用MobileNetV3作为预训练模型遇到的问题及解决方法_第1张图片
然后我选的是mobilenetv3.old.py和它的训练好的权重文件mbv3_large.old.oth.tar(之所以不使用作者更新过的mobilenetv3.py文件是因为作者只更新了代码而没有更新权重文件)

接着便是下载权重文件,然后再上传到kaggle的服务器上面。
而代码我是直接copy然后在kaggle的cell里面运行,就像这样
使用MobileNetV3作为预训练模型遇到的问题及解决方法_第2张图片

三、修改模型
因为我最后是回归问题,而模型原先是1000分类问题,所以我的想法是直接在最后一层(1280 -> 1000)后面再添加一层bn层、hswish层以及线性层(1000 -> 1)。下面是我具体的代码

因为原先权重文件里面每一层的key都包含着’module.’,而我们读取时是不能有这部分的,不然会报错" Miss key(s)…"。所以要去掉这几个字母。使用MobileNetV3作为预训练模型遇到的问题及解决方法_第3张图片

注意:我们修改模型之前应该先把权重读进去,然后再决定添加或删减层。
我的处理:
1、取倒数第四层之前的所有层,即为linear3之前的hswish层
2、再添加自己想要的层。这里的CFG.target_size = 1
3、记得在self.model 和 self.new之间要有一层自适应池化层和维数变换(四维变二维)

使用MobileNetV3作为预训练模型遇到的问题及解决方法_第4张图片
这样我们的模型就定义好了,直接初始化就可以了
使用MobileNetV3作为预训练模型遇到的问题及解决方法_第5张图片
测试一下
在这里插入图片描述

四、遇到的问题
1、" Missing key(s) in state_dict: “conv1.weight”,…"
"Unexpected key(s) in state_dict: “module.conv1.weight”,… "

:正如我前面所说,是因为权重文件的多了’module.'这个前缀,所以我们只要去掉就好了。
使用MobileNetV3作为预训练模型遇到的问题及解决方法_第6张图片

*2、怎么知道我要保存的层数是多少呢?
即self.model = nn.Sequential(list(self.model.children())[:-4])中的’ -4 '是怎么确定的?
、你可以 通过 print(*list(self.model.children())) 来查看模型各层参数,然后再确定具体要哪些层,从而确定层数为多少。大不了就-1、-2一直试下去嘛。

3、当我的batch_size = 1,即测试时 x = torch.randn([1,3,512,512]) ,报错:
Expected more than 1 value per channel when training, got input size torch.Size([1, 1280])

:查了一下发现有可能是样本数与batch_size不匹配的情况(但是1不是会被任何数整除嘛?)然后我改成2、3、16等就都可以了。所以我想应该不可以batch_size = 1吧。后面有大佬指导也可以在评论区里教一下。

使用MobileNetV3作为预训练模型遇到的问题及解决方法_第7张图片

你可能感兴趣的:(人工智能,python)