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)机制,包括版本链、ReadView以及在不同事务隔离级别下MVCC的工作原理,通过一个具体的示例演示了在可重... 目录简介ReadView版本链演示过程总结简介MVCC(Multi-Version Concurr

关于Gateway路由匹配规则解读

《关于Gateway路由匹配规则解读》本文详细介绍了SpringCloudGateway的路由匹配规则,包括基本概念、常用属性、实际应用以及注意事项,路由匹配规则决定了请求如何被转发到目标服务,是Ga... 目录Gateway路由匹配规则一、基本概念二、常用属性三、实际应用四、注意事项总结Gateway路由

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

MySQL中时区参数time_zone解读

《MySQL中时区参数time_zone解读》MySQL时区参数time_zone用于控制系统函数和字段的DEFAULTCURRENT_TIMESTAMP属性,修改时区可能会影响timestamp类型... 目录前言1.时区参数影响2.如何设置3.字段类型选择总结前言mysql 时区参数 time_zon

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 网络的名称。比如