SSD检测几个小细节
之前感觉SSD很简单,这两天从头到尾把论文和源码都看了一下,发现之前很多细节都没掌握。
这篇文章只说一些之前遗漏的点,读者阅读有一定基础
@
一. 抛砖引玉的Faster-RCNN
1.1 候选框的作用
之前看Fast-RCNN代码对Selective Search的操作一直有很大的疑惑?
为什么一张图会分割成这样大大小小的区域?分割后有啥意义呢?
- 第一个问题很简单,使用了
贪心算法和图论方面的知识,区域合并等算法。 - 第二个问题到后来才明白,是深度学习的
学习成本的问题。。。
看上图的resnet核心模块,就是降低了学习成本,使得网络更容易学习
下面这张图预测区域通过两次平移到达目标区域
下面这张图预测区域先通过放大再做两次平移到达目标区域
下面这张图通过多个预测区域对不同的目标进行预测
通过上面的三幅图可以发现,回归的方式需要付出不同的代价
当然代价越低越容易回归,可以看我之前的文章EAST和改进的EAST,就是通过回归的代价不同,最后效果提升挺大的。
最后一幅图,通过打不同的回归点(Anchor),比盲目的回归效果好很多
那么我们怎么知道目标在哪?怎么打候选框(Anchor)呢?
假设上图是一个4 * 4的feature map,我们既然不知道实际目标在哪,那就以每个像素为中心生成很多个候选框
上面生成的候选框数量也就是4 * 4 * 2=32个
会不会觉得那么多框进行回归效率很低?
首先那么多框都是固定的,比如上图的32个,回归的时候SSD也考虑到了这些,hard sample才需要回归,easy sample是不需要回归的
1.2 下采样问题
- RoIPooling
这个比较简单了,就是一个让输出对称的pooling操作。
- ROIAlign
这个也比较简单,就是利用双线性差值对中心的坐标进行计算出来
二. SSD细节理解
2.1 六个LOSS
这是笔者没看源代码,比较糊涂的想法,问了其他在跑ssd的人也没回答出来。。。
笔者大概画了一个上图,这个问题很简单,想不通就很麻烦。。。
- 在六个feature回归六个图信息
- 六个信息映射到原图大小
- 六个原图大小的信息合并成一个图(一个图6个通道,和一个图RGB通道一样)
2.2 Anchor生成细节
Anchor的特征主要包括几个方面:ratio(长宽比例)、scale(面积开根号,也就是正方形边长)、step/stride(步长,也就是原图和feature的比例)
- ratio:固定的包括几个{1,2,3,1/2,1/3},还有一个1是不同的面积scale
- scale:通过不同的
feature map计算出来的(因为不同的特征图肯定得设置不同大小的scale) - step/stride:两个表示都是一个含义,不同的卷积核(步长、padding)生成的步长不同
一定要理解上面几个参数的含义,具体公式的计算就很简单了,读者可以自己跑一下源代码
def default_prior_box():
mean_layer = []
for k,f in enumerate(Config.feature_map):
mean = []
for i,j in product(range(f),repeat=2):
f_k = Config.image_size/Config.steps[k]#当前feature map 的大小(通过步数重新计算)
#anchor中心点坐标(cx / cy已经归一化操作)
cx = (j+0.5)/f_k
cy = (i+0.5)/f_k
s_k = Config.sk[k]/Config.image_size
mean += [cx,cy,s_k,s_k]
s_k_prime = sqrt(s_k * Config.sk[k+1]/Config.image_size)
mean += [cx,cy,s_k_prime,s_k_prime]
for ar in Config.aspect_ratios[k]:
mean += [cx, cy, s_k * sqrt(ar), s_k/sqrt(ar)]
mean += [cx, cy, s_k / sqrt(ar), s_k * sqrt(ar)]
if Config.use_cuda:
mean = torch.Tensor(mean).cuda().view(Config.feature_map[k], Config.feature_map[k], -1).contiguous()
else:
mean = torch.Tensor(mean).view( Config.feature_map[k],Config.feature_map[k],-1).contiguous()
mean.clamp_(max=1, min=0)
mean_layer.append(mean)
2.3 Encode&&Decode
疑点:刚开始看网上说的:
prior box是:(中心X,中心Y,宽,高)- 实际边界是(中心X,中心Y,宽,高)
- 学习的参数是(中心X偏移,中心Y偏移,宽比例,高比例)
按照这个推理:
\]
\]
\]
\]
其中\(b\)代表实际框,\(d\)代表default box,\(l\)代表回归参数
而实际的表达式如下所示:
\]
\]
\]
\]
笔者认为不管回归什么东西,只要是一种映射关系即可
定义完LOSS,神经网络会帮我们完成这种表达式的关系
所以这里作者也是为了方便,所以使用了除以d,又使用log函数
2.4 负样本挖掘
有专门的论文会解释这类事件,笔者这里只关注SSD的做法
SSD生成8732个prior box框,而实际的一张图中目标只有几个
有无数个预先设定的框,而实际和目标相交大于阈值的框很少
假设直接进行回归操作?
所有的框都进行回归=正样本的框+负样本的框
因为后者占比非常大,LOSS基本由负样本控制,最后的训练的结果如下:
目标能检测到,但是对于边界的处理非常不好,因为细节基本由负样本控制
SSD如何进行操作?
回归分为两个部分=位置回归+类别回归
位置回归按照上述方式进行
种类按照
1 :3的方式进行
首先计算出种类的loss
把正样本的loss置0(正样本全部保留)
负样本进行排序,按照3倍的正样本保留(保留大的loss属于hard sample)
最后正负样本叠加
loss_c = utils.log_sum_exp(batch_conf) - batch_conf.gather(1, target_conf.view(-1, 1))
loss_c = loss_c.view(batch_num, -1)
# 将正样本设定为0
loss_c[pos] = 0
# 将剩下的负样本排序,选出目标数量的负样本
_, loss_idx = loss_c.sort(1, descending=True)
_, idx_rank = loss_idx.sort(1)
num_pos = pos.long().sum(1, keepdim=True)
num_neg = torch.clamp(3*num_pos, max=pos.size(1)-1)
# 提取出正负样本
neg = idx_rank < num_neg.expand_as(idx_rank)
pos_idx = pos.unsqueeze(2).expand_as(conf_data)
neg_idx = neg.unsqueeze(2).expand_as(conf_data)
conf_p = conf_data[(pos_idx+neg_idx).gt(0)].view(-1, Config.class_num)
targets_weighted = target_conf[(pos+neg).gt(0)]
loss_c = F.cross_entropy(conf_p, targets_weighted, size_average=False)
图画的不好,因为正好叠合就看不到效果了
参考文献
https://arxiv.org/pdf/1512.02325.pdf
https://www.cnblogs.com/cmai/p/10080005.html
https://blog.csdn.net/u010167269/article/details/52563573
https://www.cnblogs.com/xuanyuyt/p/7222867.html#_label2
https://www.cnblogs.com/pacino12134/p/10353959.html
https://blog.csdn.net/u010712012/article/details/86555814
https://deepsense.ai/satellite-images-semantic-segmentation-with-deep-learning/
https://www.jianshu.com/p/8b7d7036d715
SSD检测几个小细节的更多相关文章
- 学习Java,容易被你忽略的小细节(2)
昨天心情真的太糟糕了,写完<学习Java,值得注意你注意的问题(1)>之后,迎来些许的支持以后就是一片片的谴责.我的主页上涌现出许许多多Java方面的牛人,谴责我水平太低,写的问题太初级. ...
- Oracle Sales Cloud:管理沙盒(定制化)小细节2——使用对象触发器更新数字字段
在上一篇 "管理沙盒(定制化)小细节1" 的随笔中,我们使用公式法在 "业务机会" 对象(单头)上建立了 "利润合计" 字段,并将它等于 & ...
- Oracle Sales Cloud:管理沙盒(定制化)小细节1——利用公式创建字段并显示在前端页面
Oracle Sales Cloud(Oracle 销售云)是一套基于Oracle云端的CRM管理系统.由于 Oracle 销售云是基于 Oracle 云环境的,它与传统的管理系统相比,显著特点之一便 ...
- Oracle Sales Cloud:报告和分析(BIEE)小细节2——利用变量和过滤器传参(例如,根据提示展示不同部门的数据)
在上一篇随笔中,我们建立了部门和子部门的双提示,并将部门和子部门做了关联.那么,本篇随笔我们重点介绍利用建好的双提示进行传参. 在操作之前,我们来看一个报告和分析的具体需求: [1] 两个有关联的提示 ...
- Oracle Sales Cloud:报告和分析(BIEE)小细节1——创建双提示并建立关联(例如,部门和子部门提示)
Oracle Sales Cloud(Oracle 销售云)是一套基于Oracle云端的客户商机管理系统,通过提供丰富的功能来帮助提高销售效率,更好地去了解客户,发现和追踪商机,为最终的销售成交 (d ...
- php课程---Json格式规范需要注意的小细节
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...
- ASP.NET MVC 自定义路由中几个需要注意的小细节
本文主要记录在ASP.NET MVC自定义路由时,一个需要注意的参数设置小细节. 举例来说,就是在访问 http://localhost/Home/About/arg1/arg2/arg3 这样的自定 ...
- [小细节,大BUG]记录一些小问题引起的大BUG(长期更新....)
[小细节,大BUG] 6.问题描述:当从Plist文件加载数据,放入到tableView中展示时,有时有数据,有时又没有数据.这是为什么呢?相信很多大牛都想到了:我们一般将加载的数据,转换成模型,放入 ...
- C++在使用Qt中SLOT宏须要注意的一个小细节
大家都知道C++虚函数的机制,对于基类定义为虚函数的地方,子类假设覆写,在基类指针或者引用来指向子类的时候会实现动态绑定. 但假设指针去调用非虚函数,这个时候会调用C++的静态绑定,去推断当前的指针是 ...
随机推荐
- PAT-1021 Deepest Root (25 分) 并查集判断成环和联通+求树的深度
A graph which is connected and acyclic can be considered a tree. The height of the tree depends on t ...
- Ajax调用WebService接口样例
在做手机端h5的应用时,通过Ajax调用http接口时没啥问题的:但有些老的接口是用WebService实现的,也来不及改成http的方式,这时通过Ajax调用会有些麻烦,在此记录具体实现过程.本文使 ...
- 算法题:购买n个苹果,苹果6个一袋或者8个一袋,若想袋数最少,如何购买?
这是面试一家公司java实习生的算法题,我当时把代码写出来了,但是回学校之后搜索别人的算法,才发现自己的算法实在是太简陋了呜呜呜 我的算法: public void buy(int n){ int m ...
- CSS3Ps -Photoshop图层特效转CSS3代码
CSS3Ps 这个ps插件可以将ps图层特效直接转化成css3代码,对前端非常有益. 插件下载:http://css3ps.com/Download/
- java ajax上传文件
包括案例 1.springmvc上传 2.ajax上传 3.form表单与文件上传 - 1. http://localhost:8080/ 第一种:springmvc上传- 2. http://loc ...
- nodejs之express的中间件
express中间件分成三种 内置中间件 static 自定义中间件 第三方中间件 (body-parser) (拦截器) 全局自定义中间件 在请求接口时 有几个接口都要验证传来的内容是否存在或者是否 ...
- 安装HANA Rules Framework(HRF)
1. 收集文档 1.1 SAP HANA Rules Framework by the SAP HANA Academy link 1.2 HANA Rules Framework (HRF) b ...
- SDcms1.8代码审计
由于工作原因,分析了很多的cms也都写过文章,不过觉得好像没什么骚操作都是网上的基本操作,所以也就没发表在网站上,都保存在本地.最近突然发现自己博客中实战的东西太少了,决定将以前写的一些文章搬过来,由 ...
- mysql主从部署
一.安装环境 1.系统环境 系统 IP 主机名 说明 server_id centos6.7 192.168.0.173 master 数据库:主 173 centos6.7 192.168.0.1 ...
- MVC-Cache-1.输出缓存(Cache:[1].输出缓存2.应用程序缓存)
缓存前提概念: 1.使用缓存的目的就是为提供网站性能,减轻对数据库的压力,提高访问的速度. 2.如果使用缓存不当,比不使用缓存造成的影响更恶劣(缓存数据的更新不及时.缓存过多等). 3..net MV ...