SSD网络backbone由VGG16网络的全部卷积层,即到conv5为止,去掉之后的全连接层。如下图:

然后是
conv6:3x3x1024;
conv7:1x1x1024;
conv8:1x1x256,stride=1,3x3x512,stride=2,padding=1;
conv9:1x1x128,stride=1,3x3x256,stride=2,padding=1;
conv10:1x1x128,stride=1,3x3x256,stride=1,padding=0;
conv11:1x1x128,stride=1,3x3x256,stride=1,padding=0;

其中conv4,7,8,9,10,11作为多尺度特征图,再分别进行3x3xp的卷积提取检测结果。
其中p=( ratio数量x ( 类别数(21)+预测框参数个数(4) ) )
ratio数量 conv7,8,9 为6个,其他为4个,具体原因在稍后讲到。

default box

对于之前的每一个特征图,特征图上的每一个像素点cell都会生成一系列default box,每一个default box按特征图和原图的比例映射到原图,就能获得不同大小的框,来识别不同大小的目标。
每个feature map 的大小分别为

38x38、19x19、10x10、5x5、3x3、1x1

每个特征层经过卷积之后,在channel方向,就有每个小像素点对应ratio组defaultbox的信息,每一组包括21个类别概率,4个预测框回归参数。

defaultbox大小的选取

Sk可以简单理解为default box面积 与 原图的比例,Smax原文取0.9,Smin原文取0.2,m是特征图的数量,backbone里的conv4不算,所以m=5,k是第k个特征图。k=1时,取Sk=0.1。
所以default box的大小(面积开根号)为

                      300 * 0.1,300*0.2,*300[0.2+(0.7/4)*(2-1)],等等

                         30,60,111,162,213,264

实际上很多复现,并没有按这个来~

大小确定,确定ratio,即default box的形状
conv7,8,9 有 6种形状

1:1 、1:1(大小为Sk’)、1:2、2:1、1:3、3:1

conv4,conv10,conv11有4种形状

1:1 、1:1(大小为Sk’)、1:2、2:1、

也就是之前3x3xp卷积的p中的不同

default box中心点的定义

fk为特征图的长度,其实中心点就定义在每个像素点的中间

正负样本的选取

正样本:
首先ground truth匹配每个和它iou最大的boundingbox,将这些boundingbox选为正样本。
bounding box与某个ground truth的IOU大于某个阈值(0.5)设为正样本。

负样本:
其他都为负样本

由于负样本太多,所以会对负样本进行排序,取负样本中概率为背景较大的一些,保持 负样本:正样本 接近 3:1。

损失函数

损失函数定义为位置误差(loc)与置信度误差(conf)的加权和

位置误差采用Smooth L1 loss

l为预测的位置参数,g为真实的位置参数,d为default box的位置参数,x,y是中心坐标,w,h是box的宽和高,xij=1,第i个预测box与第j个ground truth所匹配。
我个人认为学习的是default box 和 ground truth的偏移量,并且只关心位置,不关心类别。

置信度误差
采用softmax,0表示为背景的概率

大概就是这样了,之后遇到什么问题再补充

2021.5.8
SSD300框架

import torch
import torch.nn as nn
from Basic_Net.VGG import VGGclass SSD (nn.Module):def __init__(self,num_class=21):super(SSD, self).__init__()self.num_class = num_classself.backbone = VGG()# todo 把backbone的maxpool改为向上取整 ceil_mode = True# 去掉最后一个maxpoolself.backbone_all = list(self.backbone.children())[0][0:-1]# 去掉conv5 提取特征self.backbone_conv4 = nn.Sequential(*list(self.backbone.children())[0][0:23])print(list(self.backbone.children())[0][0:23])self.backbone = nn.Sequential(*list(self.backbone_all))#self.conv_6_7 = nn.Sequential(nn.Conv2d(512,1024,kernel_size=3,padding=1),nn.BatchNorm2d(1024),nn.ReLU(True),nn.Conv2d(1024,1024,kernel_size=1),nn.BatchNorm2d(1024),nn.ReLU(True),)self.conv_8 = nn.Sequential(nn.Conv2d(1024,256,kernel_size=1),nn.BatchNorm2d(256),nn.ReLU(True),nn.Conv2d(256,512,kernel_size=3,stride=2,padding=1),nn.BatchNorm2d(512),nn.ReLU(True),)self.conv_9 = nn.Sequential(nn.Conv2d(512,128,kernel_size=1,stride=1),nn.BatchNorm2d(128),nn.ReLU(True),nn.Conv2d(128,256,kernel_size=3,stride=2,padding=1),nn.BatchNorm2d(256),nn.ReLU(True),)self.conv_10 = nn.Sequential(nn.Conv2d(256,128,kernel_size=1,stride=1),nn.BatchNorm2d(128),nn.ReLU(True),nn.Conv2d(128,256,kernel_size=3,stride=1,padding=0),nn.BatchNorm2d(256),nn.ReLU(True),)self.conv_11 = nn.Sequential(nn.Conv2d(256,128,kernel_size=1),nn.BatchNorm2d(128),nn.ReLU(True),nn.Conv2d(128,256,kernel_size=3,stride=1,padding=0),# 1x1矩阵就不需要BN啦nn.ReLU(True),)# 提取特征层inchannel = [512,1024,512,256,256,256]self.conv_featrue = []for i,channel in enumerate(inchannel):if i in[1,2,3]:ratio = 6else:ratio = 4print(ratio)# 位置conv_loc = nn.Sequential(nn.Conv2d(channel, ratio * 4, kernel_size=3, stride=1,padding=1),)# 分类置信度conv_cof = nn.Sequential(nn.Conv2d(channel, ratio * num_class, kernel_size=3, stride=1,padding=1),)self.conv_featrue.append((conv_loc,conv_cof))#self.conv_featrue = nn.ModuleList(self.conv_featrue)def forward(self,x):self.feature_extra = []# 先把特征图1拿出来feature_1 = self.backbone_conv4(x)self.feature_extra.append(feature_1)x = self.backbone(x)x = self.conv_6_7(x)self.feature_extra.append(x)x = self.conv_8(x)self.feature_extra.append(x)x = self.conv_9(x)self.feature_extra.append(x)x = self.conv_10(x)self.feature_extra.append(x)x = self.conv_11(x)self.feature_extra.append(x)# batch,channel,w,h w*h 个点 每个点的channel方向是一组 不同形状的box的类别和位置偏移信息self.loc,self.conf = self.get_feature(self.feature_extra)# (batch,4,box_num)return self.loc,self.confdef get_feature(self,feature_list):# nn.ModuleList 使list可以调用Module的方法# self.feature_list = nn.ModuleList(feature_list)locs = []confs = []self.feature_list = feature_listfor (x,conv) in zip(self.feature_list,self.conv_featrue):# conv_feature : tuple(loc_conv2d,confi_conv2d)conv_loc,conv_conf = convloc = conv_loc(x)conf = conv_conf(x)# (batch,ratio_num*4,w,h) => (batch,4,box_num)loc = loc.reshape((loc.size(0),4,-1))# => (batch, 21, box_num)conf = conf.reshape((conf.size(0),self.num_class,-1))locs.append(loc)confs.append(conf)# 所有的cat在一起,cat在哪个维度,哪个维度东西变多loc = torch.cat(locs,2)conf = torch.cat(confs,2)return loc,conf

【深度学习】SSD网络原理相关推荐

  1. 深度学习 | BN层原理浅谈

    深度学习 | BN层原理浅谈 文章目录 深度学习 | BN层原理浅谈 一. 背景 二. BN层作用 三. 计算原理 四. 注意事项 为什么BN层一般用在线性层和卷积层的后面,而不是放在激活函数后 为什 ...

  2. 深度学习的工作原理学习方式

    14天学习训练营导师课程: 李立宗<讲给入门者的深度学习> 工作原理 以培育水稻为例,影响水稻生长的因素包括:施肥量.灌溉量.施肥时间.插秧密度等. 想要获得影响生长因素的各项参数的最优值 ...

  3. 【深度学习】VGGNet原理解析及实现

    [深度学习]VGGNet原理解析及实现 VGGNet由牛津大学的视觉几何组(Visual Geometry Group)和Google DeepMind公司的研究员共同提出,是ILSVRC-2014中 ...

  4. 深度学习Anchor Boxes原理与实战技术

    深度学习Anchor Boxes原理与实战技术 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的地面真实边界框.不同的模型 ...

  5. 《中国人工智能学会通讯》——第3章 3.1基于深度学习的网络表示研究进展

    第3章 3.1基于深度学习的网络表示研究进展 网络结构在现实世界中无处不在(如航线网络.通信网络.论文引用网络.世界万维网和社交网络等),在此基础之上的应用和研究问题受到了学术界和工业界的广泛关注,这 ...

  6. pytorch | 深度学习分割网络U-net的pytorch模型实现

    原文:https://blog.csdn.net/u014722627/article/details/60883185 pytorch | 深度学习分割网络U-net的pytorch模型实现 这个是 ...

  7. 深度学习 自组织映射网络 ——python实现SOM(用于聚类)

    深度学习 自组织映射网络 --python实现SOM(用于聚类) 摘要 python实现代码 计算实例 摘要 SOM(Self Organizing Maps ) 的目标是用低维目标空间的点来表示高维 ...

  8. 深度学习attention原理_深度学习Anchor Boxes原理与实战技术

    深度学习Anchor Boxes原理与实战技术 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的地面真实边界框.不同的模型 ...

  9. 0基础怎样理解深度学习的工作原理?做个票价预测工具就懂了

    原作:Radu Raice 安妮 编译自 Medium 量子位 出品 | 公众号 QbitAI 这篇文章颇!具!人!气! 软件工程专业的学生Radu Raice近日发表了文章<Want to k ...

  10. HALCON 21.11:深度学习笔记---网络和训练过程(4)

    HALCON 21.11:深度学习笔记---网络和训练过程(4) HALCON 21.11.0.0中,实现了深度学习方法.关于网络和训练过程如下: 在深度学习中,任务是通过网络发送输入图像来执行的.整 ...

最新文章

  1. 创建Material Design风格的Android应用--使用Drawable
  2. 看板中的WIP限制思想
  3. 《Orange’s 一个操作系统的实现》3.保护模式3----DOS加载.EXE过程
  4. php中取出数组中指定的值,PHP除开数组中指定的值
  5. 完整html生日祝福代码_孩子生日发朋友圈祝福语(一)!
  6. 迷你星域冒险服务器维护中,迷你世界星域冒险
  7. NSS_08 extjs表单验证
  8. 金鹏GB28181平台对接
  9. 计算机学院篮球赛主题,计算机学院称雄中国科大2011年学生篮球赛
  10. VMware Workstation 14 Pro 安装 Windows Server 2003(完)
  11. Mac词典扩充、本地化
  12. ear的英语怎么念_ear的三种发音各有哪些英文单词
  13. leach协议c++代码_leach协议.doc
  14. wampServer:橙色变绿色
  15. 睡不着有什么办法可以快速入睡?提升睡眠质量的好物和方法分享
  16. SQL注入-安全狗apache绕过
  17. 无线宽带有哪些适用场景?
  18. 在C和C ++中创建循环缓冲区
  19. 『 云原生·Docker』Docker存储
  20. 网狐服务器的基本结构

热门文章

  1. Python图像处理(13):brisk特征检测
  2. 【网络通信】【电信运营商实战工程师】思科设备篇-网络工程师必备基础知识
  3. Visual C++实现推箱子游戏的核心算法设计与实现(附源码和和资源)
  4. 手机号与邮箱正则表达式
  5. Shiro系统权限管理、及原理剖析
  6. freeswitch智能语音开发之ASR
  7. VC知识库的一篇文章
  8. 云服务器云虚拟主机区别,带你了解云服务器和云虚拟主机有什么区别?
  9. Mongodb 查询重复数据
  10. Android LRUCache原理