YOLOV3
YOLO3主要的改进有:调整了网络结构;利用多尺度特征进行对象检测;对象分类用Logistic取代了softmax。
新的网络结构Darknet -53
darknet-53借用了resnet的思想,在网络中加入了残差模块,这样有利于解决深层次网络的梯度问题,每个残差模块由两个卷积层和一个shortcut connections,
1,2,8,8,4代表有几个重复的残差模块,整个v3结构里面,没有池化层和全连接层,网络的下采样是通过设置卷积的stride为2来达到的,每当通过这个卷积层之后
图像的尺寸就会减小到一半。而每个卷积层的实现又是包含 卷积+BN+Leaky relu ,每个残差模块之后又要加上一个zero padding,具体实现可以参考下面的一张图。
具体的全部模型结构可以从这个网站的工具进行可视化分析:
https://lutzroeder.github.io/netron/
从Yolo的官网上下载yolov3的权重文件,然后通过官网上的指导转化为H5文件,然后可以再这个浏览器工具里直接看yolov3的每一层是如何分布的;类似下边截图是一部分网络(最后的拼接部分);
论文中所给的大致结果如下,由卷积结构和残差模块组成;
多尺度检测:
对于多尺度检测来说,采用多个尺度进行预测,具体形式是在网络预测的最后某些层进行上采样拼接的操作来达到;对于分辨率对预测的影响如下解释:
分辨率信息直接反映的就是构成object的像素的数量。一个object,像素数量越多,它对object的细节表现就越丰富越具体,也就是说分辨率信息越丰富。这也就是为什么大尺度feature map提供的是分辨率信息了。语义信息在目标检测中指的是让object区分于背景的信息,即语义信息是让你知道这个是object,其余是背景。在不同类别中语义信息并不需要很多细节信息,分辨率信息大,反而会降低语义信息,因此小尺度feature map在提供必要的分辨率信息下语义信息会提供的更好。(而对于小目标,小尺度feature map无法提供必要的分辨率信息,所以还需结合大尺度的feature map)
YOLO3更进一步采用了3个不同尺度的特征图来进行对象检测。能够检测的到更加细粒度的特征。
网络的最终输出有3个尺度分别为1/32,1/16,1/8;
在第79层之后经过几个卷积操作得到的是1/32 (13*13) 的预测结果,下采样倍数高,这里特征图的感受野比较大,因此适合检测图像中尺寸比较大的对象。
然后这个结果通过上采样与第61层的结果进行concat,再经过几个卷积操作得到1/16的预测结果;它具有中等尺度的感受野,适合检测中等尺度的对象。
91层的结果经过上采样之后在于第36层的结果进行concat,经过几个卷积操作之后得到的是1/8的结果,它的感受野最小,适合检测小尺寸的对象。
concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。
logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),(用于NMS),即这块位置是目标的可能性有多大。
公式一:
yolo_v3只会对1个prior进行操作,也就是那个最佳prior。而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。
预测对象类别时不使用softmax,改成使用logistic的输出进行预测。这样能够支持多标签对象(比如一个人有Woman 和 Person两个标签)。
YOLO的LOSS函数:
1 # K.binary_crossentropy is helpful to avoid exp overflow.
2 xy_loss = object_mask * box_loss_scale * K.binary_crossentropy(raw_true_xy, raw_pred[...,0:2], from_logits=True)
3 wh_loss = object_mask * box_loss_scale * 0.5 * K.square(raw_true_wh-raw_pred[...,2:4])
4 confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True)+ 5 (1-object_mask) * K.binary_crossentropy(object_mask, raw_pred[...,4:5], from_logits=True) * ignore_mask
6 class_loss = object_mask * K.binary_crossentropy(true_class_probs, raw_pred[...,5:], from_logits=True)
7
8 xy_loss = K.sum(xy_loss) / mf
9 wh_loss = K.sum(wh_loss) / mf
10 confidence_loss = K.sum(confidence_loss) / mf
11 class_loss = K.sum(class_loss) / mf
12 loss += xy_loss + wh_loss + confidence_loss + class_loss
13 if print_loss:
14 loss = tf.Print(loss, [loss, xy_loss, wh_loss, confidence_loss, class_loss, K.sum(ignore_mask)], message=‘loss: ‘)
15 return loss
yolov3再keras中定义的Loss函数如上,基本可以看出,对于回归预测的部分是采用多个mse均方差相加来进行的(类似于上边所提到的v1中的Loss函数),对于分类部分和置信度是采用K.binary_crossentropy来进行的,最后把两种Loss相加得出最终的loss
整体来看Yolov3的输入与输出形式如下:
输入416*416*3的图像,通过darknet网络得到三种不同尺度的预测结果,每个尺度都对应N个通道,包含着预测的信息;
每个网格每个尺寸的anchors的预测结果。
原文:https://www.cnblogs.com/ywheunji/p/10809695.html