| 93 | |
| 94 | |
| 95 | class ResNetC4Model(GeneralizedRCNN): |
| 96 | def inputs(self): |
| 97 | ret = [ |
| 98 | tf.TensorSpec((None, None, 3), tf.float32, 'image'), |
| 99 | tf.TensorSpec((None, None, cfg.RPN.NUM_ANCHOR), tf.int32, 'anchor_labels'), |
| 100 | tf.TensorSpec((None, None, cfg.RPN.NUM_ANCHOR, 4), tf.float32, 'anchor_boxes'), |
| 101 | tf.TensorSpec((None, 4), tf.float32, 'gt_boxes'), |
| 102 | tf.TensorSpec((None,), tf.int64, 'gt_labels')] # all > 0 |
| 103 | if cfg.MODE_MASK: |
| 104 | ret.append( |
| 105 | tf.TensorSpec((None, None, None), tf.uint8, 'gt_masks_packed') |
| 106 | ) # NR_GT x height x ceil(width/8), packed groundtruth masks |
| 107 | return ret |
| 108 | |
| 109 | def backbone(self, image): |
| 110 | return [resnet_c4_backbone(image, cfg.BACKBONE.RESNET_NUM_BLOCKS[:3])] |
| 111 | |
| 112 | def rpn(self, image, features, inputs): |
| 113 | featuremap = features[0] |
| 114 | rpn_label_logits, rpn_box_logits = rpn_head('rpn', featuremap, cfg.RPN.HEAD_DIM, cfg.RPN.NUM_ANCHOR) |
| 115 | anchors = RPNAnchors( |
| 116 | get_all_anchors( |
| 117 | stride=cfg.RPN.ANCHOR_STRIDE, sizes=cfg.RPN.ANCHOR_SIZES, |
| 118 | ratios=cfg.RPN.ANCHOR_RATIOS, max_size=cfg.PREPROC.MAX_SIZE), |
| 119 | inputs['anchor_labels'], inputs['anchor_boxes']) |
| 120 | anchors = anchors.narrow_to(featuremap) |
| 121 | |
| 122 | image_shape2d = tf.shape(image)[2:] # h,w |
| 123 | pred_boxes_decoded = anchors.decode_logits(rpn_box_logits) # fHxfWxNAx4, floatbox |
| 124 | proposal_boxes, proposal_scores = generate_rpn_proposals( |
| 125 | tf.reshape(pred_boxes_decoded, [-1, 4]), |
| 126 | tf.reshape(rpn_label_logits, [-1]), |
| 127 | image_shape2d, |
| 128 | cfg.RPN.TRAIN_PRE_NMS_TOPK if self.training else cfg.RPN.TEST_PRE_NMS_TOPK, |
| 129 | cfg.RPN.TRAIN_POST_NMS_TOPK if self.training else cfg.RPN.TEST_POST_NMS_TOPK) |
| 130 | |
| 131 | if self.training: |
| 132 | losses = rpn_losses( |
| 133 | anchors.gt_labels, anchors.encoded_gt_boxes(), rpn_label_logits, rpn_box_logits) |
| 134 | else: |
| 135 | losses = [] |
| 136 | |
| 137 | return BoxProposals(proposal_boxes), losses |
| 138 | |
| 139 | def roi_heads(self, image, features, proposals, targets): |
| 140 | image_shape2d = tf.shape(image)[2:] # h,w |
| 141 | featuremap = features[0] |
| 142 | |
| 143 | gt_boxes, gt_labels, *_ = targets |
| 144 | |
| 145 | if self.training: |
| 146 | # sample proposal boxes in training |
| 147 | proposals = sample_fast_rcnn_targets(proposals.boxes, gt_boxes, gt_labels) |
| 148 | # The boxes to be used to crop RoIs. |
| 149 | # Use all proposal boxes in inference |
| 150 | |
| 151 | boxes_on_featuremap = proposals.boxes * (1.0 / cfg.RPN.ANCHOR_STRIDE) |
| 152 | roi_resized = roi_align(featuremap, boxes_on_featuremap, 14) |
no outgoing calls
no test coverage detected