yolo模型简介
作为一个从业时间1个月的ai相关开发人员,我确实对yolo模型谈不上多了解。但是好在作为一个从业10多年的游戏开发人员,我对“引擎”的理解还是比较深刻的。在我看来yolo模型就是一个引擎,按照规范输入信息,就能获取想要的结果。所以想要使用一个引擎,最关键的是准确理解输入结构和输出结构。而模型部署的主要任务:
- 前处理Preprocess – 就是准备输入数据
- 推理Inference – 这个不需要操心
- 后处理Postprocess–就是从输出数据中取得自己需要的信息
既然绕不开,我就尝试按照自己的理解大致介绍一下这个模型的输入数据和输出数据。如果有错误,也希望不吝赐教。
我司目前用到的yolo模型主要有3种任务:分类Classify,检测Detect和分割Segment。除此之外还有一种任务,似乎是和动作分析有关,但我司业务中用不到,就愉快的略过吧。
ok,假设我有一张图:

然后训练了针对猫狗的3种模型,那么当输入这张图后,各自会得到什么信息呢?
分类Classify
分类是最简单的一种任务,输出是各个分类的概率。所有分类的概率总和为1。经过推理,上图获得的信息如下:

检测Detect
很多时候,我希望知道狗狗到底在图中哪里,所以只有一个分类概率是不够的。我们希望知道图中的什么地方有什么东西。所以目标检测是由一批矩形框,以及每个矩形框在每个类别的概率组成的。一个典型的输出结果如图:

分割Segment
目标检测给出的通常是目标物体的外接矩形框。如果我们希望获得更加准确的轮廓,就需要用到分割任务。分割任务的输出分为两块:
- 检测头Predict:在Detect基础上,增加32个权重Weights,对应32个掩码维度
- 掩码头Mask:将图片分为32个维度,并生成32个掩码图。通常会下采样2次,假如输入图为640 x 640,则mask图为160 x 160。
通过weight和mask,可以更精细的知道每一格(mask一格对应到原图其实就是一块区域)是目标物体的概率,可以更精细的提取物体轮廓:

前处理Preprocess
一个典型的 640 x 640的3通道图片其实就是一组字节数组组成的。每3个字节对应一个像素的rgb3个通道(opencv::Mat是bgr)。每3 x 640个字节(640 个像素)是一行,一共有3 x 640 x 640个字节(640列)。用3维数组表示:
uint8_t image[640][640][3];

我们通常不会在c++中这样定义图片,但理解这个3维数组定义,对我们理解各种切片至关重要!
我们仔细看这3个维度,按照顺序分别是:
- 第一个640:高度Height
- 第二个640:宽度Weight
- 3:通道Channel
所以作为模型的输入数据,我们通常说这个格式叫HWC。但是模型需要的格式是CHW,从逻辑上说我们需要进行通道转换,或者说需要进行变形(想象这是一个3维立方体,其实转换结果就是这个立方体进行了翻转)。
翻转后还有一步归一化,其实就是将原来0-255之间的颜色值,除以256,使其变为0~1之间的浮点数。归一化在模型中非常常见。
预处理后的数据如图:

下一篇开始讲解基于opencv的前处理和分割后处理代码。基于上面的介绍,可知分割是3种任务中最复杂的,所以理解了分割后处理流程,另两个自然就都明白了。
to be continue…
&spm=1001.2101.3001.5002&articleId=148567747&d=1&t=3&u=5192a08cf6f0451f9335eff42bd6d9ec)
353

被折叠的 条评论
为什么被折叠?



