一、YOLO-V3论文总结

论文导读

YOLO-V1

1、基于深度神经网络的目标检测:

双阶段(two-stage):第一级网络用于候选区提取,第二级网络对提取的候选区域进行分类和精确坐标回归,例如RCNN系列;

单阶段(one-stage):摒弃了提取候选区这一步,只用一级网络就能完成分类和回归两个任务

2、YOLO-V1原理

  • 一次性输出所检测到的目标,包括类别和位置;

  • 只要求这个物体的中心在某个grid(网格);

  • 每个grid都预测出B个bounding boxs,这个bounding boxs有5个量,分别是物体的中心位置(x,y)和它的宽高(w,h),以及这次预测的置信度;

  • 每个框还要负责预测这个框中的物体是什么类别;

  • 如果有SxS个框,每个框的bounding box为B,分类器可以识别C种不同物体,那么整个ground truth长度为:S x S x(B x 5 + C)

3、Bounding Boxs细节

如果我们不对x、y、w、h做任何处理,那么输出的坐标位置可以为任意实数,这样模型在大小目标上泛化能力会有很大差异,为了解决泛化问题,先对xywh做归一化处理:

  • 让真实的x除以grid的宽度
  • 让真实的y除以grid的高度
  • w除以整张图片的宽度
  • h除以整张图片的高度

结论:经过这样处理,xywh取值范围都在0~1,模型能够实现大小目标的泛化能力;

4、Confidence置信度

计算公式为:C = Pr(obj) * IOUtruthpred

IOU是预测bounding box和真实物体的一个交并比,Pr是grid有物体的概率(1或者0)

5、损失函数:

在这里插入图片描述

6、缺点

  • 一个grid只能识别一种物体;
  • Bounding box的预测准确度不如R-CNN;

YOLO-V2

对比Yolo-V1改进点:

1、每个卷积层加入BN层,总体mAP提升2%,并且去除Dropout;

2、采用高分辨率预训练,在ImageNet数据集采用448x448的大小进行预训练,相比V1的224x224大大提升,总体mAP提升4%;

3、Anchor Box替换全连接层,不对预测框的宽高的绝对值进行预测,而是预测与Anchor框的偏差;训练时,最接近ground truth的框产生loss,其余框不计算loss;移除了最后两层全连接层,降低了计算量;

4、相对于左上角的格点坐标预测偏移量;

5、细粒度特征,加入passthrough层,将26x26x1特征图卷积后变成13x13x4的特征图:

在这里插入图片描述

6、多尺度训练,V2中只有卷积层与池化层,对于网络的输入没有限制,只需输入的特征图尺寸为32的倍数即可,在训练10个batch后,将特征图大小变换;

论文概要

YOLO-V3

主干网络:DarkNet53(相对于ResNet-101,FPS较高)

DarkNet53网络结构解析:

1、只有卷积层:通过调节卷积步长控制输出特征图的尺寸,对输入图片没有特别限制;

2、金字塔特征图:小尺寸特征图检测大尺寸物体,大尺寸特征图检测小尺寸物体;

3、借鉴ResNet:跳连结构的概念;

4、借鉴DenseNet:将特征图按通道维度直接进行拼接;

特征图细节:

每个特征图的每个格子中,都配置3个不同的先验框,最后得到三个特征图,暂且reshape为8x8x3x85、16x16x3x85、32x32x3x85(有80个类别,COCO数据集有80类);

先验框:沿用V2中先验框的技巧,并且使用K-means对数据中的标签进行聚类,得到类别中心的9个框,随后通过先验框与输出特征图,就可以得到检测框x,y,w,h;

训练策略:

预测框:正例(positive)、负例(negative)、忽略样例(ignore);

正例:取一个ground truth,与4032个框全部计算IOU,最大的为正例;正例产生置信度Loss、检测框Loss、类别Loss;

负例:与全部ground truth的IOU都小于阈值(0.5),则为负例,只有置信度产生Loss,置信度标签为0;

忽略样例:与任意一个ground truth的IOU大于阈值(0.5),不产生任何Loss;

模型结构图:

在这里插入图片描述

YOLO-V4

主要是在训练上进行改进,对算法方面的改进没有;

改进创新点:

1、马赛克数据增强;(拼接和马赛克两种形式)

2、自对抗训练:对图像做改变扰动,然后在这个图像上训练;

3、改进attention方式,并加入网络中;

4、Cross mini-batch Normal:比如多个batch进行normalization;

论文总结

  • YOLO-V3

    关键点:

    1、特征图解码

    2、快速高效的检测方式

    创新点:

    1、结合检测与识别为一体

    2、3个尺度的特征图

    3、置信度和类别解码

  • YOLO-V4

    关键点:

    1、平衡正负样本

    2、注意力机制

    3、数据增强

论文代码

数据处理

augmentations.py和transforms.py

预处理库:imgaug

说明文档:https://imgaug.readthedocs.io/en/latest/index.html

1、全部处理:

AUGMENTATION_TRANSFORMS = transforms.Compose([
    AbsoluteLabels(),   # 标签对齐
    DefaultAug(),       # 一些基本增强
    PadSquare(),        # padding成正方形
    RelativeLabels(),   # 标签标准化
    ToTensor(),         # 转换成Tensor类型
])

2、将图像padding成正方形(方法一)

import imgaug.augmenters as iaa
def __init__(self, ):
	self.augmentations = iaa.Sequential([
	iaa.PadToAspectRatio(1.0,position="center-center").to_deterministic()])

方法二:

def pad_to_square(img, pad_value):
    c, h, w = img.shape
    dim_diff = np.abs(h - w)
    # (upper / left) padding and (lower / right) padding
    pad1, pad2 = dim_diff // 2, dim_diff - dim_diff // 2
    # Determine padding
    pad = (0, 0, pad1, pad2) if h <= w else (pad1, pad2, 0, 0)
    # Add padding
    img = F.pad(img, pad, "constant", value=pad_value)

    return img, pad

3、自定义初始化权重的函数

def weights_init_normal(m):
    classname = m.__class__.__name__
    if classname.find("Conv") != -1:
        nn.init.normal_(m.weight.data, 0.0, 0.02)
    elif classname.find("BatchNorm2d") != -1:
        nn.init.normal_(m.weight.data, 1.0, 0.02)
        nn.init.constant_(m.bias.data, 0.0)     # 偏置初始化为0

4、将中心坐标和宽高,转化为左上角和右下角坐标

def xywh2xyxy(x):
    y = x.new(x.shape)
    y[..., 0] = x[..., 0] - x[..., 2] / 2
    y[..., 1] = x[..., 1] - x[..., 3] / 2
    y[..., 2] = x[..., 0] + x[..., 2] / 2
    y[..., 3] = x[..., 1] + x[..., 3] / 2
    return y

指标计算

1、IOU的计算

第一种方法:有x1y1x2y2的坐标值

def bbox_iou(box1, box2, x1y1x2y2=True):
    """
    Returns the IoU of two bounding boxes
    """
    if not x1y1x2y2:
        # Transform from center and width to exact coordinates
        b1_x1, b1_x2 = box1[:, 0] - box1[:, 2] / 2, box1[:, 0] + box1[:, 2] / 2
        b1_y1, b1_y2 = box1[:, 1] - box1[:, 3] / 2, box1[:, 1] + box1[:, 3] / 2
        b2_x1, b2_x2 = box2[:, 0] - box2[:, 2] / 2, box2[:, 0] + box2[:, 2] / 2
        b2_y1, b2_y2 = box2[:, 1] - box2[:, 3] / 2, box2[:, 1] + box2[:, 3] / 2
    else:
        # Get the coordinates of bounding boxes
        b1_x1, b1_y1, b1_x2, b1_y2 = \
            box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3]
        b2_x1, b2_y1, b2_x2, b2_y2 = \
            box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3]

    # get the corrdinates of the intersection rectangle
    inter_rect_x1 = torch.max(b1_x1, b2_x1)
    inter_rect_y1 = torch.max(b1_y1, b2_y1)
    inter_rect_x2 = torch.min(b1_x2, b2_x2)
    inter_rect_y2 = torch.min(b1_y2, b2_y2)
    # 上面得到两个box重叠部分的左上和右下

    # Intersection area     得到重叠部分面积
    inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1 + 1, min=0) * torch.clamp(
        inter_rect_y2 - inter_rect_y1 + 1, min=0
    )
    # Union Area        得到各自部分的妙计
    b1_area = (b1_x2 - b1_x1 + 1) * (b1_y2 - b1_y1 + 1)
    b2_area = (b2_x2 - b2_x1 + 1) * (b2_y2 - b2_y1 + 1)

    # 计算IOU
    iou = inter_area / (b1_area + b2_area - inter_area + 1e-16)

    return iou

第二种方法:只有两个box

def box_iou(box1, box2):
    def box_area(box):
    # box = 4xn
    return (box[2] - box[0]) * (box[3] - box[1])

    # 计算出两个box的面积
    area1 = box_area(box1.T)
    area2 = box_area(box2.T)

    # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2)     计算重叠部分面积,没有弄懂
    inter = (torch.min(box1[:, None, 2:], box2[:, 2:]) -
             torch.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2)
    # iou = inter / (area1 + area2 - inter)
    return inter / (area1[:, None] + area2 - inter)

总结:模型层的构造在yolov3.cfg中,配置文件写明了一些参数和模型的构造,在代码中只需要读取配置文件并做一些简单处理即可;还有NMS和训练的一些技巧就不在这做说明了,之后会更新一些细节方面的实操,包括训练自己的数据;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值