yolov3检测块的解析与实现

在yolo v3模型中,检测部分的模型是由yolo检测块、yolo检测层以及上采样函数组成。
yolo检测块负责进一步提取特征;
检测层负责将最终特征转化为bbox attrs单元
bbox_attrs单元 所有是可能的含有目标的预测框 例如特征图大小为1313 每个特征点预测3个anchor 则bbox_attrs单元就会有1313*3个
上采样函数的作用是将高层特征和底层特征相组合,作为yolo预测的输入
yolov3的整体前向传播框架图如下图所示,我画的是横着的图,发现这里放不下所以放了竖着的图,根据下面的图,依次实现下面的所有模块。

一、yolov3检测块

1、yolov3检测块网络结构

2、yolov3检测块实现

def _yolo_block(inputs, filters):''':param inputs: 输入  类型tensor  形状 [batch, height_in, width_in, channels].:param filters: 卷积核个数 类型 int:return:  route = conv_1x1_1_f->conv_3x3_1_2f->conv_1x1_1_f->conv_3x3_2_2f->conv_1x1_1_f 用于配合一下尺度的特征及一起计算inputs = conv_1x1_1_f->conv_3x3_1_2f->conv_1x1_1_f->conv_3x3_2_2f->conv_1x1_1_f->conv_3x3_1_2f 用于输入检测层进行bbox_attrs单元的计算'''inputs = slim.conv2d(inputs, filters, 1, stride=1, padding='SAME')  # 正常卷积inputs = slim.conv2d(inputs, filters * 2, 3, stride=1, padding='SAME')  # 正常卷积inputs = slim.conv2d(inputs, filters, 1, stride=1, padding='SAME')  # 正常卷积inputs = slim.conv2d(inputs, filters * 2, 3, stride=1, padding='SAME')  # 正常卷积inputs = slim.conv2d(inputs, filters, 1, stride=1, padding='SAME')  # 正常卷积route = inputsinputs = slim.conv2d(inputs, filters * 2, 3, stride=1, padding='SAME')  # 正常卷积return route, inputs

二、yolov3检测层

yolo检测层是yolo中最重要的一层也是最难处理的一层

1、yolo检测层网络结构

2、中心坐标的中心点坐标理解

2.1输入特征图的像素坐标点矩阵创建示意图

2.2 网络预测的是中心坐标的中心点坐标意义

网络预测的是相对于输入特征图的每个像素点坐标的一个偏置值,预测偏置值+对应特征图的对应像素点坐标得到的是相对于统一图的缩放的中心点坐标,再乘上输入特征图相对于统一图的缩放倍数才会得到相对于统一图的中心点坐标

3、anchor的宽高预测

anchor的宽高预测在上面yolo检测层结构图中已经说了 不想在说一次了 不过理解这个东西是很重要的
只要知道网络预测的是标签公式的结果就可以了,而且反解后的结果直接就是相对于统一图的anchor的宽高了。

4、yolo检测层的实现

# 特征转化为预测框
# 检测层 将神经网络的输出转化为真实预测输出
def _detection_layer(inputs, num_classes, anchors, img_size, data_format):''':param inputs:  输入  类型tensor  形状 [batch, height_in, width_in, channels].:param num_classes: 分类个数 类型int:param anchors: 每个特征点对应的anchors个数  类型 list:param img_size: 原始图片大侠 类型 list  [416,416]:param data_format: 未使用:return:num_anchors * (5 + num_classes)中 5 代表 x, y, w, h,and confidence。其中confidence就是预测的bounding box和ground truth box的IOU值(应该是分类可能的概率值)num_anchors 每个特征图像素点对应的anchor数量num_classes 分类数'''print(inputs.get_shape())   # 获取输入形状(1, 13, 13, 1024)或(1, 26, 26, 512)或者(1, 52, 52, 256)num_anchors = len(anchors)  # 候选框个数# 最后一层卷积,没有激活函数,输出特征图通道数为 num_anchors * (5 + num_classes) 即对特征进行预测# 每个bbox_attrs都有一个长度为(5 + num_classes) 的预测向量# predictions 形状为[1, 13, 13, 24]或者[1, 26, 26, 24]或者[1, 52, 52, 24]predictions = slim.conv2d(inputs, num_anchors * (5 + num_classes), 1, stride=1, normalizer_fn=None,activation_fn=None, biases_initializer=tf.zeros_initializer())# 获取 特征图预测卷积后 的形状shape = predictions.get_shape().as_list()print("shape", shape)  # 三个尺度的形状分别为:[1, 13, 13, 3*(5+c)]或[1, 26, 26, 3*(5+c)]或[1, 52, 52, 3*(5+c)]grid_size = shape[1:3]  # 取 NHWC中的HW 即获取到[13, 13]或[26, 26]或[52, 52]dim = grid_size[0] * grid_size[1]  # 计算特征图像素个数bbox_attrs = 5 + num_classes       # 计算每个bbox_attrs的预测向量长度# 三个尺度的特征图经过计算tf.reshape后形状分别为 (1, 507, 8)或(1, 2028, 8)或(1, 8112, 8)predictions = tf.reshape(predictions, [-1, num_anchors * dim, bbox_attrs])  # 把h和w展开成dim   num_anchors * dim  是每个特征图的bbox_attrs个数stride = (img_size[0] // grid_size[0], img_size[1] // grid_size[1])  # 缩放参数 32(416/13) 16(416/26)8(416/52)  用原始图长宽除特征图长宽来计算缩放倍数anchors = [(a[0] / 1.0, a[1] / 1.0) for a in anchors]   # 目的将anchors数据类型由整型转化为浮点型# 将包含边框的单元属性拆分,拆分最后一个维度# 如 num_classes=3# (1, 507, 8)拆成-->(1, 507, 2)、(1, 507, 2)、(1, 507, 1)、(1, 507, 3)# (1, 2028, 8)拆成-->(1, 2028, 2)、(1, 2028, 2)、(1, 2028, 1)、(1, 2028, 3)# (1, 8112, 8)拆成-->(1, 8112, 2)、(1, 8112, 2)、(1, 8112, 1)、(1, 8112, 3)box_centers, box_sizes, confidence, classes = tf.split(predictions, [2, 2, 1, num_classes], axis=-1)box_centers = tf.nn.sigmoid(box_centers)   # 中心点做sigmoid激活(这得到是中心点偏移量的预测)confidence = tf.nn.sigmoid(confidence)     # 置信度做sigmoid激活# =============================创建和特征图大小相等的网格坐标点 每个坐标点对应一个特征图的像素点的位置=====================# a 存放x坐标点 b 存放y坐标点grid_x = tf.range(grid_size[0], dtype=tf.float32)  # 定义网格索引0,1,2...ngrid_y = tf.range(grid_size[1], dtype=tf.float32)  # 定义网格索引0,1,2,...m# grid_x自我复制赋值给a  grid_y自我复制赋值给ba, b = tf.meshgrid(grid_x, grid_y)  # 生成网格矩阵 a0,a1.。。an(共M行)  , b0,b0,。。。b0(共n个),第二行为b1# 将a b 按列拉直x_offset = tf.reshape(a, (-1, 1))  # 展开 一共dim个y_offset = tf.reshape(b, (-1, 1))# 按列组合成坐标x_y_offset = tf.concat([x_offset, y_offset], axis=-1)  # 连接----[dim,2]# 每一个bbox_attrs都有一个中心坐标 每个坐标对应num_anchors个anchor,这num_anchors个anchor的中心坐标是一样的x_y_offset = tf.reshape(tf.tile(x_y_offset, [1, num_anchors]), [1, -1, 2])  # 按候选框的个数复制xy(【1,n】代表第0维一次,第1维复制n次)'''tf.tile(input,multiples,name=None)  input:输入tensor  multiples:是一维张量,第一个元素值代表第一维度复制为原来的几倍,第二个元素值代表第二维度复制为原来的几倍,即张量值依次表示为依次表示input的第1,第2,第3...第n维数据扩展为原来的几倍。  '''# ============================真实中心的预测计算=======================================================# 真实预测的中心位置(处于缩放状态) = 预测的中心偏移量 + 原具体的位置(对应特征像素点位置)box_centers = box_centers + x_y_offset  # box_centers为0-1,x_y为具体网格的索引,相加后,就是真实位置(0.1+4=4.1,第4个网格里0.1的偏移)# 真实预测的中心位置(处于真实状态)= 真实预测的中心位置(处于缩放状态)* 缩放倍数box_centers = box_centers * stride  # 真实尺寸像素点# ============================真实边框(hw)的预测计算=======================================================# dim 为特征图的像素个数,anchors:自定义统一图下的anchor# 将自定义缩放状态的anchor复制dim倍,即每一个像素点对应三个不同尺寸的统一图下的anchoranchors = tf.tile(anchors, [dim, 1])# tf.exp(box_sizes) 是预测的统一图下的anchor的缩放倍数# anchors是自定义统一图的anchor# box_sizes是统一图下的边框宽高的预测的某种映射,即# 网络预测的是anchor的w = log(相对于统一图的标注框的w/标注框匹配到的输入特征所对应的自定义的统一图下的anchor的W)# 网络预测的是anchor的h = log(相对于统一图的标注框的h/标注框匹配到的输入特征所对应的自定义的统一图下的anchor的h)# 而我们所需要是标注框W 因为我们是用标注框的w和h 用公式log(相对于统一图的标注框的w/标注框匹配到的输入特征所对应的自定义的统一图下的anchor的W),来指导学习的。# 所以学习的结果是log(相对于统一图的标注框的w/标注框匹配到的输入特征所对应的自定义的统一图下的anchor的W),所以我们要反解出标注框的w,这才是我们所需要的数值# 计算相对于统一图的anchor得边长whbox_sizes = tf.exp(box_sizes)*anchors# 将计算好的预测的真实中心点和边框以及置信度组合到一起detections = tf.concat([box_centers, box_sizes, confidence], axis=-1)# # 分类做sigmoid激活classes = tf.nn.sigmoid(classes)# 将计算好的预测的真实中心点和边框以及置信度和分类组合到一起predictions = tf.concat([detections, classes], axis=-1)  # 将转化后的结果合起来# 显示完整预测值的形状,三个尺度有三个结果print(predictions.get_shape())  # 三个尺度的形状分别为:[1, 507(13*13*3), 5+c]、[1, 2028, 5+c]、[1, 8112, 5+c]return predictions  # 返回预测值

yolov3前向传播(二)-- yolov3相关模块的解析与实现(一)相关推荐

  1. yolov3前向传播(一)-- darknet53网络解析与实现

    一.darknet53网络解析与实现 一.darknet53网络结构组成部分 darknet53网络是由 darknet块 下采样卷积块组成的 1.darknet块 1.1 darknet块网络结构 ...

  2. yolov3前向传播(二)-- yolov3相关模块的解析与实现(二)

    yolov3相关模块的解析与实现(二) 接上一篇 三.上采样函数 作用:用于将特征图扩展到想要的尺寸大小,和其他特征叠加到一起使用. 上采样的方法为近邻差值法 上采样函数的实现 # 定义上采样函数 d ...

  3. yolov3前向传播(三)-- 坐标转换,iou计算,权重加载,图片显示

    坐标转换,iou计算,权重加载,图片显示 一.坐标转换 1.分析 2.实现 # =====================================坐标值转化函数================ ...

  4. 使用pytorch从零开始实现YOLO-V3目标检测算法 (二)

    原文:https://blog.csdn.net/u011520516/article/details/80212960 博客翻译 这是从零开始实现YOLO v3检测器的教程的第2部分.在上一节中,我 ...

  5. 前向传播和反向传播_深度学习的地基模块:模型、参数、非线性、前向传播、反向偏微分

    头条ID:钱多多先森,关注更多AI.CV.数码.个人理财领域知识,关注我,一起成长 在深度学习中,数据.模型.参数.非线性.前向传播预测.反向偏微分参数更新等等,都是该领域的基础内容.究竟他们最基础的 ...

  6. 【Linux开发】linux设备驱动归纳总结(二):模块的相关基础概念

    linux设备驱动归纳总结(二):模块的相关基础概念 系统平台:Ubuntu 10.04 开发平台:S3C2440开发板 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  7. (二十四) 手推BP神经网络的前向传播和反向传播

    手推BP神经网络的前向传播和反向传播 一.基本术语 1.监督学习与非监督学习 Supervised Learning有监督式学习: 输入的数据被称为训练数据,一个模型需要通过一个训练过程,在这个过程中 ...

  8. 自上而下解读ncnn系列(1):加载param模型和bin文件前向传播

    由于这段时间着手实现tensorflow到ncnn的转换,开发过程中对ncnn框架有了一定的认识,特此分享. 关于tensorflow2ncnn的具体细节和步骤,可以参考我的github: https ...

  9. 【DETR源码解析】二、Backbone模块

    目录 前言 一.Backbone整体结构 一.CNN-Backbone 二.Positional Encoding Reference 前言 最近在看DETR的源码,断断续续看了一星期左右,把主要的模 ...

最新文章

  1. 两个html文件互相访问变量,访问一个js文件的变量上的HTML文件
  2. android NDk编程
  3. 为什么要关心均值和哈希码
  4. 分布式Session框架
  5. 软件工程 选课系统的uml类图_想成为高级程序猿,面向对象建模和UML你不应该知道?...
  6. hdu1284钱币兑换问题
  7. 796. 子矩阵的和
  8. linux oracle 运维_运维日记| Linux磁盘空间被莫名占用的问题
  9. 计算机二级C语言题库(60套真题+刷题软件)2022年9月份新题第二套
  10. 【iOS 15】iPhone如何录屏?iPhone屏幕录制技巧分享
  11. oracle考试试题及其答案,Oracle期末考试试题及答案-
  12. 计算机二级真题期刊论文模板,标准期刊论文格式模板_优秀论文范文3000字
  13. vue3.0脚手架的搭建
  14. Java 无限级递归生成树级菜单
  15. ECNU203.2333进制
  16. excel组合汇总_Excel汇总20140609
  17. OpenCV 模板匹配去重
  18. 小程序购物车右上角数字显示与消失
  19. vue+element ui+腾讯云开发打造会员管理系统之实战教程(三)系统登录
  20. 详解可微神经网络架构搜索框架(DNAS)

热门文章

  1. bzoj 3406: [Usaco2009 Oct]Invasion of the Milkweed 乳草的入侵
  2. bzoj 3403: [Usaco2009 Open]Cow Line 直线上的牛
  3. js中WINDOW对象
  4. 风格迁移与Gram matrix
  5. NMS(Non-maximum suppression)非极大抑制
  6. 实现labelme批量json_to_dataset方法
  7. RC充放电网络的定量计算
  8. 2018.10.01 NOIP模拟 卡牌游戏(贪心)
  9. Janusec WAF网关安装体验
  10. [水煮 ASP.NET Web API2 方法论](12-1)创建 OData