浅谈目标识别与运算加速
介绍目标识别
Yolo是目前非常精准的目标识别算法(图像分割可以去隔壁ViT模型看看,效率更高),凭借他较为新颖的算法可以完成绝大多数人群的适配(毕竟那可是目标识别嘛),接下来针对Yolo算法的原理和使用进行详细说明。
R-CNN
作为目标识别的祖宗级别的网络,RCNN以它新颖的思路开创了深度目标识别算法的先河。
既然是目标识别那么我们可以写出如下思路:
- 列出所有目标
- 对每一个目标跑一遍卷积神经网络得到值
- 根据值向量判断类型
对于R-CNN而言,它的流程精髓如上,列出所有目标使用到了选择性搜索(Selective Search)算法,选择性搜索算法使用到的度量值为:
- 颜色相似度
统计颜色直方图,得到所有颜色的一个颜色向量,计算两点的L1范数即可。
$$
s_{color}=\sum_{k=1}^n min(c_i^k,c_j^k)
$$
- 纹理相似度
纹理相似度计算相邻点的导数,将导数计算L1范数后得到的值为纹理相似度
$$
s_{texture}=\sum_{k=1}^n min(t_i^k,t_j^k)
$$
- 尺寸相似度
尺寸相似度在计算的时候优先合并小的区域,如果仅仅是通过颜色和纹理特征合并的话,很容易使得合并后的区域不断吞并周围的区域,后果就是多尺度只应用在了那个局部,而不是全局的多尺度。因此我们给小的区域更多的权重,这样保证在图像每个位置都是多尺度的在合并。
$$
s_{size}=1-\frac{size(r_i)+size(r_j)}{size(im)}
$$
- 填充相似度
填充相似度用于衡量相邻区域的填充程度,给出一个矩形区域计算其中包含两点$r_i和r_j$的的矩形。
$$
s_{fill}=1-\frac{size(Box_{ij})-size(r_i)-size(r_j)}{size(im)}
$$
最终的相似度为前面所有数值的和。
$$
s=s_{color}+s_{texture}+s_{size}+s_{fill}
$$
由此我们得到了很多个可能的区域。尽管精度比较低。
因为区域过多且精度较低,那我们就需要去除那些重复过多的区域,这里使用到的计算方法为交并比IoU。
$$
IoU=\frac{重合面积}{总体面积}
$$
我们希望这个IoU尽可能的小,所以足够大的我们就将它融合。
NMS 非极大值抑制
这个环节是目标的精髓,它可以将IoU合适但是依然重复的那种临界状态区域进行合并计算:
- 将所有框的得分排序,选中最高分及其对应的框
- 遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值(常用的值为0.5左右),我们就将框删除。(为什么要删除,是因为超过设定阈值,认为两个框的里面的物体属于同一个类别,比如都属于狗这个类别。我们只需要留下一个类别的可能性框图即可。)
- 从未处理的框中继续选一个得分最高的,重复上述过程。
SPP-Net
这个网络模型比R-CNN优化了卷积部分,R-CNN是一个区域一个区域去计算,而SPP-Net是一口气全部计算。
缺点显而易见:
- 需要大量的训练集去训练CNN
- 训练时间长,训练阶段多
Yolo
下图为coco测试集的效果,可以看到精度非常高而且重叠区域一样可以识别出来,这就是Yolo的强大之处。
下图为onnx结构图:
局部可见与传统的CNN别无二至。同时多了Split环节,增加了C2F和C3单元。即半数通道卷积和循环卷积。首先介绍一个Yolo使用过的所有单元:
CSP
通过直接卷积与先求残差再求卷积的值进行融合,最后强关联打平化处理。得到最终的前向传播数值
C2F
这里使用到了一个Bottleneck结构,它包含了卷积打平层(CBL),将输出与输入求和。
C2F通过CBL层与Bottleneck进行有限个串联,得到了最终的输出。
SPP
将CBL层与多个池化层进行串联,将所有输出与输入进行强关联操作,然后进行CBL层计算。
接下来使用ultralytics的包使用yolov8吧!
1 |
|
运行效果自行体会。
接下来我们需要对它进行加速处理,对于torch模型可以导出通用模型onnx,使用yolo训练过程也会输出onnx
TensorRT使用onnx
首先将onnx转换成trt文件,然后转化为engine文件,最后直接使用即可,我用C++实现Yolo加速吧!
1 |
|
preprocessing.hpp
1 |
|
我们运行一下就可以让他跑起来啦!