def convert_net(args, net, blobs): @op_filter() def convert_op_name(op): if args.device != 'gpu': if op.engine != 'DEPTHWISE_3x3': op.engine = '' op.device_option.CopyFrom(caffe2_pb2.DeviceOption()) reset_names(op.input) reset_names(op.output) return [op] @op_filter(type="Python", inputs=['rpn_cls_probs', 'rpn_bbox_pred', 'im_info']) def convert_gen_proposal(op_in): gen_proposals_op, ext_input = convert_gen_proposals( op_in, blobs, rpn_min_size=float(cfg.TEST.RPN_MIN_SIZE), rpn_post_nms_topN=cfg.TEST.RPN_POST_NMS_TOP_N, rpn_pre_nms_topN=cfg.TEST.RPN_PRE_NMS_TOP_N, rpn_nms_thres=cfg.TEST.RPN_NMS_THRESH, ) net.external_input.extend([ext_input]) return [gen_proposals_op] @op_filter(input_has='rois') def convert_rpn_rois(op): for j in range(0, len(op.input)): if op.input[j] == 'rois': print('Converting op {} input name: rois -> rpn_rois:\n{}'.format( op.type, op)) op.input[j] = 'rpn_rois' return [op] @op_filter(type_in=['StopGradient', 'Alias']) def convert_remove_op(op): print('Removing op {}:\n{}'.format(op.type, op)) return [] convert_op_in_proto(net, convert_op_name) convert_op_in_proto(net, [ convert_gen_proposal, convert_rpn_rois, convert_remove_op ]) reset_names(net.external_input) reset_names(net.external_output) reset_blob_names(blobs)
def convert_net(args, net, blobs): @op_filter() def convert_op_name(op): if args.device != 'gpu': if op.engine != 'DEPTHWISE_3x3': op.engine = '' op.device_option.CopyFrom(caffe2_pb2.DeviceOption()) reset_names(op.input) reset_names(op.output) return [op] @op_filter(type="Python", inputs=['rpn_cls_probs', 'rpn_bbox_pred', 'im_info']) def convert_gen_proposal(op_in): gen_proposals_op, ext_input = convert_gen_proposals( op_in, blobs, rpn_min_size=float(cfg.TEST.RPN_MIN_SIZE), rpn_post_nms_topN=cfg.TEST.RPN_POST_NMS_TOP_N, rpn_pre_nms_topN=cfg.TEST.RPN_PRE_NMS_TOP_N, rpn_nms_thres=cfg.TEST.RPN_NMS_THRESH, ) net.external_input.extend([ext_input]) return [gen_proposals_op] @op_filter(input_has='rois') def convert_rpn_rois(op): for j in range(0, len(op.input)): if op.input[j] == 'rois': print('Converting op {} input name: rois -> rpn_rois:\n{}'. format(op.type, op)) op.input[j] = 'rpn_rois' return [op] @op_filter(type_in=['StopGradient', 'Alias']) def convert_remove_op(op): print('Removing op {}:\n{}'.format(op.type, op)) return [] convert_op_in_proto(net, convert_op_name) convert_op_in_proto( net, [convert_gen_proposal, convert_rpn_rois, convert_remove_op]) reset_names(net.external_input) reset_names(net.external_output) reset_blob_names(blobs)
def convert_model_gpu(args, net, init_net): assert args.device == 'gpu' ret_net = copy.deepcopy(net) ret_init_net = copy.deepcopy(init_net) cdo_cuda = mutils.get_device_option_cuda() cdo_cpu = mutils.get_device_option_cpu() CPU_OPS = [ ["CollectAndDistributeFpnRpnProposals", None], ["GenerateProposals", None], ["BBoxTransform", None], ["BoxWithNMSLimit", None], ] CPU_BLOBS = ["im_info", "anchor"] @op_filter() def convert_op_gpu(op): for x in CPU_OPS: if mutils.filter_op(op, type=x[0], inputs=x[1]): return None op.device_option.CopyFrom(cdo_cuda) return [op] @op_filter() def convert_init_op_gpu(op): if op.output[0] in CPU_BLOBS: op.device_option.CopyFrom(cdo_cpu) else: op.device_option.CopyFrom(cdo_cuda) return [op] convert_op_in_proto(ret_init_net.Proto(), convert_init_op_gpu) convert_op_in_proto(ret_net.Proto(), convert_op_gpu) ret = core.InjectDeviceCopiesAmongNets([ret_init_net, ret_net]) return [ret[0][1], ret[0][0]]
def convert_net(args, net, blobs): @op_filter() def convert_op_name(op): if args.device != 'gpu': if op.engine != 'DEPTHWISE_3x3': op.engine = '' op.device_option.CopyFrom(caffe2_pb2.DeviceOption()) reset_names(op.input) reset_names(op.output) return [op] @op_filter(type='Python') def convert_python(op): if op.name.startswith('GenerateProposalsOp'): gen_proposals_op, ext_input = convert_gen_proposals( op, blobs, rpn_min_size=float(cfg.TEST.RPN_MIN_SIZE), rpn_post_nms_topN=cfg.TEST.RPN_POST_NMS_TOP_N, rpn_pre_nms_topN=cfg.TEST.RPN_PRE_NMS_TOP_N, rpn_nms_thresh=cfg.TEST.RPN_NMS_THRESH, ) net.external_input.extend([ext_input]) return [gen_proposals_op] elif op.name.startswith('CollectAndDistributeFpnRpnProposalsOp'): collect_dist_op = convert_collect_and_distribute( op, blobs, roi_canonical_scale=cfg.FPN.ROI_CANONICAL_SCALE, roi_canonical_level=cfg.FPN.ROI_CANONICAL_LEVEL, roi_max_level=cfg.FPN.ROI_MAX_LEVEL, roi_min_level=cfg.FPN.ROI_MIN_LEVEL, rpn_max_level=cfg.FPN.RPN_MAX_LEVEL, rpn_min_level=cfg.FPN.RPN_MIN_LEVEL, rpn_post_nms_topN=cfg.TEST.RPN_POST_NMS_TOP_N, ) return [collect_dist_op] else: raise ValueError('Failed to convert Python op {}'.format( op.name)) # Only convert UpsampleNearest to ResizeNearest when converting to pb so that the existing models is unchanged # https://github.com/facebookresearch/Detectron/pull/372#issuecomment-410248561 @op_filter(type='UpsampleNearest') def convert_upsample_nearest(op): for arg in op.arg: if arg.name == 'scale': scale = arg.i break else: raise KeyError('No attribute "scale" in UpsampleNearest op') resize_nearest_op = core.CreateOperator('ResizeNearest', list(op.input), list(op.output), name=op.name, width_scale=float(scale), height_scale=float(scale)) return resize_nearest_op @op_filter() def convert_rpn_rois(op): for j in range(len(op.input)): if op.input[j] == 'rois': print('Converting op {} input name: rois -> rpn_rois:\n{}'.format( op.type, op)) op.input[j] = 'rpn_rois' for j in range(len(op.output)): if op.output[j] == 'rois': print('Converting op {} output name: rois -> rpn_rois:\n{}'.format( op.type, op)) op.output[j] = 'rpn_rois' return [op] @op_filter(type_in=['StopGradient', 'Alias']) def convert_remove_op(op): print('Removing op {}:\n{}'.format(op.type, op)) return [] # We want to apply to all operators, including converted # so run separately convert_op_in_proto(net, convert_remove_op) convert_op_in_proto(net, convert_upsample_nearest) convert_op_in_proto(net, convert_python) convert_op_in_proto(net, convert_op_name) convert_op_in_proto(net, convert_rpn_rois) reset_names(net.external_input) reset_names(net.external_output) reset_blob_names(blobs)