今天突发奇想,准备一个总结系列,以备面试只需,嘿嘿,忘了就回来看看,以框架流程为主,不涉及细节、
点云
-
pointnet
代码仓库
https://github.com/yanx27/Pointnet_Pointnet2_pytorch
参考博客
最远点采样(Farthest Point Sampling)介绍
【3D计算机视觉】PointNet++的pytorch实现代码阅读
论文阅读笔记 | 三维目标检测——PointNet++
论文阅读笔记 | 三维目标检测——PointNet
PointNet++详解(一):数据增强方法
一文搞懂PointNet全家桶——强势的点云处理神经网络
3D点云深度学习PointNet源码解析——数据预处理
【3D计算机视觉】从PointNet到PointNet++理论及pytorch代码
【三维目标分类】PointNet++详解(一)
-
数据
pointnet的工具在 provider.py 中
随机顺序 shuffle_data() shuffle_points()
随机旋转 rotate_perturbation_point_cloud_with_normal()
随机噪声 jitter_point_cloud()
随机平移 shift_point_cloud()
随机缩放 random_scale_point_cloud()
随机丢弃 random_point_dropout() -
模型
具体来说,对于每一个N × 3 N\times 3N×3的点云输入,网络先通过一个T-Net将其在空间上对齐(旋转到正面),再通过MLP将其映射到64维的空间上,再进行对齐,最后映射到1024维的空间上。这时对于每一个点,都有一个1024维的向量表征,而这样的向量表征对于一个3维的点云明显是冗余的,因此这个时候引入最大池化操作,将1024维所有通道上都只保留最大的那一个,这样得到的1 × 1024 的向量就是N 个点云的全局特征。1.输入为一帧的全部点云数据的集合,表示为一个nx3的2d tensor,其中n代表点云数量,3对应xyz坐标。(输入的维度是 nx3 是二维的)
2.输入数据先通过和一个T-Net学习到的转换矩阵相乘来对齐,保证了模型的对特定空间转换的不变性。(T-Net是针对点云旋转不变性设计的网络,目的是将点云旋转到合适的位置)
3.通过多次mlp对各点云数据进行特征提取后,再用一个T-Net对特征进行对齐。(用mlp提取特征是为了将点云升维(到 nx1024),以便后面进行max-pooling,不至于最终特征很少)
4.在特征的各个维度上执行maxpooling操作来得到最终的全局特征。
5.对分类任务,将全局特征通过mlp来预测最后的分类分数;对分割任务,将全局特征和之前学习到的各点云的局部特征进行串联(concat),再通过mlp得到每个数据点的分类结果。
-
-
pointnet++
pointnet++取消了T-Net网络对齐,在点云数据的处理上提出了局部划分(为了获取局部特征)。因为考虑稀疏问题,提出了MSG和MRG(代码似乎没有MRG)
-
数据
pointnet++中,没有了T-Net网络做转换对齐什么的,他直接在全局的数据上进行局部划分,然后在每个局部数据上进行pointnet提取特征(pointnet其实就是一个特征提取器了,里面就是卷积了)。
1、sample_and_group() 局部划分,如名字一样,先sample在group。
2、sample_and_group() 实现步骤- 先用farthest_point_sample函数实现最远点采样FPS得到采样点的索引,再通过index_points将这些点的从原始点中挑出来,作为new_xyz
- 利用query_ball_point和index_points将原始点云通过new_xyz 作为中心分为npoint个球形区域其中每个区域有nsample个采样点
- 每个区域的点减去区域的中心值
- 如果每个点上面有新的特征的维度,则用新的特征与旧的特征拼接,否则直接返回旧的特征
-
模型
pointnet++所用的工具在pointnet2_util.py中
数据在做完sample_and_group后,就送到网络去提取特征了。
MSG体现在哪呢,他在局部划分时,有一个半径参数,就是取不同的半径,最后将这些半径不一样的特征拼接在一起。
在分类里没有拼接,在分割里是做了拼接的(cat)
pointnet++的PointNetSetAbstractionMsg层里包括了局部划分和特征提取
pointnet++中的PointNetFeaturePropagation层的实现主要通过线性差值与MLP堆叠完成。
-
pointnet系列就算完结了。
目标检测
参考资料
YOLO v2详细解读
同济自豪兄的b站视频
-
YOLOv1
这是经典中的经典了,总有新的博客出现,而且讲的越来越好了,以往的疑惑都解开了,就总结一个YOLO系列!yolo的预测和训练要分开讲、
-
预测
- 从论文中可知,作者的思路
- 图像被分成7x7个网格,在这49个网格中来预测,每个网格预测两个bounding boxes,和所有类别的条件概率Class(注意是条件概率,网格包含物体的条件下)。
- 每个bounding boxes中包含了(x,y)(中心点坐标),(w,h)(bounding boxes宽高),conf(是否包含物体的概率)
- 最后网络的输出是一组7x7x30(30=2x5+num_class)的特征,然后在进行后处理+nms等。
- 流程:图片送进来,经过卷积网络输出 7x7x30 的特征,然后开始decode,,将bounding box的conf乘上类别条件概率C得到类别的全概率,经过全概率阈值筛选排序后进入nms筛选,最后输出结果。
- 疑问:为什么conf要乘C,为了加速?
- 疑问:为什么类别概率要用条件概率,默认每个bounding box都有物体,全送到nms里不行么?
-
训练
- 将图片送入网络,和预测一样得到 7x7x30 的特征。通过损失函数来缩小与标注的差距。
- yolov1的损失计算思路可分为,在包含真值的grid中计算损失和不包含真值的grid中计算损失。(也就是所谓的真值的中心点在哪个grid,就由哪个grid负责预测该真值)
S²表示遍历所有的grid cell,B表示遍历所有的预测框;
对于每一个GTbox只分配一个正样本(预测框),也就是与它IOU最大的那个预测框,其余为负样本;
正样本有定位损失、类别损失和置信度损失;负样本只有置信度损失。
正样本的置信度标签值为预测框与标注框(ground truth)的IOU;
YOLOV1的类别归grid cell管(一个grid cell负责预测一个类别);
YOLOV2/3的类别归anchor管(一个anchor负责预测一个类别);
- 上图中的1、2、3、5行是包含物体的损失函数,第4行是不包含物体的损失函数
- 1行是包含物体的 bounding box 的 x,y坐标损失
- 2行是包含物体 bounding box 的w,h损失
- 3行是包含物体的 bounding box 的conf损失
- 4行是不包含物体的 bounding box 的conf损失
- 5行是包含物体的 grid 的类别概率
- 三个 λ 是包含物体和不包含物体的权重(正样本和负样本权重)
- 训练阶段是不进行 nms 的
- 疑问:对于yolov1的该 grid 的 bounding box 会不会飘移到其他 grid 中。
- 我认为是这样,首先yolov1是bx中心点对 grid 中心点的偏移量回归(yolov2 是对 anchor 的偏移量回归),其次,网络最后的 sigmod 层使输出在0-1之间,并且对坐标进行了 1/grid_number ,结合代码可知,bounding box 的中心点是不会到其他grid的。
-
nms
-
非极大抑制 在一堆根据置信度排序的框中,将最大置信度的框与其他框比较IOU,来筛选最终留下的框。
1.从最大概率矩形框A开始,分别判断其他矩形框与A的重叠度IOU是否大于某个设定的阈值;2.假设B、C矩形框的重叠度超过阈值,那么就扔掉他们;并标记第一个矩形框A,这个是我们保留下来的。
3.从剩下的矩形框D、E、F中,选择概率最大的D,然后判断E、F与D的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记D是我们保留下来的第二个矩形框。
4.重复这个过程,找到所有被保留下来的矩形框。
-
-
-
YOLOv2
-
在yolov1基础上增加了
1.Batch Normalization BN层
YOLO v2中在每个卷积层后加Batch Normalization(BN)层,去掉了dropout层。 Batch Normalization层可以起到一定的正则化效果,能提升模型收敛速度,防止模型过拟合。YOLO v2通过使用BN层使得mAP提高了2%。2.High Resolution Classifier 高分辨率分类器(就是用分辨率更高的图训练)
目前的大部分检测模型都会使用主流分类网络(如vgg、resnet)在ImageNet上的预训练模型作为特征提取器,而这些分类网络大部分都是以小于256 × 256 256×256256×256的图片作为输入进行训练的,低分辨率会影响模型检测能力。 YOLO v2将输入图片的分辨率提升448 × 448 448×448448×448,为了使网络适应新的分辨率,YOLO v2先在ImageNet上以448 × 448 448×448448×448的分辨率对网络进行10个epoch的微调,让网络适应高分辨率的输入。通过使用高分辨率的输入,YOLO v2的mAP提升了约4%。3.Anchor 锚框
YOLO v2去掉了 YOLO v1中的全连接层,使用Anchor Boxes,同时为了得到更高分辨率的特征图, YOLO v2还去掉了一个池化层。由于图片中的物体都倾向于出现在图片的中心位置,若特征图恰好有一个中心位置,利用这个中心位置预测中心点落入该位置的物体,对这些物体的检测会更容易。所以总希望得到的特征图的宽高都为奇数。 YOLO v2通过缩减网络,使用416 × 416 的输入,模型下采样的总步长为32,最后得到13 × 13 的特征图,然后对13 × 13 的特征图的每个cell预测 5 个bounding boxes,分别预测了对每个anchor box的位置信息偏移量、置信度和一套分类概率值。4.Dimension Cluster 聚类选择anchor
YOLO v2采用k-means聚类算法对训练集中的边界框做了聚类分析,选用boxes之间的IOU值作为聚类指标。综合考虑模型复杂度和召回率,最终选择5 55个聚类中心,得到5 55个先验框,发现其中中扁长的框较少,而瘦高的框更多,更符合行人特征。通过对比实验,发现用聚类分析得到的先验框比手动选择的先验框有更高的平均IOU值,这使得模型更容易训练学习。5.Direct location prediction 绝对位置预测
YOLOv2沿用 YOLOv1的方法,根据所在网格单元的位置来预测坐标,则Ground Truth的值介于0到1之间。
网络中将得到的网络预测结果再输入sigmoid函数中,让输出结果介于0到1之间。
设一个网格相对于图片左上角的偏移量是c x , c y 。先验框的宽度和高度分别是p w 和 p h ,
则预测的边界框相对于特征图的中心坐标( b x , b y ) 和宽高b w 、 b h 的计算公式如下图所示。
-
-
这里需要注意的是,网络的输出由五个预测框组成,每个预测框包含tx,ty,tw,th,conf,class,和上图中的tx,ty,tw,th对应。yolov2没有直接对预测框进行预测,它预测的是相对anchor的偏移量,所以还需要anchor的pw,ph才能得到。anchor是没有x,y,的因为cx,cy可以根据归一化和ceil算出来。
6.Fine-Grained Features 整合细粒度特征多尺度训练(Passthrough层,不同层的特征拼接)
YOLO v2借鉴SSD使用多尺度的特征图做检测,提出pass through层将高分辨率的特征图与低分辨率的特征图联系在一起,从而实现多尺度检测。 YOLO v2提取Darknet-19最后一个max pool层的输入,得到26 × 26 × 512的特征图。经过1 × 1 × 64的卷积以降低特征图的维度,得到26 × 26 × 64的特征图,然后经过pass through层的处理变成 13 x 13 x 256 的特征图(抽取原特征图每个2x2的局部区域组成新的channel,即原特征图大小降低4倍,channel增加4倍),再与13 × 13 × 1024大小的特征图连接,变成13 × 13 × 1280的特征图,最后在这些特征图上做预测。使用Fine-Grained Features, YOLO v2的性能提升了1%.passthroug具体是怎么1拆4的呢?并不是简单的“两刀切4块”,而是在每个2 × 2 2×22×2的小区域上都选择左上角块,具体看下图。
7.Multi-Scale Training 多尺度训练(用不同大小的输入训练)
cpp YOLO v2中使用的Darknet-19网络结构中只有卷积层和池化层,所以其对输入图片的大小没有限制。 YOLO v2采用多尺度输入的方式训练,在训练过程中每隔10个batches,重新随机选择输入图片的尺寸, 由于Darknet-19下采样总步长为32,输入图片的尺寸一般选择32 3232的倍数{320,352,…,608}。
-
YOLOv3/v4/v5
我写不出来,还是看博客吧,博主们写的很好~
参考博客:
深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解
深入浅出Yolo系列之Yolov5核心基础知识完整讲解 -
YOLOv6
-