def attach(self, netspec, bottom): from hybrid import ConvBNReLULego, ConvBNLego, ShortcutLego # attach 3x3 conv layer conv_params = dict(name=self.name + '_3by3', num_output=self.num_outputs[0], kernel_size=3, pad=1, stride=1, use_global_stats=self.use_global_stats) if len(self.num_outputs) == 1: last = ConvBNLego(conv_params).attach(netspec, bottom) else: last = ConvBNReLULego(conv_params).attach(netspec, bottom) for i in range(1, len(self.num_outputs)): params = dict(name=self.name + '_1by1_' + str(i), num_output=self.num_outputs[i], kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) if i == len(self.num_outputs) - 1: last = ConvBNLego(params).attach(netspec, [last]) else: # last = ConvBNReLULego(params).attach(netspec, [last]) params['main_branch'] = '1by1_normal' params['shortcut'] = 'identity' last = ShortcutLego(params).attach(netspec, [last]) perm = BaseLegoFunction('Permute', self.perm_params).attach(netspec, [last]) flat = BaseLegoFunction('Flatten', self.flat_params).attach(netspec, [perm]) return flat
def attach(self, netspec, bottom): conv = BaseLegoFunction('Convolution', self.convParams).attach(netspec, bottom) bn = BaseLegoFunction('BatchNorm', self.batchNormParams).attach(netspec, [conv]) scale = BaseLegoFunction('Scale', self.scaleParams).attach(netspec, [bn]) return scale
def attach(self, netspec, bottom): from hybrid import ConvBNLego, ConvReLULego conv = BaseLegoFunction('Convolution', self.conv_params).attach(netspec, bottom) perm = BaseLegoFunction('Permute', self.perm_params).attach(netspec, [conv]) flat = BaseLegoFunction('Flatten', self.flat_params).attach(netspec, [perm]) return flat
def attach(self, netspec, bottom): # Squeeze name = self.name + '_' + 'squeeze_1by1' sq_params = dict(name=name, num_output=self.squeeze_num_output, kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) sq = ConvBNReLULego(sq_params).attach(netspec, bottom) stride = 2 if self.downsample else 1 # expand name = self.name + '_' + 'expand_1by1' exp1_params = dict(name=name, num_output=self.squeeze_num_output * self.filter_mult, kernel_size=1, pad=0, stride=stride, use_global_stats=self.use_global_stats) exp1 = ConvBNReLULego(exp1_params).attach(netspec, [sq]) name = self.name + '_' + 'expand_3by3' exp2_params = dict(name=name, num_output=self.squeeze_num_output * self.filter_mult, kernel_size=3, pad=1, stride=stride, use_global_stats=self.use_global_stats) exp2 = ConvBNReLULego(exp2_params).attach(netspec, [sq]) # concat name = self.name + '_' + 'concat' concat = BaseLegoFunction('Concat', dict(name=name)).attach( netspec, [exp1, exp2]) return concat
def attach(self, netspec, bottom): eltwise = BaseLegoFunction('Eltwise', self.eltwiseParams).attach(netspec, bottom) relu = BaseLegoFunction('ReLU', self.reluParams).attach(netspec, [eltwise]) return relu
def attach(self, netspec, bottom): conv = BaseLegoFunction('Convolution', self.convParams).attach(netspec, bottom) relu = BaseLegoFunction('ReLU', self.reluParams).attach(netspec, [conv]) return relu
def attach(self, netspec, bottom): stride = 2 if self.downsample else 1 # branch1by1 name = self.name + '_' + 'br1by1' params = dict(name=name, num_output=self.num_output / 4, kernel_size=1, pad=0, stride=stride, use_global_stats=self.use_global_stats) br1by1 = ConvBNReLULego(params).attach(netspec, bottom) # branch 3by3 name = self.name + '_' + 'br3by3_reduce' params = dict(name=name, num_output=self.num_output * 3 / 16, kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) br3by3_reduce = ConvBNReLULego(params).attach(netspec, bottom) name = self.name + '_' + 'br3by3_expand' params = dict(name=name, num_output=self.num_output / 4, kernel_size=3, pad=1, stride=stride, use_global_stats=self.use_global_stats) br3by3_expand = ConvBNReLULego(params).attach(netspec, [br3by3_reduce]) # branch 2*3by3 name = self.name + '_' + 'br2_3by3_reduce' params = dict(name=name, num_output=self.num_output * 3 / 16, kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) br2_3by3_reduce = ConvBNReLULego(params).attach(netspec, bottom) name = self.name + '_' + 'br2_3by3_expand_1' params = dict(name=name, num_output=self.num_output / 4, kernel_size=3, pad=1, stride=1, use_global_stats=self.use_global_stats) br2_3by3_expand_1 = ConvBNReLULego(params).attach( netspec, [br2_3by3_reduce]) name = self.name + '_' + 'br2_3by3_expand_2' params = dict(name=name, num_output=self.num_output / 4, kernel_size=3, pad=1, stride=stride, use_global_stats=self.use_global_stats) br2_3by3_expand_2 = ConvBNReLULego(params).attach( netspec, [br2_3by3_expand_1]) # branch pool name = self.name + '_' + 'pool' pad = 0 if self.downsample else 1 params = dict(kernel_size=3, stride=stride, pool='max', name=name, pad=pad) pool = BaseLegoFunction('Pooling', params).attach(netspec, bottom) name = self.name + '_' + 'pool_expand' params = dict(name=name, num_output=self.num_output / 4, kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) pool_conv = ConvBNReLULego(params).attach(netspec, [pool]) # concat name = self.name + '_' + 'concat' concat = BaseLegoFunction('Concat', dict(name=name)).attach( netspec, [br1by1, br3by3_expand, br2_3by3_expand_2, pool_conv]) # concat = ConcatLego(dict(name=name)).attach(netspec, [br1by1, br3by3_expand, br2_3by3_expand_2 ]) return concat
def attach(self, netspec, bottom): # branch1by1 name = self.name + '_' + 'br1by1' params = dict(name=name, num_output=self.num_outputs[0], kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) br1by1 = ConvBNReLULego(params).attach(netspec, bottom) # branch 3by3 name = self.name + '_' + 'br3by3_reduce' params = dict(name=name, num_output=self.num_outputs[1], kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) br3by3_reduce = ConvBNReLULego(params).attach(netspec, bottom) name = self.name + '_' + 'br3by3_expand' params = dict(name=name, num_output=self.num_outputs[2], kernel_size=3, pad=1, stride=1, use_global_stats=self.use_global_stats) br3by3_expand = ConvBNReLULego(params).attach(netspec, [br3by3_reduce]) # branch 5by5 name = self.name + '_' + 'br5by5_reduce' params = dict(name=name, num_output=self.num_outputs[3], kernel_size=1, pad=0, stride=1, use_global_stats=self.use_global_stats) br5by5_reduce = ConvBNReLULego(params).attach(netspec, bottom) name = self.name + '_' + 'br5by5_expand' params = dict(name=name, num_output=self.num_outputs[4], kernel_size=5, pad=2, stride=1, use_global_stats=self.use_global_stats) br5by5_expand = ConvBNReLULego(params).attach(netspec, [br5by5_reduce]) # branch pool name = self.name + '_' + 'pool_reduce' params = dict(kernel_size=3, stride=1, pool=P.Pooling.MAX, name=name) pool = BaseLegoFunction('Pooling', params).attach(netspec, bottom) name = self.name + '_' + 'pool_expand' params = dict(name=name, num_output=self.num_outputs[5], kernel_size=1, pad=1, stride=1, use_global_stats=self.use_global_stats) pool_conv = ConvBNReLULego(params).attach(netspec, [pool]) # concat name = self.name + '_' + 'concat' concat = BaseLegoFunction('Concat', dict(name=name)).attach( netspec, [br1by1, br3by3_expand, br5by5_expand, pool_conv]) return concat
def attach(self, netspec, bottom): label = bottom[0] mbox_source_layers = self.params['mbox_source_layers'] num_classes = self.params['num_classes'] normalizations = self.params['normalizations'] aspect_ratios = self.params['aspect_ratios'] min_sizes = self.params['min_sizes'] max_sizes = self.params['max_sizes'] is_train = self.params['is_train'] use_global_stats = False if is_train else True loc = [] conf = [] prior = [] for i, layer in enumerate(mbox_source_layers): if normalizations[i] != -1: norm_name = "{}_norm".format(layer) norm_layer = BaseLegoFunction( 'Normalize', dict(name=norm_name, scale_filler=dict(type="constant", value=normalizations[i]), across_spatial=False, channel_shared=False)).attach(netspec, [netspec[layer]]) layer_name = norm_name else: layer_name = layer # Estimate number of priors per location given provided parameters. aspect_ratio = [] if len(aspect_ratios) > i: aspect_ratio = aspect_ratios[i] if type(aspect_ratio) is not list: aspect_ratio = [aspect_ratio] if max_sizes and max_sizes[i]: num_priors_per_location = 2 + len(aspect_ratio) else: num_priors_per_location = 1 + len(aspect_ratio) num_priors_per_location += len(aspect_ratio) params = dict(name=layer_name, num_classes=num_classes, num_priors_per_location=num_priors_per_location, min_size=min_sizes[i], max_size=max_sizes[i], aspect_ratio=aspect_ratio, use_global_stats=use_global_stats) params['deep_mult'] = 4 params['type'] = 'linear' # params['type'] = 'deep' # params['depth'] = 3 arr = MBoxUnitLego(params).attach( netspec, [netspec[layer_name], netspec['data']]) loc.append(arr[0]) conf.append(arr[1]) prior.append(arr[2]) mbox_layers = [] locs = BaseLegoFunction('Concat', dict(name='mbox_loc', axis=1)).attach(netspec, loc) mbox_layers.append(locs) confs = BaseLegoFunction('Concat', dict(name='mbox_conf', axis=1)).attach(netspec, conf) mbox_layers.append(confs) priors = BaseLegoFunction('Concat', dict(name='mbox_priorbox', axis=2)).attach(netspec, prior) mbox_layers.append(priors) # MultiBoxLoss parameters. share_location = True background_label_id = 0 train_on_diff_gt = True normalization_mode = P.Loss.VALID code_type = P.PriorBox.CENTER_SIZE neg_pos_ratio = 3. loc_weight = (neg_pos_ratio + 1.) / 4. multibox_loss_param = { 'loc_loss_type': P.MultiBoxLoss.SMOOTH_L1, 'conf_loss_type': P.MultiBoxLoss.SOFTMAX, 'loc_weight': loc_weight, 'num_classes': num_classes, 'share_location': share_location, 'match_type': P.MultiBoxLoss.PER_PREDICTION, 'overlap_threshold': 0.5, 'use_prior_for_matching': True, 'background_label_id': background_label_id, 'use_difficult_gt': train_on_diff_gt, 'do_neg_mining': True, 'neg_pos_ratio': neg_pos_ratio, 'neg_overlap': 0.5, 'code_type': code_type, } loss_param = { 'normalization': normalization_mode, } mbox_layers.append(label) BaseLegoFunction( 'MultiBoxLoss', dict(name='mbox_loss', multibox_loss_param=multibox_loss_param, loss_param=loss_param, include=dict(phase=caffe_pb2.Phase.Value('TRAIN')), propagate_down=[True, True, False, False])).attach(netspec, mbox_layers) if not is_train: # parameters for generating detection output. det_out_param = { 'num_classes': num_classes, 'share_location': True, 'background_label_id': 0, 'nms_param': { 'nms_threshold': 0.45, 'top_k': 400 }, 'save_output_param': { 'output_directory': "./models/voc2007/resnet_36_with4k_inception_trick/expt1/detection/", 'output_name_prefix': "comp4_det_test_", 'output_format': "VOC", 'label_map_file': "data/VOC0712/labelmap_voc.prototxt", 'name_size_file': "data/VOC0712/test_name_size.txt", 'num_test_image': 4952, }, 'keep_top_k': 200, 'confidence_threshold': 0.01, 'code_type': P.PriorBox.CENTER_SIZE, } # parameters for evaluating detection results. det_eval_param = { 'num_classes': num_classes, 'background_label_id': 0, 'overlap_threshold': 0.5, 'evaluate_difficult_gt': False, 'name_size_file': "data/VOC0712/test_name_size.txt", } conf_name = "mbox_conf" reshape_name = "{}_reshape".format(conf_name) netspec[reshape_name] = L.Reshape( netspec[conf_name], shape=dict(dim=[0, -1, num_classes])) softmax_name = "{}_softmax".format(conf_name) netspec[softmax_name] = L.Softmax(netspec[reshape_name], axis=2) flatten_name = "{}_flatten".format(conf_name) netspec[flatten_name] = L.Flatten(netspec[softmax_name], axis=1) mbox_layers[1] = netspec[flatten_name] netspec.detection_out = L.DetectionOutput( *mbox_layers, detection_output_param=det_out_param, include=dict(phase=caffe_pb2.Phase.Value('TEST'))) netspec.detection_eval = L.DetectionEvaluate( netspec.detection_out, netspec.label, detection_evaluate_param=det_eval_param, include=dict(phase=caffe_pb2.Phase.Value('TEST')))
def attach(self, netspec, bottom): if self.params['type'] == 'deep': # Location prediction layers deep_mult = self.params['deep_mult'] num_outputs = [] for i in range(self.params['depth']): num_outputs.append(self.params['num_priors_per_location'] * 4 * deep_mult) num_outputs.append(self.params['num_priors_per_location'] * 4) loc_params = dict() loc_params['name'] = self.params['name'] + '_mbox_loc' loc_params['num_outputs'] = num_outputs loc_params['use_global_stats'] = self.params['use_global_stats'] loc = DeepPredictionLego(loc_params).attach(netspec, [bottom[0]]) # Confidence prediction layers num_outputs = [] for i in range(self.params['depth']): num_outputs.append(self.params['num_priors_per_location'] * self.params['num_classes'] * deep_mult) num_outputs.append(self.params['num_priors_per_location'] * self.params['num_classes']) conf_params = dict() conf_params['name'] = self.params['name'] + '_mbox_conf' conf_params['num_outputs'] = num_outputs conf_params['use_global_stats'] = self.params['use_global_stats'] conf = DeepPredictionLego(conf_params).attach(netspec, [bottom[0]]) else: # Confidence prediction layers conf_params = dict() conf_params['name'] = self.params['name'] + '_mbox_conf' conf_params['num_output'] = self.params[ 'num_classes'] * self.params['num_priors_per_location'] # conf_params['num_outputs'] = [self.params['num_classes'] * self.params['num_priors_per_location']] # comment below line to go original way of detection heads # conf_params['use_global_stats'] = self.params['use_global_stats'] conf = PredictionLego(conf_params).attach(netspec, [bottom[0]]) # Location prediction layers loc_params = dict() loc_params['name'] = self.params['name'] + '_mbox_loc' loc_params[ 'num_output'] = self.params['num_priors_per_location'] * 4 # loc_params['num_outputs'] = [self.params['num_priors_per_location'] * 4] # comment below line to go original way of detection heads # loc_params['use_global_stats'] = self.params['use_global_stats'] loc = PredictionLego(loc_params).attach(netspec, [bottom[0]]) # Priorbox layers prior_box_params = dict(min_size=self.params['min_size'], aspect_ratio=self.params['aspect_ratio'], flip=True, clip=True, variance=[0.1, 0.1, 0.2, 0.2]) if self.params['max_size']: prior_box_params['max_size'] = self.params['max_size'] prior_params = dict(name=self.params['name'] + '_mbox_priorbox', prior_box_param=prior_box_params) prior = BaseLegoFunction('PriorBox', prior_params).attach(netspec, bottom) return [loc, conf, prior]