以resnet50为backbone的ssd模型以及代码总结

ssd模型图示

模型原理

ssd主要的思想是以cnn做为特征提取网络,例如以resnet50做为提取网络,删除掉resnet后面的全连接层,再增添几层额外的卷基层提取特征,得到不同尺度的特征图,然后我们让这些不同层次的特征图分别预测不同大小的目标,浅层卷积层提取到的是比较细小的特征,越深层的卷积提取到的信息会越丰富,因此我们让浅层的卷积特征图去检测小的目标,让深层的卷积特征图去检测大的目标。
还是直接上图和代码吧
在这里插入图片描述

ssd原论文应该是使用的vgg做为backbone,这里我做了一点修改,使用更优秀的resnet50做为backbone提取原图的特征信息。
首先,ssd接收的输入图像是300300的彩色rgb图像,即原始输入是input_size (3,300,3),依次经过以下卷积层
具体流程见我在草稿纸上推的流程,需要注意的一点是ssd的resnet50与普通resnet50有一点不同就是他在resnet的conv4_的第一个block中把s从2设置成了1,目的是不让通过conv4之后特征图尺寸缩小一半,因此可以看到通过conv3_的特征图尺寸为512
3838,通过conv4_之后尺寸为10243838,并没有缩减一半到1919.

在这里插入图片描述
由上图推导可以看出我们再resnet之后增添了5个层再加上resnet的conv4_得到的特征图,最终得到了6个特征图分别是
feature_map1(1024, 38, 38)
feature_map2(512, 19, 19)
feature_map3(512, 10, 10)
feature_map4(256, 5, 5)
feature_map5(256, 3, 3)
feature_map6(256, 1, 1)

backbone代码

class Backbone(nn.Module):
    def __init__(self, pretrain_path=None):
        super(Backbone, self).__init__()
        net = resnet50()
        # outchannels指输出的六个features_map的维度
        self.out_channels = [1024, 512, 512, 256, 256, 256]

        if pretrain_path is not None:
            net.load_state_dict(torch.load(pretrain_path))
		# 为网络定义特征提取器,是resnet从第一个卷积层到conv4_
        self.feature_extractor = nn.Sequential(*list(net.children())[:7])
		
        conv4_block1 = self.feature_extractor[-1][0]

        # 修改conv4_block1的步距,从2->1,不让特征图尺寸缩减一半
        conv4_block1.conv1.stride = (1, 1)
        conv4_block1.conv2.stride = (1, 1)
        conv4_block1.downsample[0].stride = (1, 1)

    def forward(self, x):  # 得到第一个feature_map1
        x = self.feature_extractor(x)
        return x

下面是为ssd增添额外卷积层的代码

    def 
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值