Skip to content

Commit

Permalink
Update the table of contents and titles to make the article content s…
Browse files Browse the repository at this point in the history
…tructure clearer
  • Loading branch information
HarleysZhang committed Sep 30, 2020
1 parent a4f62d4 commit 564ad23
Showing 1 changed file with 27 additions and 96 deletions.
123 changes: 27 additions & 96 deletions 计算机视觉/目标检测基本概念与评价指标计算.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 前言
**不同的问题和不同的数据集都会有不同的模型评价指标,比如分类问题,数据集类别平衡的情况下可以使用准确率作为评价指标,但是现实中的数据集几乎都是类别不平衡的,所以一般都是采用 `AP` 作为分类的评价指标,分别计算每个类别的 `AP`,再计算`mAP`**
## anchors
## 一,anchors 理解
所谓 `anchors`,实际上就是一组由 generate_anchors.py 生成的矩形框。其中每行的4个值 `(x1,y1,x2,y2)` 表矩形左上和右下角点坐标。9 个矩形共有 3 种形状,长宽比为大约为 `{1:1, 1:2, 2:1}` 三种, 实际上通过anchors就引入了检测中常用到的多尺度方法。generate_anchors.py的代码如下:
```Python
import numpy as np
Expand Down Expand Up @@ -78,7 +78,7 @@ if __name__ == "__main__":
[ -37.254833 -82.50967 98.50967 53.254833]
[ -82.50967 -173.01933 189.01933 98.50967 ]
[-173.01933 -354.03867 370.03867 189.01933 ]]
## 交并比IOU
## 二,交并比IOU
交并比(Intersection-over-Union,IoU),目标检测中使用的一个概念,是产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率,即它们的交集与并集的比值。最理想情况是完全重叠,即比值为1。计算公式如下:

![IOU计算公式](../images/IOU计算公式.png)
Expand Down Expand Up @@ -151,7 +151,7 @@ if __name__=='__main__':

![程序运行结果](../images/iou代码输出结果.png)

## 非极大值抑制算法NMS
## 三,NMS 算法
### [NMS介绍](https://juejin.im/entry/5bdbc26151882516da0ddd25)
在目标检测中,常会利用非极大值抑制算法(NMS,non maximum suppression)对生成的大量候选框进行后处理,去除冗余的候选框,得到最佳检测框,以加快目标检测的效率。其本质思想是其思想是搜素局部最大值,抑制非极大值。非极大值抑制,在计算机视觉任务中得到了广泛的应用,例如边缘检测、人脸检测、目标检测(DPM,YOLO,SSD,Faster R-CNN)等。即如下图所示实现效果,消除多余的候选框,找到最佳的 `bbox``NMS过程`如下图所示:

Expand Down Expand Up @@ -280,7 +280,7 @@ def nms(bboxs,scores,thresh):
order=order[ious<=thresh]
return keep
```
## Soft NMS算法
## 四,Soft NMS算法
Soft NMS算法是对NMS算法的改进,是发表在ICCV2017的文章中提出的。`NMS`算法存在一个问题是可能会把一些目标框给过滤掉,从而导致目标的`recall`指标比较低。原来的NMS可以描述如下:将IOU大于阈值的窗口的得分全部置为0,计算公式如下:

![硬NMS算法](../images/硬NMS算法.jpg)
Expand Down Expand Up @@ -340,17 +340,21 @@ def soft_nms(dets, thresh, type='gaussian'):
scores = scores[tmp]
return keep
```
## AP计算
## 五,AP计算概述
**目标检测领域常用的评估标准是**`mAP`(mean average precision),计算 mAP 需要先计算 `AP`,计算 `AP` 需涉及到 `precision``recall` 的计算,而这两者的计算又需设计 `TP``FP``FN` 的计算。

`AP` 的计算一般先涉及到 `P-R` 曲线(precision-recall curve)的绘制,P-R曲线下面与x轴围成的面积称为`average precison(AP)`。下图是一个二分类问题的P-R曲线:

![分类问题的PR曲线图](../images/分类PR曲线图.png)

### 近似计算AP(approximated average precision)
知道了`AP` 的定义,下一步就是理解`AP`计算的实现,理论上可以通过积分来计算`AP`,公式如下:
$$AP=\int_0^1 P(r) dr$$
但通常情况下都是使用近似或者插值的方法来计算 AP。
### 5.1,近似计算AP

$$AP = \sum_{k=1}^{N}P(k)\Delta r(k)$$

+ 这个计算方式称为 approximated 形式的,而插值计算的方式里面这个是最精确的,每个样本点都参与了计算
+ 近似计算 AP(`approximated average precision`),这种计算方式是 approximated 形式的
+ 很显然位于一条竖直线上的点对计算AP没有贡献;
+ 这里 `N` 为数据总量,`k` 为每个样本点的索引, $Δr(k)=r(k)−r(k−1)$。

Expand Down Expand Up @@ -405,8 +409,8 @@ def draw_PR_curve(predict_scores, eval_labels, name, cls_idx=1):
plt.close(fig)
```

### 插值计算(Interpolated average precision)
插值计算 AP 的公式的演变过程这里不做讨论,详情可以参考这篇[文章](https://arleyzhang.github.io/articles/c521a01c/),我这里的公式和图也是参考此文章的。`11点插值计算方式计算AP公式`如下:
### 5.2,插值计算AP
插值计算(`Interpolated average precision`) AP 的公式的演变过程这里不做讨论,详情可以参考这篇[文章](https://arleyzhang.github.io/articles/c521a01c/),我这里的公式和图也是参考此文章的。`11点插值计算方式计算AP公式`如下:

![11点插值计算方式计算AP公式](../images/插值计算AP公式.png)

Expand All @@ -421,20 +425,8 @@ def draw_PR_curve(predict_scores, eval_labels, name, cls_idx=1):

![PASCAL论文给出的11点计算AP公式](../images/11点计算AP公式.png)

## 项目中的AP计算代码

### 不同数据集map计算方法
由于 mAP 是数据集中所有类别 AP 值得平均,所以我们要计算mAP,首先得知道某一类别的 AP 值怎么求。不同数据集的某类别的 AP 计算方法大同小异,主要分为三种:

(1)在 `VOC2007`,只需要选取当Recall >= 0, 0.1, 0.2, ..., 1共11个点时的Precision最大值,然后AP就是这11个Precision的平均值,map就是所有类别AP值的平均。

(2)在 `VOC2010` 及以后,需要针对每一个不同的 `Recall` 值(包括0和1),选取其大于等于这些 `Recall` 值时的 `Precision` 最大值,然后计算PR曲线下面积作为 AP 值,map 就是所有类别 AP 值的平均。

(3)`COCO` 数据集,设定多个 IOU 阈值(0.5-0.95,0.05为步长),在每一个IOU阈值下都有某一类别的 AP 值,然后求不同 IOU 阈值下的 AP 平均,就是所求的最终的某类别的AP值。

`VOC` 数据集中计算 `AP` 的代码(用的是插值计算方法,代码出自[py-faster-rcnn仓库](https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py))如下:

1, 在给定 `recal``precision` 的条件下计算AP:
## 六,AP计算代码
1, 在给定 `recal``precision` 的条件下计算 `AP`
```Python
def voc_ap(rec, prec, use_07_metric=False):
"""
Expand Down Expand Up @@ -470,7 +462,7 @@ def voc_ap(rec, prec, use_07_metric=False):
ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])
return ap
```
**给定目标检测结果文件和测试集标签文件 xml 等计算AP**
2,给定目标检测结果文件和测试集标签文件 `xml` 等计算 `AP`
```Python
def parse_rec(filename):
""" Parse a PASCAL VOC xml file
Expand All @@ -493,7 +485,6 @@ def parse_rec(filename):

return objects


def voc_eval(detpath,
annopath,
imagesetfile,
Expand Down Expand Up @@ -636,78 +627,18 @@ def voc_eval(detpath,
return rec, prec, ap
```

## 模型计算量分析
> 终端设备上运行深度学习算法需要考虑内存和算力的需求,因此需要进行模型复杂度分析,涉及到模型计算量(时间复杂度)和模型参数量(空间复杂度)分析。模型理论计算量:指模型推断时需要多少计算次数。
+ `FLOPs`:floating point operations 指的是浮点运算次数,**理解为计算量**,可以用来衡量算法/模型时间的复杂度。
+ `FLOPS`:(全部大写),Floating-point Operations Per Second,每秒所执行的浮点运算次数,理解为计算速度,是一个衡量硬件性能/模型速度的指标。
+ `MACCs`:multiply-accumulate operations,乘-加操作次数,`MACCs` 大约是 FLOPs 的一半。将 $w[0]*x[0] + ...$ 视为一个乘法累加或 `1``MACC`
> 注意,网上很多文章将 MACCs 与 MACC 概念搞混,我猜测可能是机器翻译英文文章不准确的缘故,可以参考此[链接](http://machinethink.net/blog/how-fast-is-my-model/)了解更多。
### 卷积层FLOPs计算
> 卷积操作本质上是个线性运算
+ $FLOPs=(2\times C_i\times K^2-1)\times H\times W\times C_o$(不考虑bias)
+ $FLOPs=(2\times C_i\times K^2)\times H\times W\times C_o$(考虑bias)
+ $MACC=(C_i\times K^2)\times H\times W\times C_o$(考虑bias)

**$C_i$ 为输入特征图通道数,$K$ 为过滤器尺寸,$H,W,C_o$ 为输出特征图的高,宽和通道数**`二维卷积过程`如下图所示:

> 二维卷积是一个相当简单的操作:从卷积核开始,这是一个小的权值矩阵。这个卷积核在 2 维输入数据上「滑动」,对当前输入的部分元素进行矩阵乘法,然后将结果汇为单个输出像素。
![卷积过程](../images/二维卷积操作动态图.gif)

公式解释,参考[这里](https://zhuanlan.zhihu.com/p/70306015?utm_source=wechat_session&utm_medium=social&utm_oi=571954943427219456),如下:

**理解 `FLOPs` 的计算公式分两步**。括号内是第一步,计算出`output feature map` 的一个 `pixel`,然后再乘以 $H\times W\times C_o$,从而拓展到整个 output feature map。括号内的部分又可以分为两步:$(2\times C_i\times K^2-1)=(C_i\times K^2) + (C_i\times K^2-1)$。第一项是乘法运算次数,第二项是加法运算次数,因为 $n$ 个数相加,要加 $n-1$次,所以不考虑 `bias` 的情况下,会有一个 -1,如果考虑 `bias`,刚好中和掉,括号内变为$(2\times C_i\times K^2)$。

所以卷积层的 $FLOPs=(2\times C_{i}\times K^2-1)\times H\times W\times C_o$ ($C_i$ 为输入特征图通道数,$K$ 为过滤器尺寸,$H, W, C_o$为输出特征图的高,宽和通道数)。

### 全连接层的 FLOPs 计算
全连接层的 $FLOPs = (2I − 1)O$,$I$ 是输入层的维度,$O$ 是输出层的维度。
## 模型参数量分析
> 模型参数数量(params):指模型含有多少参数,直接决定模型的大小,也影响推断时对内存的占用量。
模型参数量的分析是为了了解内存占用情况,内存带宽其实比 `FLOPs` 更重要。目前的计算机结构下,单次内存访问比单次运算慢得多的多。对每一层网络,端侧设备需要:
+ 从主内存中读取输入向量 / `feature map`
+ 从主内存中读取权重并计算点积;
+ 将输出向量或 `feature map` 写回主内存。

`MAes`:memory accesse,内存访问次数。
### 卷积层参数量
卷积层权重参数量 = $C_i\times K^2\times C_o + C_o$。$C_i$ 为输入特征图通道数,$K$ 为过滤器(卷积核)尺寸,$C_o$ 为输出的特征图的 `channel` 数(也是 `filter` 的数量),算式第二项是偏置项的参数量 。(一般不写偏置项,偏置项对总参数量的数量级的影响可以忽略不记,这里为了准确起见,把偏置项的参数量也考虑进来。)

假设输入层矩阵维度是 96×96×3,第一层卷积层使用尺寸为 5×5、深度为 16 的过滤器(卷积核尺寸为 5×5、卷积核数量为 16),那么这层卷积层的参数个数为 5×5×3×16+16=1216个。
### BN层参数量
`BN` 层参数量 = $2\times C_i$。其中 $C_i$ 为输入的 `channel` 数(BN层有两个需要学习的参数,平移因子和缩放因子)

### 全连接层参数量
全连接层参数量 = $T_i\times T_o + T_O$。$T_i$ 为输入向量的长度, $T_o$ 为输出向量的长度,公式的第二项为偏置项参数量。(目前全连接层已经逐渐被 `Global Average Pooling` 层取代了。) 注意,全连接层的权重参数量(内存占用)远远大于卷积层。
### 参考资料
+ [PRUNING CONVOLUTIONAL NEURAL NETWORKS
FOR RESOURCE EFFICIENT INFERENCE
](https://arxiv.org/pdf/1611.06440.pdf)
+ [神经网络参数量的计算:以UNet为例](https://zhuanlan.zhihu.com/p/57437131)
+ [How fast is my model?](http://machinethink.net/blog/how-fast-is-my-model/)
+ [MobileNetV1 & MobileNetV2 简介](https://blog.csdn.net/mzpmzk/article/details/82976871)
## 双精度、单精度和半精度
`CPU/GPU` 的浮点计算能力得区分不同精度的浮点数,分为双精度 `FP64`、单精度 `FP32` 和半精度 `FP16`。因为采用不同位数的浮点数的表达精度不一样,所以造成的计算误差也不一样,对于需要处理的数字范围大而且需要精确计算的科学计算来说,就要求采用双精度浮点数,而对于常见的多媒体和图形处理计算,`32` 位的单精度浮点计算已经足够了,对于要求精度更低的机器学习等一些应用来说,半精度 `16` 位浮点数就可以甚至 `8` 位浮点数就已经够用了。
对于浮点计算来说, `CPU` 可以同时支持不同精度的浮点运算,但在 `GPU` 里针对单精度和双精度就需要各自独立的计算单元。
## 浮点计算能力
`FLOPS`:每秒浮点运算次数,每秒所执行的浮点运算次数,浮点运算包括了所有涉及小数的运算,比整数运算更费时间。下面几个是表示浮点运算能力的单位。

+ `MFLOPS`(megaFLOPS):等于每秒一佰万(=10^6)次的浮点运算。
+ `GFLOPS`(gigaFLOPS):等于每秒拾亿(=10^9)次的浮点运算。
+ `TFLOPS`(teraFLOPS):等于每秒万亿(=10^12)次的浮点运算。
+ `PFLOPS`(petaFLOPS):等于每秒千万亿(=10^15)次的浮点运算。
+ `EFLOPS`(exaFLOPS):等于每秒百亿亿(=10^18)次的浮点运算。

### 参考资料
[双精度,单精度和半精度](https://blog.csdn.net/sinat_24143931/article/details/78557852?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase)
## 欧式距离
## 目标检测度量标准汇总
## 七,map计算方法
因为 mAP 值的计算是对数据集中所有类别的 AP 值求平均,所以我们要计算 mAP,首先得知道某一类别的 AP 值怎么求。不同数据集的某类别的 AP 计算方法大同小异,主要分为三种:

(1)在 `VOC2007`,只需要选取当Recall >= 0, 0.1, 0.2, ..., 1共11个点时的Precision最大值,然后AP就是这11个Precision的平均值,map就是所有类别AP值的平均。`VOC` 数据集中计算 `AP` 的代码(用的是插值计算方法,代码出自[py-faster-rcnn仓库](https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py)

(2)在 `VOC2010` 及以后,需要针对每一个不同的 `Recall` 值(包括0和1),选取其大于等于这些 `Recall` 值时的 `Precision` 最大值,然后计算PR曲线下面积作为 AP 值,map 就是所有类别 AP 值的平均。

(3)`COCO` 数据集,设定多个 IOU 阈值(0.5-0.95,0.05为步长),在每一个IOU阈值下都有某一类别的 AP 值,然后求不同 IOU 阈值下的 AP 平均,就是所求的最终的某类别的AP值。

## 八,目标检测度量标准汇总
![目标检测指标汇总](../images/目标检测度量标准汇总.jpg)
## 目标检测领域中的数据不均衡问题
## 九,目标检测领域中的数据不均衡问题
参考此论文[Imbalance Problems in Object Detection](https://arxiv.org/abs/1909.00169.pdf),我的理解之后补充。
## 参考资料
+ [目标检测评价标准-AP mAP](https://Harleyzhang.github.io/articles/c521a01c/)
Expand Down

0 comments on commit 564ad23

Please sign in to comment.