YOLOV1-V2

yolov1

设计思想

YOLO将输入图像分成SxS个格子,若某个物体 Ground truth 的中心位置的坐标落入到某个格子,那么这个格子就负责检测出这个物体

每个单元格预测B个bounding box和其置信度,,以及C个类别概率

  1. bbox信息包括(x,y,w,h),x,y是中心坐标,w,h是宽高,需要注意的是x,y是相对于所在单元格左上角点的偏移比例值,w,h是相对于整张图片的宽高。所以x,y,z,h都在[0,1]之间,
  2. 置信度反映边界框是否含有物体,以及包含预测框的准确性,是 P r ( O b j e c t ) × I O U p r e d t r u t h , 其 中 P r ( O b j e c t ) ∈ { 0 , 1 } Pr(Object) \times IOU^{truth}_{pred}, 其中Pr(Object)\in\{0,1\} Pr(Object)×IOUpredtruth,Pr(Object){0,1}
  3. 类别概率: P r ( c l a s s i ∣ o b j e c t ) ∗ P r ( o b j e c t ) ∗ I O U p r e d t r u t h = P r ( c l a s s i ) ∗ I O U p r e d t r u t h Pr(class_i|object)*Pr(object)*IOU^{truth}_{pred}=Pr(class_i)*IOU^{truth}_{pred} Pr(classiobject)Pr(object)IOUpredtruth=Pr(classi)IOUpredtruth
    总结,SS个单元格需要预测SS(B*5+C)个值

网络设计

参考googlenet,包含24个卷积层和2个全连接层,不过并没有用残差模块,而是用1×1 卷积层+3×3卷积层替代。1×1主要为了降维。原文中Figure3中说到Alternating 1×1 convolutional layers reduce the features space from preceding layers.对于卷积层和全连接层,采用Leaky ReLU激活函数: max(x, 0.1x) 。但是最后一层却采用线性激活函数

缺陷:

  1. 对小目标检测不好,因为每个单元格只预测一组类别概率,如果是小物体,比如一群鸟之类,有多个物体的中心落在了同一个单元格内,但是却只能检测出一个物体。

损失函数

分析:

  1. 最后每个grid输出 20+2*5 =30维,这30维中8维是回归box的坐标,2维是box的confidence,还有20维是类别。8维的坐标误差和20维的分类误差同等重要这显然是很不合理的
  2. 因为图片中,背景很多,而目标很少。会使得分类器直接一股脑分成不含有物体,置信度趋向0,acc也可以刷的很高,这对含有物体的分类是很不利的

解决思路

  1. 增大定位误差权重 λ c o o r d = 5 \lambda coord=5 λcoord=5
  2. 减小背景置信度权重 λ n o o b j = 0.5 \lambda noobj=0.5 λnoobj=0.5
  3. 其余权重都是1
    这是参数说明

    主要分三部分,BBox误差、置信度误差、类别概率误差,与我们设计思想相对应

需要注意的地方:

  1. 训练时,如果该单元格内确实存在目标,那么只选择与ground truth的IOU最大的那个边界框来负责预测该目标,而其它边界框认为不存在目标。
  2. 类别概率误差中,物体是否出现在网格中,物体中心落在该网格才在该网格出现。
  3. 同等对待大小不同的边界框,但是实际上较小的边界框的坐标误差应该要比较大的边界框要更敏感。为了保证这一点,将网络的边界框的宽与高预测改为对其平方根的预测,即预测值变为 ( x , y , w , h ) (x,y,\sqrt{w}, \sqrt{h}) (x,y,w ,h )
  4. 对于不存在对应目标的边界框,其误差项就是只有置信度,坐标项误差是没法计算的。而只有当一个单元格内确实存在目标时,才计算分类误差项,否则该项也是无法计算的。

网络训练

  1. 使用yolo前20个卷积层,接着是平均池化层和全连接层,在imagenet训练
  2. 预训练后,后面 添加权重随机初始化的四个卷积层和两个全连接层。由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。

yolo V2

改进

  1. Batch Norm:
    在yolov2中,每个卷积层后面加入batchnorm层,并且移除dropout层,提高了2%以上的mAP在yolov2中,每个卷积层后面加入batchnorm层,并且移除dropout层,提高了2%以上的mAP
  2. 高分辨率分类器:
    v1中使用224 × 224训练分类器网络,扩大到448用于检测网络。v2将ImageNet以448×448 的分辨率微调最初的分类网络,迭代10 epochs。使mAP增加了近4%(???没有太看懂)v1中使用224 × 224训练分类器网络,扩大到448用于检测网络。v2将ImageNet以448×448 的分辨率微调最初的分类网络,迭代10 epochs。使mAP增加了近4%(???没有太看懂)
  3. anchor box
    v1中直接在卷积层之后使用全连接层预测bbox的坐标。v2借鉴Faster R-CNN的思想预测bbox的偏移.移除了全连接层,并且删掉了一个pooling层使特征的分辨率更大一些.另外调整了网络的输入(448->416)以使得位置坐标是奇数只有一个中心点.这样做是因为想要在特征图中有奇数个位置,只有一个中心单元。目标,尤其是大的目标,往往占据图像的中心,所以最好在正中心拥有单独一个位置来预测这些目标,而不是在中心附近的四个位置。(yolo使用pooling来下采样,有5个size=2,stride=2的max pooling,而卷积层没有降低大小,因此最后的特征是416/(2^ 5)=13).。YOLOv1只能预测98个边界框( 7×7×2 ),而YOLOv2使用anchor boxes之后可以预测上千个边界框( 13×13×num_anchors )检测结果从69.5mAP,81% recall变为69.2 mAP,88% recall.
  4. 维度聚类:
    FastRcnn的anchor box时人为指定的。如果我们使用更好的先验,网络就会学的更好的检测结果。使用kmean进行维度聚类。距离度量用如下公式FastRcnn的anchor box时人为指定的。如果我们使用更好的先验,网络就会学的更好的检测结果。使用kmean进行维度聚类。距离度量用如下公式
    d ( b o x , c e n t r o i d ) = 1 − I O U ( b o x , c e n t r o i d ) d(box,centroid)=1-IOU(box,centroid) d(box,centroid)=1IOU(box,centroid)
  5. 直接位置预测
    前面提到,借鉴fastrcnn的anchorbox,预测相对于anchor box的offset,那么预测框的实际中心位置(x,y),可由预测的偏移值 ( t x , t y ) (t_x,t_y) (tx,ty),anchor box的尺度 ( w a , h a ) (w_a,h_a) (wa,ha)和中心坐标 ( x a , y a ) (x_a,y_a) (xa,ya),得到:前面提到,借鉴fastrcnn的anchorbox,预测相对于anchor box的offset,那么预测框的实际中心位置(x,y),可由预测的偏移值 ( t x , t y ) (t_x,t_y) (tx,ty),anchor box的尺度 ( w a , h a ) (w_a,h_a) (wa,ha)和中心坐标 ( x a , y a ) (x_a,y_a) (xa,ya),得到
    x = ( t x ∗ w a ) − x a x=(t_x * w_a)-x_a x=(txwa)xa
    y = ( t y ∗ h a ) − y a y=(t_y*h_a)-y_a y=(tyha)ya
    没有看懂公式
    上面两个式子是没有约束的,例如,预测 t x = 1 t_x = 1 tx=1会使该框向右移动锚框的宽度,而预测 t x = − 1 t_x = -1 tx=1会将其向左移动相同的量。所以任何锚框都可以在图像中的任何一点结束,而不管这个框是在哪个位置预测的。随机初始化模型需要很长时间才能稳定以预测合理的偏移。
    yolov2 没有预测偏移值,而是继承v1的做法,预测相对于单元格左上角点的位置坐标,这样,真实值被限制在0~1之间。v2使用sigmoid函数使得偏移值限制在这个范围内,网络每个预测框依旧预测出5个值 t x , t y , t w , t h , t o t_x,t_y,t_w,t_h,t_o tx,ty,tw,th,to,单元格左上角坐标为 ( c x , c y ) (c_x,c_y) (cx,cy),那么预测对应于

    其中 ( c x , x y ) (c_x, x_y) (cx,xy) 为cell的左上角坐标,如图5所示,在计算时每个cell的尺度为1,所以当前cell的左上角坐标为 (1,1) 。由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多。而 p w p_w pw p h p_h ph 是先验框的宽度与长度,前面说过它们的值也是相对于特征图大小的,在特征图中每个cell的长和宽均为1。这里记特征图的大小为 (W, H) (在文中是 (13, 13) ),这样我们可以将边界框相对于整张图片的位置和大小计算出来(4个值均在0和1之间):
    b x = ( σ ( t x ) + c x ) / W b_x=(\sigma (t_x) +c_x)/W bx=(σ(tx)+cx)/W
    b y = ( σ ( t y ) + c y ) / H b_y=(\sigma (t_y)+c_y)/H by=(σ(ty)+cy)/H
    b w = p w e t w / W b_w=p_w e^{t_w} / W bw=pwetw/W
    b h = p h e t h / H b_h=p_h e^{t_h}/H bh=pheth/H
    如果再将上面的4个值分别乘以图片的宽度和长度(像素点值)就可以得到边界框的最终位置和大小了。这就是YOLOv2边界框的整个解码过程。约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值提升了约5%。
    具体可看下图
  6. 细粒度功能
    YOLOv2的输入图片大小为 416×416 ,经过5次maxpooling之后得到 13×13 大小的特征图,并以此特征图采用卷积做预测。 13×13 大小的特征图对检测大物体是足够了,但是对于小物体还需要更精细的特征图(Fine-Grained Features)。因此SSD使用了多尺度的特征图来分别检测不同大小的物体,前面更精细的特征图可以用来预测小物体。YOLOv2提出了一种passthrough层来利用更精细的特征图。YOLOv2所利用的Fine-Grained Features是 26×26 大小的特征图(最后一个maxpooling层的输入),对于Darknet-19模型来说就是大小为 26×26×512 的特征图。passthrough层与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个 2×2 的局部区域,然后将其转化为channel维度,对于 26×26×512 的特征图,经passthrough层处理之后就变成了 13×13×2048 的新特征图(特征图大小降低4倍,而channles增加4倍,图6为一个实例),这样就可以与后面的 13×13×1024 特征图连接在一起形成 13×13×3072 大小的特征图,然后在此特征图基础上卷积做预测。下图是passthrough实例。此方法使得模型的性能获得了1%的提升
    在这里插入图片描述
  7. 多尺度训练
    和YOLOv1训练时网络输入的图像尺寸固定不变不同,YOLOv2(在cfg文件中random=1时)每隔几次迭代后就会微调网络的输入尺寸。训练时每迭代10次,就会随机选择新的输入图像尺寸。因为YOLOv2的网络使用的downsamples倍率为32,所以使用32的倍数调整输入图像尺寸{320,352,…,608}。训练使用的最小的图像尺寸为320 x 320,最大的图像尺寸为608 x 608。 这使得网络可以适应多种不同尺度的输入.

网络设计

YOLOv2采用了一个新的基础模型(特征提取器),称为Darknet-19,包括19个卷积层和5个maxpooling层,Darknet-19与VGG16模型设计原则是一致的,主要采用 3x3 卷积,采用 2x2 的maxpooling层之后,特征图维度降低2倍,而同时将特征图的channles增加两倍。按照Network in Network(NIN)的方法,我们使用全局平均池化来做预测已看懂,并使用1×1滤波器来压缩3×3卷积的特征表示。使用批量归一化来稳定训练,加速收敛,并规范模型。
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我可以回答这个问题。以下是一个使用TensorRT加速YOLOv3-tiny的Python程序的示例: ```python import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2 # Load the TensorRT engine engine_file_path = 'yolov3-tiny.engine' with open(engine_file_path, 'rb') as f: engine_data = f.read() engine = trt.lite.Engine(None, engine_data) # Create a TensorRT context context = engine.create_execution_context() # Allocate memory for input and output tensors input_shape = (3, 416, 416) input_size = np.product(input_shape) * np.dtype(np.float32).itemsize input_buf = cuda.mem_alloc(input_size) output_shape = (1, 255, 13, 13) output_size = np.product(output_shape) * np.dtype(np.float32).itemsize output_buf = cuda.mem_alloc(output_size) # Load an image and preprocess it image_file_path = 'image.jpg' image = cv2.imread(image_file_path) image = cv2.resize(image, (416, 416)) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = image.transpose((2, 0, 1)) image = image.astype(np.float32) / 255.0 image = np.ascontiguousarray(image) # Copy the input tensor to the GPU cuda.memcpy_htod(input_buf, image) # Run inference context.execute_v2(bindings=[int(input_buf), int(output_buf)]) # Copy the output tensor from the GPU output = np.empty(output_shape, dtype=np.float32) cuda.memcpy_dtoh(output, output_buf) # Postprocess the output tensor output = output.reshape((1, 3, 85, 13, 13)) boxes = output[:, :2, :, :, :] * 32.0 confidences = output[:, 2:3, :, :, :] class_probs = output[:, 3:, :, :, :] scores = confidences * class_probs scores = scores.reshape((1, 255, -1)) scores = scores[0] scores = scores[scores[:, 0] > 0.5] boxes = boxes.reshape((1, 2, -1)) boxes = boxes[0] boxes = boxes[:, :, boxes[0, :, 0] > 0.5] boxes = boxes.transpose((1, 0, 2)) boxes = boxes.reshape((-1, 4)) boxes[:, 0] -= boxes[:, 2] / 2 boxes[:, 1] -= boxes[:, 3] / 2 boxes[:, 2] += boxes[:, 0] boxes[:, 3] += boxes[:, 1] boxes = boxes.astype(np.int32) scores = scores[scores[:, 0].argsort()[::-1]] scores = scores[:100] boxes = boxes[:100] for box, score in zip(boxes, scores): x1, y1, x2, y2 = box label = np.argmax(score[1:]) + 1 confidence = score[label] print(f'Label: {label}, Confidence: {confidence}, Box: ({x1}, {y1}, {x2}, {y2})') ``` 这个程序使用TensorRT加速了YOLOv3-tiny的推理过程,可以在GPU上快速地检测图像中的物体。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值