MCPcopy Create free account
hub / github.com/NVIDIA/TensorRT / roi_heads

Method roi_heads

samples/python/detectron2/create_onnx.py:410–511  ·  view source on GitHub ↗

Updates the graph to replace all ROIAlign Caffe ops with one single pyramid ROIAlign. Eliminates CollectRpnProposals DistributeFpnProposals and BatchPermutation nodes that are not supported by TensorRT. Connects pyramid ROIAlign to box_head and connects box_head

(rpn_outputs, p2, p3, p4, p5, second_nms_threshold)

Source from the content-addressed store, hash-verified

408 return nms_outputs
409
410 def roi_heads(rpn_outputs, p2, p3, p4, p5, second_nms_threshold):
411 """
412 Updates the graph to replace all ROIAlign Caffe ops with one single pyramid ROIAlign. Eliminates CollectRpnProposals
413 DistributeFpnProposals and BatchPermutation nodes that are not supported by TensorRT. Connects pyramid ROIAlign to box_head
414 and connects box_head to final box head outputs in a form of second NMS. In order to implement mask head outputs,
415 similar steps as in box_pooler are performed to replace mask_pooler. Finally, reimplemented mask_pooler is connected to
416 mask_head and mask head outputs are produced.
417 :param rpn_outputs: Outputs of the first NMS/proposal generator.
418 :param p2: Output of p2 feature map, required for ROIAlign operation.
419 :param p3: Output of p3 feature map, required for ROIAlign operation.
420 :param p4: Output of p4 feature map, required for ROIAlign operation.
421 :param p5: Output of p5 feature map, required for ROIAlign operation.
422 :param second_nms_threshold: Override the 2nd NMS score threshold value. If set to None, use the value in the graph.
423 """
424 # Create ROIAlign node.
425 box_pooler_output = self.ROIAlign(rpn_outputs[1], p2, p3, p4, p5, self.first_ROIAlign_pooled_size, self.first_ROIAlign_sampling_ratio, self.first_ROIAlign_type, self.first_NMS_max_proposals, 'box_pooler')
426
427 # Reshape node that prepares ROIAlign/box pooler output for Gemm node that comes next.
428 box_pooler_shape = np.asarray([-1, self.fpn_out_channels*self.first_ROIAlign_pooled_size*self.first_ROIAlign_pooled_size], dtype=np.int64)
429 box_pooler_reshape = self.graph.op_with_const("Reshape", "box_pooler/reshape", box_pooler_output, box_pooler_shape)
430
431 # Get first Gemm op of box head and connect box pooler to it.
432 first_box_head_gemm = self.graph.find_node_by_op_name("Gemm", "/roi_heads/box_head/fc1/Gemm")
433 first_box_head_gemm.inputs[0] = box_pooler_reshape[0]
434
435 # Get final two nodes of box predictor. Softmax op for cls_score, Gemm op for bbox_pred.
436 cls_score = self.graph.find_node_by_op_name("Softmax", "/roi_heads/Softmax")
437 bbox_pred = self.graph.find_node_by_op_name("Gemm", "/roi_heads/box_predictor/bbox_pred/Gemm")
438
439 # Linear transformation to convert box coordinates from (TopLeft, BottomRight) Corner encoding
440 # to CenterSize encoding. 1st NMS boxes are multiplied by transformation matrix in order to
441 # encode it into CenterSize format.
442 matmul_const = np.matrix('0.5 0 -1 0; 0 0.5 0 -1; 0.5 0 1 0; 0 0.5 0 1', dtype=np.float32)
443 matmul_out = self.graph.matmul("RPN_NMS/detection_boxes_conversion", rpn_outputs[1], matmul_const)
444
445 # Reshape node that prepares bbox_pred for scaling and second NMS.
446 bbox_pred_shape = np.asarray([self.batch_size, self.first_NMS_max_proposals, self.num_classes, 4], dtype=np.int64)
447 bbox_pred_reshape = self.graph.op_with_const("Reshape", "bbox_pred/reshape", bbox_pred.outputs[0], bbox_pred_shape)
448
449 # 0.1, 0.1, 0.2, 0.2 are localization head variance numbers, they scale bbox_pred_reshape, in order to get accurate coordinates.
450 scale_adj = np.expand_dims(np.asarray([0.1, 0.1, 0.2, 0.2], dtype=np.float32), axis=(0, 1))
451 final_bbox_pred = self.graph.op_with_const("Mul", "bbox_pred/scale", bbox_pred_reshape[0], scale_adj)
452
453 # Reshape node that prepares cls_score for slicing and second NMS.
454 cls_score_shape = np.array([self.batch_size, self.first_NMS_max_proposals, self.num_classes+1], dtype=np.int64)
455 cls_score_reshape = self.graph.op_with_const("Reshape", "cls_score/reshape", cls_score.outputs[0], cls_score_shape)
456
457 # Slice operation to adjust third dimension of cls_score tensor, deletion of background class (81 in Detectron 2).
458 final_cls_score = self.graph.slice("cls_score/slicer", cls_score_reshape[0], 0, self.num_classes, 2)
459
460 # Create NMS node.
461 nms_outputs = self.NMS(final_bbox_pred[0], final_cls_score[0], matmul_out[0], -1, False, self.second_NMS_max_proposals, self.second_NMS_iou_threshold, self.second_NMS_score_threshold, second_nms_threshold, 'box_outputs')
462
463 # Create ROIAlign node.
464 mask_pooler_output = self.ROIAlign(nms_outputs[1], p2, p3, p4, p5, self.second_ROIAlign_pooled_size, self.second_ROIAlign_sampling_ratio, self.second_ROIAlign_type, self.second_NMS_max_proposals, 'mask_pooler')
465
466 # Reshape mask pooler output.
467 mask_pooler_shape = np.asarray([self.second_NMS_max_proposals*self.batch_size, self.fpn_out_channels, self.second_ROIAlign_pooled_size, self.second_ROIAlign_pooled_size], dtype=np.int64)

Callers

nothing calls this directly

Calls 3

ROIAlignMethod · 0.95
NMSMethod · 0.95
appendMethod · 0.45

Tested by

no test coverage detected