Tensorflow版Faster RCNN源码解析(TFFRCNN) (14) VGGnet_test.py
本blog为github上CharlesShang/TFFRCNN版源码解析系列代码笔记
---------------个人学习笔记---------------
----------------本文作者疆--------------
------点击此处链接至博客园原文------
该脚本定义了测试网络和几个变量的占位符,测试阶段test.py中im_detect函数以feed_dict馈入data等图像信息,照此层层计算。(从network.py中看)各层计算时首先置空self.inputs下一层输入列表,然后将本层的输入添加进来,将本层的输出保存在self.layers字典中可供下一层取输入数据时使用
整个工程定义了许多类,类间调用逻辑顺序不明,该VGGnet_test类以何种方式被调用?
为什么rpn_cls_score在softmax前要reshape?然后再reshape回来???应与softmax接收的输入有关
import tensorflow as tf from .network import Network from ..fast_rcnn.config import cfg # 以何种方式被调用??? class VGGnet_test(Network): # 重构了基类Network中的__init__(...)方法,则基类__init__(...)不执行 def __init__(self, trainable=True): # 存储下一层的输入(列表) self.inputs = [] self.data = tf.placeholder(tf.float32, shape=[None, None, None, 3]) self.im_info = tf.placeholder(tf.float32, shape=[None, 3]) self.keep_prob = tf.placeholder(tf.float32) # 存储各层的输出(字典) self.layers = dict({'data': self.data, 'im_info': self.im_info}) self.trainable = trainable self.setup() # 重构了基类Network中的setup方法 def setup(self): #n_classes = 21 #2018.1.30 n_classes = cfg.NCLASSES # anchor_scales = [8, 16, 32] anchor_scales = cfg.ANCHOR_SCALES _feat_stride = [16, ] # 各层间运算机制可见network.py中代码理解,需要理解装饰器 # conv1_1、conv1_2、conv2_1、conv2_2参数(在训练阶段)均不更新 (self.feed('data') .conv(3, 3, 64, 1, 1, name='conv1_1', trainable=False) .conv(3, 3, 64, 1, 1, name='conv1_2', trainable=False) .max_pool(2, 2, 2, 2, padding='VALID', name='pool1') .conv(3, 3, 128, 1, 1, name='conv2_1', trainable=False) .conv(3, 3, 128, 1, 1, name='conv2_2', trainable=False) .max_pool(2, 2, 2, 2, padding='VALID', name='pool2') .conv(3, 3, 256, 1, 1, name='conv3_1') .conv(3, 3, 256, 1, 1, name='conv3_2') .conv(3, 3, 256, 1, 1, name='conv3_3') .max_pool(2, 2, 2, 2, padding='VALID', name='pool3') .conv(3, 3, 512, 1, 1, name='conv4_1') .conv(3, 3, 512, 1, 1, name='conv4_2') .conv(3, 3, 512, 1, 1, name='conv4_3') .max_pool(2, 2, 2, 2, padding='VALID', name='pool4') .conv(3, 3, 512, 1, 1, name='conv5_1') .conv(3, 3, 512, 1, 1, name='conv5_2') .conv(3, 3, 512, 1, 1, name='conv5_3')) # RPN (self.feed('conv5_3') .conv(3, 3, 512, 1, 1, name='rpn_conv/3x3') # 是/不是 fg的score .conv(1, 1, len(anchor_scales) * 3 * 2, 1, 1, padding='VALID', relu=False, name='rpn_cls_score')) (self.feed('rpn_conv/3x3') # ahchor的回归值 .conv(1, 1, len(anchor_scales) * 3 * 4, 1, 1, padding='VALID', relu=False, name='rpn_bbox_pred')) # shape is (1, H, W, Ax2) -> (1, H, WxA, 2) reshape和softmax处理 (self.feed('rpn_cls_score') .spatial_reshape_layer(2, name='rpn_cls_score_reshape') .spatial_softmax(name='rpn_cls_prob')) # shape is (1, H, WxA, 2) -> (1, H, W, Ax2) reshape处理 # 为什么softmax前要reshape?然后再reshape回来???应与softmax接收的输入有关 (self.feed('rpn_cls_prob') .spatial_reshape_layer(len(anchor_scales) * 3 * 2, name='rpn_cls_prob_reshape')) (self.feed('rpn_cls_prob_reshape', 'rpn_bbox_pred', 'im_info' # 回归后并经过一些后处理得到的proposal,见proposal_layer_tf.py # 默认_feat_stride = [16, ]、anchor_scales = cfg.ANCHOR_SCALES = [8, 16, 32]、TEST模式 .proposal_layer(_feat_stride, anchor_scales, 'TEST', name='rois')) # RCNN subnet (self.feed('conv5_3', 'rois') .roi_pool(7, 7, 1.0 / 16, name='pool_5') .fc(4096, name='fc6') .fc(4096, name='fc7') # score经过softmax后称为prob .fc(n_classes, relu=False, name='cls_score') .softmax(name='cls_prob')) (self.feed('fc7') .fc(n_classes * 4, relu=False, name='bbox_pred'))