def testCorrectBatchSize(self): config = EasyDict({ 'foreground_threshold': 0.5, 'background_threshold_high': 0.5, # Use zero to get all non matching as backgrounds. 'background_threshold_low': 0.0, 'foreground_fraction': 0.5, # We change the minibatch_size the catch all our foregrounds 'minibatch_size': 64, }) gt_boxes = tf.constant([ [10, 10, 20, 20, 0] ], dtype=tf.float32) proposed_boxes_backgrounds = [[21, 21, 30, 30]] * 100 proposed_boxes_foreground = [[11, 11, 19, 19]] * 100 proposed_boxes = tf.constant( proposed_boxes_backgrounds + proposed_boxes_foreground, dtype=tf.float32 ) model = RCNNTarget(self._num_classes, config, seed=0) (proposals_label, bbox_targets) = self._run_rcnn_target( model, gt_boxes, proposed_boxes ) self.assertEqual( proposals_label[proposals_label >= 0].shape[0], config.minibatch_size )
def testBboxTargetConsistency(self): """Tests that bbox_targets is consistent with proposals_label. That means we test that we have the same number of elements in bbox_targets and proposals_label, and that only the proposals marked with a class are assigned a non-zero bbox_target. """ config = EasyDict({ 'foreground_threshold': 0.5, 'background_threshold_high': 0.5, 'background_threshold_low': 0, # use 0 to get complete batch 'foreground_fraction': 0.5, # We change the minibatch_size the catch all our foregrounds 'minibatch_size': 8, }) model = RCNNTarget(self._num_classes, config, seed=0) gt_boxes = tf.constant( [(200, 300, 250, 390, self._placeholder_label)], dtype=tf.float32 ) proposed_boxes = tf.constant( [ (12, 70, 350, 540), # noise (190, 310, 240, 370), # IoU: 0.4763 (197, 300, 252, 389), # IoU: 0.9015 (196, 300, 252, 389), # IoU: 0.8859 (197, 303, 252, 394), # IoU: 0.8459 (180, 310, 235, 370), # IoU: 0.3747 (0, 0, 400, 400), # noise (197, 302, 252, 389), # IoU: 0.8832 (0, 0, 400, 400), # noise ], dtype=tf.float32 ) (proposals_label, bbox_targets) = self._run_rcnn_target( model, gt_boxes, proposed_boxes ) foreground_idxs = np.nonzero(proposals_label >= 1) non_empty_bbox_target_idxs = np.nonzero(np.any(bbox_targets, axis=1)) self.assertAllEqual( foreground_idxs, non_empty_bbox_target_idxs ) self.assertGreater(proposals_label[proposals_label >= 1].shape[0], 0) self.assertEqual( proposals_label[proposals_label >= 0].shape[0], config.minibatch_size )
def _instantiate_layers(self): """ 定义两个全连接层和后面的分类回归层 :return: 无 """ # We define layers as an array since they are simple fully connected # ones and it should be easy to tune it from the network config. # 定义两个全连接层, layer_size表示输出通道数 self._layers = [ snt.Linear( layer_size, name='fc_{}'.format(i), initializers={'w': self._rcnn_initializer}, regularizers={'w': self.regularizer}, ) for i, layer_size in enumerate(self._layer_sizes) ] # We define the classifier layer having a num_classes + 1 background # since we want to be able to predict if the proposal is background as # well. # 定义一个分类的全连接层(21类) self._classifier_layer = snt.Linear( self._num_classes + 1, name='fc_classifier', initializers={'w': self._cls_initializer}, regularizers={'w': self.regularizer}, ) # The bounding box adjustment layer has 4 times the number of classes # We choose which to use depending on the output of the classifier # layer # 输出通道数为类别数目x4, 也就是4x20, 每个类别对应4个值, 这个是独立于分类器的输出 self._bbox_layer = snt.Linear( self._num_classes * 4, name='fc_bbox', initializers={'w': self._bbox_initializer}, regularizers={'w': self.regularizer}) # ROIPoolingLayer is used to extract the feature from the feature map # using the proposals. # self._config.roi表示的就是选择crop, 7x7, valid的池化配置 self._roi_pool = ROIPoolingLayer(self._config.roi, debug=self._debug) # RCNNTarget is used to define a minibatch and the correct values for # each of the proposals. # 用来定义minibatch和提案的正确值 self._rcnn_target = RCNNTarget(self._num_classes, self._config.target, variances=self._variances, seed=self._seed) # RCNNProposal generates the final bounding boxes and tries to remove # duplicates. self._rcnn_proposal = RCNNProposal(self._num_classes, self._config.proposals, variances=self._variances)
def testOddMinibatchSize(self): """Tests we're getting the right results when there's an odd minibatch size. """ config = EasyDict({ "foreground_threshold": 0.5, "background_threshold_high": 0.5, "background_threshold_low": 0.1, "foreground_fraction": 0.5, "minibatch_size": 5, }) model = RCNNTarget(self._num_classes, config, seed=0) gt_boxes = tf.constant([(200, 300, 250, 390, self._placeholder_label)], dtype=tf.float32) proposed_boxes = tf.constant( [ (12, 70, 350, 540), # noise (190, 310, 240, 370), # IoU: 0.4763 (197, 300, 252, 389), # IoU: 0.9015 (196, 300, 252, 389), # IoU: 0.8859 (197, 303, 252, 394), # IoU: 0.8459 (180, 310, 235, 370), # IoU: 0.3747 (0, 0, 400, 400), # noise (197, 302, 252, 389), # IoU: 0.8832 (180, 310, 235, 370), # IoU: 0.3747 (180, 310, 235, 370), # IoU: 0.3747 (0, 0, 400, 400), # noise ], dtype=tf.float32, ) (proposals_label, bbox_targets) = self._run_rcnn_target(model, gt_boxes, proposed_boxes) foreground_number = proposals_label[proposals_label >= 1].shape[0] background_number = proposals_label[proposals_label == 0].shape[0] foreground_fraction = config.foreground_fraction minibatch_size = config.minibatch_size self.assertLessEqual(foreground_number, np.floor(foreground_fraction * minibatch_size)) self.assertGreater(foreground_number, 0) self.assertLessEqual(background_number, minibatch_size - foreground_number) self.assertEqual(proposals_label[proposals_label >= 0].shape[0], config.minibatch_size)
def testLabelPriority(self): """Tests we're prioritizing being the best proposal for a gt_box in label selection. """ first_label = self._placeholder_label second_label = self._placeholder_label + 1 num_classes = second_label + 10 # We need a custom config to have a larger minibatch_size. config = EasyDict({ 'foreground_threshold': 0.5, 'background_threshold_high': 0.5, # Use zero to get all non matching as backgrounds. 'background_threshold_low': 0.0, 'foreground_fraction': 0.5, # We change the minibatch_size the catch all our foregrounds 'minibatch_size': 64, }) model = RCNNTarget(num_classes, config, seed=0) gt_boxes = tf.constant([ [10, 10, 20, 20, first_label], [10, 10, 30, 30, second_label] ], dtype=tf.float32) # Both proposals have the first gt_box as the best match, but one of # them should be assigned to the label of the second gt_box anyway. proposed_boxes = tf.constant([ [10, 10, 20, 20], [12, 10, 20, 20], ], dtype=tf.float32) (proposals_label, _) = self._run_rcnn_target( model, gt_boxes, proposed_boxes ) num_first_label = len( proposals_label[proposals_label == first_label + 1] ) num_second_label = len( proposals_label[proposals_label == second_label + 1] ) # Assertions self.assertEqual(num_first_label, 1) self.assertEqual(num_second_label, 1)
def testMultipleGtBoxes(self): """Tests we're getting the right labels when there's several gt_boxes. """ num_classes = 3 config = EasyDict({ 'foreground_threshold': 0.5, 'background_threshold_high': 0.5, 'background_threshold_low': 0.1, 'foreground_fraction': 0.5, # We change the minibatch_size the catch all our foregrounds 'minibatch_size': 18, }) model = RCNNTarget(num_classes, config, seed=0) gt_boxes = tf.constant( [ (10, 0, 398, 399, 0), (200, 300, 250, 390, 1), (185, 305, 235, 372, 2), ], dtype=tf.float32 ) proposed_boxes = tf.constant( [ (12, 70, 350, 540), # noise (190, 310, 240, 370), # 2 (197, 300, 252, 389), # 1 (196, 300, 252, 389), # 1 (197, 303, 252, 394), # 1 (180, 310, 235, 370), # 2 (0, 0, 400, 400), # 0 (197, 302, 252, 389), # 1 (0, 0, 400, 400), # 0 ], dtype=tf.float32 ) (proposals_label, bbox_targets) = self._run_rcnn_target( model, gt_boxes, proposed_boxes ) # We don't care much about the first value. self.assertAllClose( proposals_label[1:], # We sum one to normalize for RCNNTarget's results. np.add([2., 1., 1., 1., 2., 0., 1., 0.], 1), self._equality_delta )
def _instantiate_layers(self): # We define layers as an array since they are simple fully connected # ones and it should be easy to tune it from the network config. self._layers = [ snt.Linear( layer_size, name="fc_{}".format(i), initializers={"w": self._rcnn_initializer}, regularizers={"w": self.regularizer}, ) for i, layer_size in enumerate(self._layer_sizes) ] # We define the classifier layer having a num_classes + 1 background # since we want to be able to predict if the proposal is background as # well. self._classifier_layer = snt.Linear( self._num_classes + 1, name="fc_classifier", initializers={"w": self._cls_initializer}, regularizers={"w": self.regularizer}, ) # The bounding box adjustment layer has 4 times the number of classes # We choose which to use depending on the output of the classifier # layer self._bbox_layer = snt.Linear( self._num_classes * 4, name="fc_bbox", initializers={"w": self._bbox_initializer}, regularizers={"w": self.regularizer}, ) # ROIPoolingLayer is used to extract the feature from the feature map # using the proposals. self._roi_pool = ROIPoolingLayer(self._config.roi, debug=self._debug) # RCNNTarget is used to define a minibatch and the correct values for # each of the proposals. self._rcnn_target = RCNNTarget( self._num_classes, self._config.target, variances=self._variances, seed=self._seed, ) # RCNNProposal generates the final bounding boxes and tries to remove # duplicates. self._rcnn_proposal = RCNNProposal( self._num_classes, self._config.proposals, variances=self._variances )
def setUp(self): super(RCNNTargetTest, self).setUp() # We don't care about the class labels or the batch number in most of # these tests. self._num_classes = 5 self._placeholder_label = 3. self._config = EasyDict({ 'foreground_threshold': 0.5, 'background_threshold_high': 0.5, 'background_threshold_low': 0.1, 'foreground_fraction': 0.5, 'minibatch_size': 2, }) # We check for a difference smaller than this numbers in our tests # instead of checking for exact equality. self._equality_delta = 1e-03 self._shared_model = RCNNTarget( self._num_classes, self._config, seed=0 ) tf.reset_default_graph()