Detect-and-Track论文:3D Mask R-CNN Caffe2源代码解析——1.模型构建梳理

2023-05-16

这篇博文的内容是对Detect-and-Track的源代码进行解析,由于是第一篇,所以展示的是代码的脉络,以及如何寻找到3D Mask R-CNN的构建过程。博文的目录是按照文件来的:

参考内容链接如下:

Detect-and-Track论文:【网页链接】

Detect-and-Track源代码:【网页链接】


目录

一、tools/train_net.py

二、lib/modeling/ model_builder.py

1.函数索引

2.创建模型:keypoint_rcnn()

3. 根据参数创建模型的函数:build_generic_fast_rcnn_model()


一、tools/train_net.py

我们将代码翻到最后,可以看到主语句:

if __name__ == '__main__':

在中间部位,我们可以看到这样一个训练语句:

checkpoints = net_trainer()

定位到net_trainer(),此函数包含了全部的训练过程。代码详解之后的系列会推出,我们先来看第一句,如何构建一个模型:

def net_trainer():
    model, start_iter, checkpoints = create_model()  # ◆创建模型
……

定位到create_model()函数:

def create_model():
    """加载节点,创建model,进行一次训练"""
    start_iter = 0
    if cfg.CLUSTER.ON_CLUSTER and cfg.CLUSTER.AUTO_RESUME:
        import re

        # 训练好的模型model_final.pkl已经存在,不需要训练
        output_dir = get_output_dir(training=True)
        final_path = os.path.join(output_dir, 'model_final.pkl')
        if os.path.exists(final_path):
            logger.info('model_final.pkl exists; no need to train!')
            return None, None, {'final': final_path}

        # 模型训练了一半,有model_iter?.pkl存在
        files = os.listdir(output_dir)
        for f in files:
            iter_string = re.findall(r'(?<=model_iter)\d+(?=\.pkl)', f)
            if len(iter_string) > 0:
                checkpoint_iter = int(iter_string[0])
                if checkpoint_iter > start_iter:
                    # 立即开始间断点之后的训练
                    # Start one iteration immediately after the checkpoint iter
                    start_iter = checkpoint_iter + 1
                    resume_weights_file = f  # 存储文件名

        if start_iter > 0:
            cfg.TRAIN.WEIGHTS = os.path.join(output_dir, resume_weights_file)  # 生成权重路径,显示信息(路径/代数)
            logger.info('===> Resuming from checkpoint {} with start iter {}'.format(cfg.TRAIN.WEIGHTS, start_iter))

    logger.info('Building nework: {}'.format(cfg.MODEL.TYPE))  # TYPE:keypoint_rcnn
    model = model_builder.create(cfg.MODEL.TYPE, train=True)  # ◆◆◆◆◆◆◆◆◆◆◆◆◆◆创建一个keypoint_rcnn模型
    # 如果选择了memonger,对模型进行内存优化
    if cfg.MEMONGER:
        optimize_memory(model)
    workspace.RunNetOnce(model.param_init_net)  # 跑一次网络
    return model, start_iter, {}

可以看到代码首先是在加载已经训练的pkl文件,之后再由

model = model_builder.create(cfg.MODEL.TYPE, train=True) # TYPE:keypoint_rcnn

创建一个模型,而此模型的定义是在lib/modeling/ model_builder.py文件中。


二、lib/modeling/ model_builder.py

1.函数索引

在这个文件的creat()函数卡了很久,最后终于弄懂了caffe2调用函数的机制,我们来看一下creat()和get_func():

def create(model_name, train=False, init_params=None):
	"""Generic model creation function that dispatches to specific model building functions.
	Args:
		train (bool): Set true if training
		init_params (bool or None): Set to true if force initialize the network
			with random weights (even at test time). Normally will init only
			at train time.
	"""
	return get_func(model_name)(init_model(model_name, train, init_params))	
	# 这一步先获取keypoint_rcnn函数,然后再执行后面的参数
	# 其实get_func(model_name)相当于keypoint_rcnn函数
	# (init_model(model_name, train, init_params))相当于(model),创建了一个模型
def get_func(func_name):
	"""Helper to return a function object by name.
	
	根据 name 返回函数对象function object.
	func_name 必须是该模块里的某个函数或者是想对于 base 'modeling' 模块的函数路径.
	"""
	# globals()返回一个字典, 表示当前的全局符号表。 
	# 这个符号表始终针对当前模块(对函数或方法来说, 是指定义它们的模块, 而不是调用它们的模块)
	
	try:
		parts = func_name.split('.')	# keypoint_rcnn
		res = globals()[parts[0]]
		for part in parts[1:]:
			res = getattr(res, part)	# 获取res类的part属性
		return res
		
	except Exception:
		logger.error('Failed to find function: {}'.format(func_name))
		raise

通过注释大家应该了解到,get_func()这个函数仅仅只是起到一个索引的功能,由给定的字符串来找到当前文件中与其对应的函数。比如程序给定的字符串是” keypoint_rcnn”,那么get_func()检查当前文件下是否有此函数,如果有的话,再返回函数名。此时create()中return的内容就变成了:

keypoint_rcnn (init_model(model_name, train, init_params))

2.创建模型:keypoint_rcnn()

定位到keypoint_rcnn()函数,此函数直接创建了3D Mask R-CNN。我们根据配置文件将这些内容显示注释出来:

def keypoint_rcnn(model):
	return build_generic_fast_rcnn_model(
		model,	# 模型本体
		get_func(cfg.MODEL.CONV_BODY),	# ResNet3D.add_ResNet18_conv4_body		残差网络主体网络
		get_func(cfg.MODEL.ROI_HEAD),	# ResNet3D.add_ResNet18_roi_conv5_head	残差网络RoI五层
		add_roi_keypoint_head_func=get_func(cfg.KRCNN.ROI_KEYPOINTS_HEAD)	# keypoint_rcnn_heads.add_roi_pose_head_v1convX_3d
		)	
	# 相当于:
	# build_generic_fast_rcnn_model(
	# model,
	# ResNet3D.add_ResNet18_conv4_body,
	# ResNet.add_ResNet18_roi_conv5_head,
	# keypoint_rcnn_heads.add_roi_pose_head_v1convX_3d,
	# )

思路非常清晰,框架由3个大部分构成:

Backbone主干网路:用了3D版的ResNet18,4阶段版本。

RoI网络:用于生成RoI、进行RoIAlign

Keypoint_rcnn_heads:网络头,进行关键点评估

3. 根据参数创建模型的函数:build_generic_fast_rcnn_model()

keypoint_rcnn()传入参数后,build_generic_fast_rcnn_model()中_single_gpu_build_func(model)函数完成创建模型的任务。这个函数中包含着三大子框架的构建过程,需要结合着看。在后期会更新三个子框架代码的详解,同时更行此代码注释。

# 创建通用的Fast R-CNN系列模型
def build_generic_fast_rcnn_model(
		model, 	# 模型本体
		add_conv_body_func, 	# 添加backbone主体
		add_roi_frcn_head_func,	# RoI卷积头(cls & reg用?)
		add_roi_mask_head_func=None, # RoI的mask网络头函数
		add_roi_keypoint_head_func=None,	# RoI的关键点网络头函数
		freeze_conv_body=False
		):
		
	def _single_gpu_build_func(model):
		"""Builds the model on a single GPU. Can be called in a loop over GPUs
		with name and device scoping to create a data parallel model."""
		# For training we define one net that contains all ops
		# For inference, we split the graph into two nets: a standard fast r-cnn
		# net and a mask prediction net; the mask net is only applied to a
		# subset of high-scoring detections
		
		is_inference = not model.train	# 判断是不是推理

		# Some generic tensors
		model.ConstantFill([], 'zero', shape=[1], value=0)
		model.ConstantFill([], 'minus1', shape=[1], value=-1)

		# ★创建ResNet卷积网络主体:ResNet3D.add_ResNet18_conv4_body
		blob_conv, dim_conv, spatial_scale_conv = add_conv_body_func(model)	# ResNet3D.add_ResNet18_conv4_body
		if freeze_conv_body:	# 是否要冻结Backbone的梯度传播
			for b in blob_ref_to_list(blob_conv):
				model.StopGradient(b, b)

		# ★根据配置判断Backbone与Heads是否需要链接
		# Convert from 3D blob to 2D, in case of videos to attach a 2D head (not necessarily will happen though)
		if cfg.MODEL.VIDEO_ON:	# 视频分析-开
			blob_conv = time_pool_blobs(blob_conv, model, cfg.VIDEO.BODY_HEAD_LINK)	# 卷积网络和网络头连接

		if is_inference:	# 是推理模式的话,就不需要创建RPN和网络头
			# Create a net that can be used to compute the conv body only on an image (no RPN or heads / branches)
			model.conv_body_net = model.net.Clone('conv_body_net')

		# Select the FPN lib, based on whether the head is 3D or 2D
		if cfg.MODEL.VIDEO_ON and cfg.VIDEO.BODY_HEAD_LINK == '':
			FPN_lib = FPN3D
			head_3d = True
			out_time_dim = cfg.VIDEO.NUM_FRAMES_MID
		else:
			FPN_lib = FPN
			head_3d = False
			out_time_dim = 1

		# Add the RPN branch
		if cfg.MODEL.FASTER_RCNN:
			if cfg.FPN.FPN_ON:
				FPN_lib.add_fpn_rpn_outputs(
					model, blob_conv, dim_conv, spatial_scale_conv,
					time_dim=out_time_dim)
				model.CollectAndDistributeFpnRpnProposals()
			else:
				add_rpn_outputs(model, blob_conv, dim_conv, spatial_scale_conv,
								nd=head_3d, time_dim=out_time_dim)

		if cfg.FPN.FPN_ON:
			# Code only supports case when RPN and ROI min levels are the same
			assert cfg.FPN.RPN_MIN_LEVEL == cfg.FPN.ROI_MIN_LEVEL
			# FPN RPN max level might be > FPN ROI max level in which case we
			# need to discard some leading conv blobs (blobs are ordered from
			# max level to min level)
			num_roi_levels = cfg.FPN.ROI_MAX_LEVEL - cfg.FPN.ROI_MIN_LEVEL + 1
			blob_conv = blob_conv[-num_roi_levels:]
			spatial_scale_conv = spatial_scale_conv[-num_roi_levels:]

		# Add the Fast R-CNN branch
		blob_frcn, dim_frcn, spatial_scale_frcn = add_roi_frcn_head_func(
			model, blob_conv, dim_conv, spatial_scale_conv)
		add_fast_rcnn_outputs(model, blob_frcn, dim_frcn, is_head_3d=head_3d)

		# Add the mask branch
		if cfg.MODEL.MASK_ON:
			if is_inference:
				bbox_net = copy.deepcopy(model.net.Proto())

			# Add the mask branch
			blob_mrcn, dim_mrcn, _ = add_roi_mask_head_func(
				model, blob_conv, dim_conv, spatial_scale_conv)
			blob_mask = add_mask_rcnn_outputs(model, blob_mrcn, dim_mrcn)

			if is_inference:
				# Extract the mask prediction net, store it as its own network,
				# then restore the primary net to the bbox-only network
				model.mask_net, blob_mask = get_suffix_net(
					'mask_net', bbox_net.op, model.net, [blob_mask])
				model.net._net = bbox_net

		# Add the keypoint branch
		if cfg.MODEL.KEYPOINTS_ON:
			if is_inference:
				bbox_net = copy.deepcopy(model.net.Proto())

			blob_krcnn, dim_krcnn, _ = add_roi_keypoint_head_func(
				model, blob_conv, dim_conv, spatial_scale_conv)
			blob_keypoint = add_heatmap_outputs(
				model, blob_krcnn, dim_krcnn,
				time_dim=out_time_dim, is_head_3d=head_3d)

			if is_inference:
				model.keypoint_net, keypoint_blob_out = get_suffix_net(
					'keypoint_net', bbox_net.op, model.net, [blob_keypoint])
				model.net._net = bbox_net

		if model.train:
			loss_gradients = add_fast_rcnn_losses(model, time_dim=out_time_dim)
			if cfg.MODEL.MASK_ON:
				loss_gradients.update(add_mask_rcnn_losses(model, blob_mask,
														   time_dim=out_time_dim))
			if cfg.MODEL.KEYPOINTS_ON:
				loss_gradients.update(add_heatmap_losses(model, time_dim=out_time_dim))
			if cfg.MODEL.FASTER_RCNN:
				if cfg.FPN.FPN_ON:
					# The loss function is shared between 2D and 3D FPN
					loss_gradients.update(FPN.add_fpn_rpn_losses(
						model, time_dim=out_time_dim))
					if cfg.VIDEO.PREDICT_RPN_BOX_VIS:
						loss_gradients.update(FPN.add_fpn_rpn_vis_losses(
							model, time_dim=out_time_dim))
				else:
					loss_gradients.update(add_rpn_losses(
						model, time_dim=out_time_dim))
					if cfg.VIDEO.PREDICT_RPN_BOX_VIS:
						loss_gradients.update(add_rpn_vis_losses(
							model, time_dim=out_time_dim))
		return loss_gradients if model.train else None

	build_data_parallel_model(model, _single_gpu_build_func)
	return model

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Detect-and-Track论文:3D Mask R-CNN Caffe2源代码解析——1.模型构建梳理 的相关文章

随机推荐

  • Tensorflow笔记2:Session

    参考内容都出自于官方API教程tf Session 一 Session类基本使用方法 这里使用的是1 15版本 xff0c TF官方为了能够在2 0 43 版本中保持兼容 xff0c 因此调用时使用了tf compat v1 Session
  • Tensorflow笔记3:Variable

    调用Variable类即可向Graph中添加变量 Variable在创建之后需要给定初始值 xff0c 可以是任意type shape的Tensor 一旦使用初始值完成了初始化 xff0c type和shape都固定 xff0c 除非使用a
  • TensorFlow-Slim API 官方教程

    https blog csdn net u014061630 article details 80632736 TF Slim 模块是 TensorFlow 中最好用的 API 之一 尤其是里面引入的 arg scope model var
  • Tensorflow笔记4:Saver

    Saver类位于tf train中 xff0c 属于训练过程中要用到的方法 xff0c 主要作用就是保存和加载save amp restore ckpt 最简单的保存应用举例 xff1a saver span class token pun
  • Tensorflow笔记4:学习率衰减策略tf.train.cosine_decay_restarts

    TF在learning rate decay py中提供了几种非常骚气的学习率下降方法 xff0c 今天就来玩一玩 只需要简单的参数设定 xff0c 就能够产生神奇的lr衰减效果 首先简介lr的一般使用方法 xff1a lr span cl
  • ffmpeg使用笔记

    视频压缩 ffmpeg i lt input gt vcodec libx264 crf 25 lt output gt 分辨率调整 ffmpeg i 123 mp4 s 960x540 1 mp4 视频截取 截取 xff08 t1 43
  • Pytorch 入门

    1 加载模型 seg model 61 torchvision models detection maskrcnn resnet50 fpn pretrained 61 True seg model 61 seg model cuda 1
  • 小白之通俗易懂的贝叶斯定理

    原文链接 xff1a https zhuanlan zhihu com p 37768413 概率论与数理统计 xff0c 在生活中实在是太有用了 xff0c 但由于大学课堂理解不够深入 xff0c 不能很好地将这些理论具象化并应用到实际生
  • tf.variable_scope中的reuse

    一 两种scope xff1a variable与name tf variable scope 是对变量进行命名管理 xff0c 而tf name scope 是对算子 op 进行命名管理 xff0c 二者相互不影响 见下例 xff1a i
  • HTML+CSS 简易搜索框

    搜索框是页面中很常见的一种 xff0c 下面分享一段简单搜索框案例 xff0c 直接上代码 HTML部分 lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 UTF
  • frp内网穿刺/反向代理教程

    文章目录 前言一 明确基本概念二 frp下载与使用1 云服务器做为Server端2 GPU服务器做为Client端3 远程访问 三 云服务器防火墙端口开启 前言 frp 是一个高性能的反向代理应用 xff0c 可以帮助开发者轻松地进行内网穿
  • Keras模型基本流程

    文章目录 前言一 Keras流程二 Keras中的模型定义1 基于Sequential 类2 基于函数式API 前言 目前打算看tensorflow probability模块 xff0c 但是发现整个都是适配Keras的 xff0c 很多
  • pytorch自动混合精度训练

    from torch cuda amp import autocast GradScaler Init Step 1 Create Model model device start epoch 61 create model opt if
  • Linux系统查看CPU个数&超线程&线程数

    小命令 xff1a Linux查看CPU详细信息 简书 jianshu com Intel CPU产品规范 xff1a 英特尔 产品 xff1a 处理器 xff0c 英特尔 NUC 迷你电脑 xff0c 内存和存储 xff0c 芯片组 in
  • Tensorflow学习笔记(1)——Tensorflow-CPU版安装躺坑实录

    从今天开始就要出品自己的Tensorflow系列啦 xff01 由于是第一篇关于Python的博文 xff0c 所以先把接触Python以来的感想和心得都放了进来 xff0c 想看Tensorflow的博友请直接跳到标题三 一 Python
  • Tensorflow学习笔记(3)——图、会话基本语法

    前言 xff1a Tensorflow xff0c 与我们之前熟悉的C C 43 43 Python的确不太一样 xff0c 建议初学者当作一门新的语言来学 如果看的过程中忽然有一种 的确不太一样 的感觉 xff0c 并且明白了哪里不一样
  • Tensorflow学习笔记(2)——Tensorflow-GPU版安装总结

    经历了N多次的失败 xff0c TF GPU的环境终于搭建好了 xff0c 全程连着弄了三天 现在把安装中的注意事项总结一下 xff0c 希望大家少走弯路 xff01 先把自己的配置列表说一下 xff1a Windows7 x64 VS20
  • 深度学习基础——彻底掌握卷积层的计算

    机器学习也是刚刚入门 xff0c 虽然对卷积 池化等过程很熟悉 xff0c 但是一直不太清楚具体的计算 xff0c 幸好在博文上看到了讲解过程 xff0c 看完以后受益匪浅 xff0c 然后自己又重新写了一遍 有这个表格 xff0c 再也不
  • Mask R-CNN 简介与论文笔记

    本篇文章是面向Mask R CNN的初学者 xff0c 旨在梳理大体思路 xff0c 认识框架基础概念 由于自己现在大四 xff0c 也是刚刚入足深度学习领域 xff0c 所以文章中免不了有错误之处 xff0c 欢迎各位博友批评指正 本博文
  • Detect-and-Track论文:3D Mask R-CNN Caffe2源代码解析——1.模型构建梳理

    这篇博文的内容是对Detect and Track的源代码进行解析 xff0c 由于是第一篇 xff0c 所以展示的是代码的脉络 xff0c 以及如何寻找到3D Mask R CNN的构建过程 博文的目录是按照文件来的 xff1a 参考内容