Faster RCNN源码解读4-其他收尾工作:ROI_pooling、分类、回归等

2024-03-03 18:32

本文主要是介绍Faster RCNN源码解读4-其他收尾工作:ROI_pooling、分类、回归等,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Faster RCNN复现

Faster RCNN源码解读1-整体流程和各个子流程梳理

Faster RCNN源码解读2-_anchor_component()为图像建立anchors(核心和关键1)

Faster RCNN源码解读3.1-_region_proposal() 筛选anchors-_proposal_layer()(核心和关键2)

Faster RCNN源码解读3.2-_region_proposal()筛选anchors-_anchor_target_layer()(核心和关键2)

Faster RCNN源码解读3.3-_region_proposal() 筛选anchors-_proposal_target_layer()(核心和关键2)

Faster RCNN源码解读4-其他收尾工作:ROI_pooling、分类、回归等

Faster RCNN源码解读5-损失函数

 

理论介绍:有关Faster RCNN理论介绍的文章,可以自行搜索,这里就不多说理论部分了。

复现过程:代码配置过程没有记录,具体怎么把源码跑起来需要自己搜索一下。

faster rcnn源码确实挺复杂的,虽然一步步解析了,但是觉得还是没有领会其中的精髓,只能算是略知皮毛。在这里将代码解析的过程给大家分享一下,希望对大家有帮助。先是解析了代码的整体结构,然后对各个子结构进行了分析。代码中的注释,有的是原来就有的注释,有的是参考网上别人的,有的是自己理解的,里面或多或少会有些错误,如果发现,欢迎指正!

本文解析的源码地址:https://github.com/lijianaiml/tf-faster-rcnn-windows

 

之前通过_region_proposal() 产生w*h*9个anchors,并通过相关操作筛选出256个包含正负样本的rois,接下来进行最后的分类和回归操作。

_crop_pool_layer() 

 _crop_pool_layer用于将256个archors从特征图中裁剪出来缩放到14*14,并进一步max pool到7*7的固定大小,得到特征,方便rcnn网络分类及回归坐标,得到pool5。

  '''_crop_pool_layer用于将256个archors从特征图中裁剪出来缩放到14*14,并进一步max pool到7*7的固定大小,得到特征,方便rcnn网络分类及回归坐标。该函数先得到特征图对应的原始图像的宽高,而后将原始图像对应的rois进行归一化,并使用tf.image.crop_and_resize(该函数需要归一化的坐标信息)缩放到[cfg.POOLING_SIZE * 2,cfg.POOLING_SIZE * 2],最后通过slim.max_pool2d进行pooling,输出大小依旧一样(25677*512)。tf.slice(rois, [0, 0], [-1, 1])是对输入进行切片。其中第二个参数为起始的坐标,第三个参数为切片的尺寸。注意,对于二维输入,后两个参数均为y,x的顺序;对于三维输入,后两个均为z,y,x的顺序。当第三个参数为-1时,代表取整个该维度。上面那句是将roi的从0,0开始第一列的数据(y为-1,代表所有行,x为1,代表第一列)'''def _crop_pool_layer(self, bottom, rois, name):with tf.variable_scope(name) as scope:batch_ids = tf.squeeze(tf.slice(rois, [0, 0], [-1, 1], name="batch_id"), [1]) #得到第一列,为类别# Get the normalized coordinates of bounding boxesbottom_shape = tf.shape(bottom)height = (tf.to_float(bottom_shape[1]) - 1.) * np.float32(self._feat_stride[0])width = (tf.to_float(bottom_shape[2]) - 1.) * np.float32(self._feat_stride[0])x1 = tf.slice(rois, [0, 1], [-1, 1], name="x1") / width  #由于crop_and_resize的bboxes范围为0-1,得到归一化的坐标y1 = tf.slice(rois, [0, 2], [-1, 1], name="y1") / heightx2 = tf.slice(rois, [0, 3], [-1, 1], name="x2") / widthy2 = tf.slice(rois, [0, 4], [-1, 1], name="y2") / height# Won't be back-propagated to rois anyway, but to save timebboxes = tf.stop_gradient(tf.concat([y1, x1, y2, x2], axis=1))pre_pool_size = cfg.POOLING_SIZE * 2# 根据bboxes裁减出256个特征,并缩放到14*14(channels和bottem的channels一样)batchsize为256crops = tf.image.crop_and_resize(bottom, bboxes, tf.to_int32(batch_ids), [pre_pool_size, pre_pool_size], name="crops")return slim.max_pool2d(crops, [2, 2], padding='SAME') #max pool后得到7*7的特征

_head_to_tail()

 _head_to_tail用于将上面得到的256个archors的特征(经过ROI_pooling操作后的pool5)增加两个fc层(ReLU)和两个dropout(train时有,test时无),降维到4096维,用于_region_classification的分类及回归。_head_to_tail位于lib / nets / vgg16.py中,得到fc7。

  '''_head_to_tail用于将上面得到的256个archors的特征增加两个fc层(ReLU)
和两个dropout(train时有,test时无),降维到4096维,用于_region_classification的分类及回归。'''def _head_to_tail(self, pool5, is_training, reuse=None):with tf.variable_scope(self._scope, self._scope, reuse=reuse):pool5_flat = slim.flatten(pool5, scope='flatten')fc6 = slim.fully_connected(pool5_flat, 4096, scope='fc6')if is_training:fc6 = slim.dropout(fc6, keep_prob=0.5, is_training=True, scope='dropout6')fc7 = slim.fully_connected(fc6, 4096, scope='fc7')if is_training:fc7 = slim.dropout(fc7, keep_prob=0.5, is_training=True, scope='dropout7')return fc7

_region_classification()

 根据上面得到的fc7,通过_region_classification进行分类及回归。

  '''fc7通过_region_classification进行分类及回归。fc7先通过fc层(无ReLU)降维到21层(类别数,得到cls_score),得到概率cls_prob及预测值cls_pred(用于rcnn的分类)。另一方面fc7通过fc层(无ReLU),降维到21*4,得到bbox_pred(用于rcnn的回归)。'''def _region_classification(self, fc7, is_training, initializer, initializer_bbox):cls_score = slim.fully_connected(fc7, self._num_classes, weights_initializer=initializer,trainable=is_training,activation_fn=None, scope='cls_score')cls_prob = self._softmax_layer(cls_score, "cls_prob")cls_pred = tf.argmax(cls_score, axis=1, name="cls_pred")bbox_pred = slim.fully_connected(fc7, self._num_classes * 4, weights_initializer=initializer_bbox,trainable=is_training,activation_fn=None, scope='bbox_pred')self._predictions["cls_score"] = cls_scoreself._predictions["cls_pred"] = cls_predself._predictions["cls_prob"] = cls_probself._predictions["bbox_pred"] = bbox_predreturn cls_prob, bbox_pred

这篇关于Faster RCNN源码解读4-其他收尾工作:ROI_pooling、分类、回归等的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/770513

相关文章

MySQL中的锁和MVCC机制解读

《MySQL中的锁和MVCC机制解读》MySQL事务、锁和MVCC机制是确保数据库操作原子性、一致性和隔离性的关键,事务必须遵循ACID原则,锁的类型包括表级锁、行级锁和意向锁,MVCC通过非锁定读和... 目录mysql的锁和MVCC机制事务的概念与ACID特性锁的类型及其工作机制锁的粒度与性能影响多版本

Redis过期键删除策略解读

《Redis过期键删除策略解读》Redis通过惰性删除策略和定期删除策略来管理过期键,惰性删除策略在键被访问时检查是否过期并删除,节省CPU开销但可能导致过期键滞留,定期删除策略定期扫描并删除过期键,... 目录1.Redis使用两种不同的策略来删除过期键,分别是惰性删除策略和定期删除策略1.1惰性删除策略

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

Redis与缓存解读

《Redis与缓存解读》文章介绍了Redis作为缓存层的优势和缺点,并分析了六种缓存更新策略,包括超时剔除、先删缓存再更新数据库、旁路缓存、先更新数据库再删缓存、先更新数据库再更新缓存、读写穿透和异步... 目录缓存缓存优缺点缓存更新策略超时剔除先删缓存再更新数据库旁路缓存(先更新数据库,再删缓存)先更新数

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

MCU7.keil中build产生的hex文件解读

1.hex文件大致解读 闲来无事,查看了MCU6.用keil新建项目的hex文件 用FlexHex打开 给我的第一印象是:经过软件的解释之后,发现这些数据排列地十分整齐 :02000F0080FE71:03000000020003F8:0C000300787FE4F6D8FD75810702000F3D:00000001FF 把解释后的数据当作十六进制来观察 1.每一行数据