论文笔记2 FasterRCNN

1 网络架构
1.1 整体结构
1.1.1 RCNN

(1) 图像中确定约为1000~2000的候选框
(2) 候选框内提取特征
(3) 分类判别候选框
(4) 候选框位置精修,边框回归
参考: 【目标检测】Faster RCNN算法详解

1.1.2 Fast RCNN

(1) 提升测试速度:将图像归一化直接送进网络
(2) 提升训练速度:候选区前几层特征不再重复计算
(3) 减小训练所需空间:类别判断和位置精挑统一用深度网络实现
参考: 【目标检测】Fast RCNN算法详解

1.2 深入细节
1.2.1 RPN
1.2.2 anchor

判断其中心区域是否是物体

参考:
[1] 大缺弦对anchor的回答
[2] 感受野计算

1.2.3 位置精修(边框回归)

(1) 位置回归损失函数: L o s s = ∑ i N ( t ∗ i − w ^ ∗ T ϕ 5 ( P i ) ) 2 (3.1) Loss = \sum_i^N(t_*^i - \hat w_*^T\phi_5(P^i))^2 \tag{3.1} Loss=iN(tiw^Tϕ5(Pi))2(3.1)其中 t x = ( G x − P x ) / P w , t y 类 似 (3.2) t_x=(G_x−P_x)/P_w,t_y类似\tag{3.2} tx=(GxPx)/Pw,ty(3.2) t w = log ⁡ ( G w / P w ) , t h 类 似 (3.3) t_w = \log (G_w / P_w), t_h类似\tag{3.3} tw=log(Gw/Pw),th(3.3)
其中 t x t_x tx用到归一化思想,而 t w t_w tw l o g log log函数限制尺度大于0,当IOU较大时认为是线性变换 t w = log ⁡ ( G w / P w ) = l o g ( G w + P w − P w P w ) = l o g ( 1 + G w − P w P w ) (3.4) t_w = \log (G_w / P_w) = log(\frac{G_w + P_w - P_w}{P_w}) = log(1 + \frac{G_w-P_w}{P_w})\tag{3.4} tw=log(Gw/Pw)=log(PwGw+PwPw)=log(1+PwGwPw)(3.4) G w − P w = 0 G_w−P_w=0 GwPw=0是线性函数(因为 l i m x = 0 l o g ( 1 + x ) = x lim_{x=0}log(1+x) = x limx=0log(1+x)=x)
(2) 使用smooth L1函数作为回归损失函数的优点:避免L2 loss缺点(对离群点比较敏感);避免L1 loss缺点在0处可能不存在导数,影响收敛.
s m o o t h L 1 = { 0.5 x 2 ∣ x ∣ < 1 ∣ x ∣ − 0.5 o t h e r w i s e smoothL1=\begin{cases} 0.5x^2 & |x| < 1 \\ |x| - 0.5 & otherwise \end{cases} smoothL1={0.5x2x0.5x<1otherwise

参考:
[1] 边框回归
[2] smoothl1损失函数

1.2.4 mAP值计算步骤

(1) precision就是计算模型预测到的所有正例中实际上是正例占的比例,
分母实际上是所有预测到所有该类物体的数目
p r e c i s i o n = T P T P + F P (4.1) precision=\frac{TP}{TP+FP}\tag{4.1} precision=TP+FPTP(4.1)
而recall是实际上的正例成功预测为正例占比,
分母就是实际上ground truth数目即实际正例数
r e c a l l = T P T P + F N (4.2) recall=\frac{TP}{TP+FN}\tag{4.2} recall=TP+FNTP(4.2)
(2) 因为IOU容易标准化,而置信度容易影响AP值,所以通过改变置信度来改变recall值
矩形框IOU计算:两个矩形右下角坐标最小的x减去左上角坐标最大的x大于0则有交集(交集不为空),y轴上类似

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Sergey Karayev
# --------------------------------------------------------

cimport cython
import numpy as np
cimport numpy as np


def compute_overlap(
    np.ndarray[double, ndim=2] boxes,
    np.ndarray[double, ndim=2] query_boxes
):
    """
    Args
        a: (N, 4) ndarray of float
        b: (K, 4) ndarray of float

    Returns
        overlaps: (N, K) ndarray of overlap between boxes and query_boxes
    """
    cdef unsigned int N = boxes.shape[0]
    cdef unsigned int K = query_boxes.shape[0]
    cdef np.ndarray[double, ndim=2] overlaps = np.zeros((N, K), dtype=np.float64)
    cdef double iw, ih, box_area
    cdef double ua
    cdef unsigned int k, n
    for k in range(K):
        box_area = (
            (query_boxes[k, 2] - query_boxes[k, 0] + 1) *
            (query_boxes[k, 3] - query_boxes[k, 1] + 1)
        )
        for n in range(N):
            iw = (
                min(boxes[n, 2], query_boxes[k, 2]) -
                max(boxes[n, 0], query_boxes[k, 0]) + 1
            )
            if iw > 0:
                ih = (
                    min(boxes[n, 3], query_boxes[k, 3]) -
                    max(boxes[n, 1], query_boxes[k, 1]) + 1
                )
                if ih > 0:
                    ua = np.float64(
                        (boxes[n, 2] - boxes[n, 0] + 1) *
                        (boxes[n, 3] - boxes[n, 1] + 1) +
                        box_area - iw * ih
                    )
                    overlaps[n, k] = iw * ih / ua
    return overlaps

(3) 按置信度排序,给recall分等级(VOC07分11个等级, 而VOC11后分n个等级,假设m个样本存在n个正例)
(4) 把每个recall等级的precision累加除以n(n个正例有n个等级)就是该类物体的AP值
A P = 1 n ∑ i = 0 n m a x ( P r e c a l l > r a n k ) AP=\frac{1}{n}\sum_{i=0}^{n}max(P_{recall>rank}) AP=n1i=0nmax(Precall>rank)
(5) mAP就是所有AP值的平均值

参考:
[1] 目标检测模型的评估指标mAP详解(附代码)
[2] 目标检测中mAP计算
[3] mAP计算

1.3 其他知识点
1.3.1 奇异值分解

参考:
[1] 奇异值分解(SVD)原理详解及推导
[2] 矩阵的分解:满秩分解和奇异值分解
[3] 一个矩阵列满秩意味着什么

1.3.2 截断正态分布

理解截断意思:截断,并不意味着直接把原始密度函数两边去掉一部分;而是,截断后概率密度函数曲线会有一些变化,使得总面积仍然为1
f ( x ; μ , σ , a , b ) = 1 σ ϕ ( x − μ σ ) Φ ( b − μ σ ) − Φ ( a − μ σ ) f(x;\mu,\sigma,a,b) = \frac{\frac{1}{\sigma}\phi(\frac{x - \mu}{\sigma})}{\Phi(\frac{b - \mu}{\sigma}) - \Phi(\frac{a - \mu}{\sigma}) } f(x;μ,σ,a,b)=Φ(σbμ)Φ(σaμ)σ1ϕ(σxμ)累积分布函数有这样的认知 b → ∞ ⇒ Φ ( b − μ σ ) = 1 b→∞⇒ Φ(b−μσ)=1 bΦ(bμσ)=1 a → − ∞ ⇒ Φ ( a − μ σ ) = 0 a→−∞⇒ Φ(a−μσ)=0 aΦ(aμσ)=0

意义: 目的是克服饱和函数(像sigmoid),截断正态分布随机数更接近0,在ML当中常希望权重接近0(不过还是难预测)
参考
[1] 正态分布和截断正态分布区别
[2] 理解截断正态分布

2 实践总结
2.1 编译运行

源码分析:参考 Faster R-CNN 源码解析(Tensorflow版)
看的路径:tool中train,test,demo->创建网络的过程(特征提取,rpn,分类和回归)->数据处理和其他部分

2.1.1 编译 tf-faster rcnn

这篇文章对小白非常友好,感谢博主:编译faster rcnn
我的显卡是GTX1050, 安装cuda7.5版本使用的是sm_37(不知道为什么这样也可以)

2.1.2 cuda问题:

anaconda可以安装不同cudatookit但是不能超过它的内核,可以安装各种cudatoolkit,但是关于cuda最重要的内核驱动它并没有安装,无论安装哪个版本的cudatoolkit,都会调用系统的cuda内核
参考:anaconda管理cuda
tensorflow c++编译
tensorflow1.8

2.2 语法和常用API

(1) 使用@property检查参数属性,有setter才可读
(2) raise NotImplementedError预留实现位置,若子类不实现就会报错
(3) argparse(参数解析器)
(4) sys.argv:是一个列表,第一个元素是sys.argv所在的python文件名(字符串类型)
(5) *args传递一个可变参数的列表给函数实参,而**kwargs则是字典形式,另外*args**kwargs前面
(6) from ast import literal_eval若进行运算的数据类型在python中存在则进行运算,否则不运算
(7) zip()将几组可迭代对象的每个元素打包成一对对元组,并返回一个对象, for k, v in zip(a, b)返回的k, v是a, b的元素
(8) cPickledump将对象序列化保存到本地的文件中, loads从字符串变量中再入python对象(cPickle用法)
(9) [:-1]选取的是除了最后项的所有元素
(10) tf.where(condition, a, b)把张量a中condition为False值的位置的元素用b中的代替,a和b的shape一样;可以结合tf.equal(a, C)使用, C为常数值

参考:TensorFlow函数:tf.where

(11) tf.gather_nd,可以把向量的某些值提取出来为新的向量

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值