2021SC@SDUSC
本周分析PaddleDetection特色模型人脸识别里的算法细节FaceBoxes。
def __init__(self, backbone="FaceBoxNet", output_decoder=SSDOutputDecoder().__dict__, densities=[[4, 2, 1], [1], [1]], fixed_sizes=[[32., 64., 128.], [256.], [512.]], num_classes=2, steps=[8., 16., 32.]): super(FaceBoxes, self).__init__() self.backbone = backbone self.num_classes = num_classes self.output_decoder = output_decoder if isinstance(output_decoder, dict): self.output_decoder = SSDOutputDecoder(**output_decoder) self.densities = densities self.fixed_sizes = fixed_sizes self.steps = steps
参数说明: backbone:模式训练主干
output_decoder:输出解码器,`SSDOutputDecoder`实例
densities:定义生成的矩阵密度
fixed_sizes:固定大小
num_classes:输出类的数量
step:特征图上相邻优先矩阵的步骤大小
本函数定义了相关输入和输出的格式以及大小,初始化该类的基本参数。
def build(self, feed_vars, mode='train'): im = feed_vars['image'] if mode == 'train': gt_bbox = feed_vars['gt_bbox'] gt_class = feed_vars['gt_class'] body_feats = self.backbone(im) locs, confs, box, box_var = self._multi_box_head( inputs=body_feats, image=im, num_classes=self.num_classes) if mode == 'train': loss = fluid.layers.ssd_loss( locs, confs, gt_bbox, gt_class, box, box_var, overlap_threshold=0.35, neg_overlap=0.35) loss = fluid.layers.reduce_sum(loss) return {'loss': loss} else: pred = self.output_decoder(locs, confs, box, box_var) return {'bbox': pred}
build()函数,根据模型定义网络变量,默认为训练模型,并根据参数、输入矩阵等信息调用ssd_loss方法获取损失函数,并将损失函数输出。
def _inputs_def(self, image_shape): im_shape = [None] + image_shape # yapf: disable inputs_def = { 'image': {'shape': im_shape, 'dtype': 'float32', 'lod_level': 0}, 'im_id': {'shape': [None, 1], 'dtype': 'int64', 'lod_level': 0}, 'gt_bbox': {'shape': [None, 4], 'dtype': 'float32', 'lod_level': 1}, 'gt_class': {'shape': [None, 1], 'dtype': 'int32', 'lod_level': 1}, 'im_shape': {'shape': [None, 3], 'dtype': 'int32', 'lod_level': 0}, } # yapf: enable return inputs_def
_input_def()函数定义了数据输入格式,初始化图像大小类型等基础变量。返回初始化完成的数据。
def build_inputs( self, image_shape=[3, None, None], fields=['image', 'im_id', 'gt_bbox', 'gt_class'], # for train use_dataloader=True, iterable=False): inputs_def = self._inputs_def(image_shape) feed_vars = OrderedDict([(key, fluid.data( name=key, shape=inputs_def[key]['shape'], dtype=inputs_def[key]['dtype'], lod_level=inputs_def[key]['lod_level'])) for key in fields]) loader = fluid.io.DataLoader.from_generator( feed_list=list(feed_vars.values()), capacity=16, use_double_buffer=True, iterable=iterable) if use_dataloader else None return feed_vars, loader
build_imputs()函数:定义构建模型必要参数:feed_vars、loader并返回
def _multi_box_head(self, inputs, image, num_classes=2): def permute_and_reshape(input, last_dim): trans = fluid.layers.transpose(input, perm=[0, 2, 3, 1]) compile_shape = [0, -1, last_dim] return fluid.layers.reshape(trans, shape=compile_shape) def _is_list_or_tuple_(data): return (isinstance(data, list) or isinstance(data, tuple)) locs, confs = [], [] boxes, vars = [], [] b_attr = ParamAttr(learning_rate=2., regularizer=L2Decay(0.)) for i, input in enumerate(inputs): densities = self.densities[i] fixed_sizes = self.fixed_sizes[i] box, var = fluid.layers.density_prior_box( input, image, densities=densities, fixed_sizes=fixed_sizes, fixed_ratios=[1.], clip=False, offset=0.5, steps=[self.steps[i]] * 2) num_boxes = box.shape[2] box = fluid.layers.reshape(box, shape=[-1, 4]) var = fluid.layers.reshape(var, shape=[-1, 4]) num_loc_output = num_boxes * 4 num_conf_output = num_boxes * num_classes # get loc mbox_loc = fluid.layers.conv2d( input, num_loc_output, 3, 1, 1, bias_attr=b_attr) loc = permute_and_reshape(mbox_loc, 4) # get conf mbox_conf = fluid.layers.conv2d( input, num_conf_output, 3, 1, 1, bias_attr=b_attr) conf = permute_and_reshape(mbox_conf, 2) locs.append(loc) confs.append(conf) boxes.append(box) vars.append(var) face_mbox_loc = fluid.layers.concat(locs, axis=1) face_mbox_conf = fluid.layers.concat(confs, axis=1) prior_boxes = fluid.layers.concat(boxes) box_vars = fluid.layers.concat(vars) return face_mbox_loc, face_mbox_conf, prior_boxes, box_vars
本函数定义了输入矩阵头配置,并对输入矩阵属性变量进行初始化。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)