amazon-science / omni-detr

PyTorch implementation of Omni-DETR for omni-supervised object detection: https://arxiv.org/abs/2203.16089
Other
64 stars 6 forks source link

The role of the 'indicators' ? #16

Open nhw649 opened 1 year ago

nhw649 commented 1 year ago

What is the role of the indicator in network propagation? I've found that apart from serving as an indicator during dataset partitioning, it has no effect when calculating loss and binary matching, as its value always remains 1.

if indicators == None:
    num_batch = outputs['pred_logits'].shape[0]
    indicators = [1 for i in range(num_batch)]
JacobBITLABS commented 11 months ago

In short: They are used in the indicator matrix of sigmoid_weighted_focal_loss() in models/segmentation.py to not penalize predictions without a pseudo label from the filter.

See in engine.py we have:

 samples = []
        samples.append(tensor_label_q)
        samples.append(tensor_label_k)
        samples.append(tensor_unlabel_q)

        targets_label_q.append(targets_label_k[0])
        targets_label_q.append(pseudo_label_k[0])
        targets = targets_label_q

        outputs = model_student(samples)

        indicators = []
        indicators.append(indicator_label[0])
        indicators.append(indicator_label[0])
        indicators.append(indicator_unlabel[0])

1) We construct a samples (images) array with strong, weak and unlabelled samples of strong aug. (remember, we stabalize training with labelled samples during semi-supervised stage), to parse to the Student. 2) Then on targets_label_q (strong augs) we append targets_label_k and pseudo_label_k, essentially creating the corresponding targets to enforce. 3) Similarly, we create indicators, to indicate which corresponding targets contains labelled ground truths for the samples. This is a bit tricky / counter-intiuive implementation, as we know pseudo_label_k contains (some) promoted labels, and now they are labelled as unlabelled (0).

However, look at the Criterion. Indicators is expected and the snippet you reference is a fallback to just enforce everything (1). During semi-supervised stageindicators != None.

Now look at loss_labels( ) in Criterion_semi:

      empty_indicators = []
        for i in range(len(indicators)):
            assert len(targets[i]['labels']) == len(targets[i]['boxes'])
            if len(targets[i]['labels']) > 0:
                empty_indicators.append(1)
            else:
                empty_indicators.append(0)

Here, an itertion over all of the indicators is evaluation wheather or not a corresponding target contains label, constructing empty_indicators (think of it as a boolean array), essentially overwriting the (0) from indicator_unlabel[0], if the pseudo label filter produced a pseudo-label for that prediction. If not, then (0) remains and that prediction was not promoted, hence should not be enforced in sigmoid_weighted_focal_loss().

nhw649 commented 11 months ago

In short: They are used in the indicator matrix of sigmoid_weighted_focal_loss() in models/segmentation.py to not penalize predictions without a pseudo label from the filter.

See in engine.py we have:

 samples = []
        samples.append(tensor_label_q)
        samples.append(tensor_label_k)
        samples.append(tensor_unlabel_q)

        targets_label_q.append(targets_label_k[0])
        targets_label_q.append(pseudo_label_k[0])
        targets = targets_label_q

        outputs = model_student(samples)

        indicators = []
        indicators.append(indicator_label[0])
        indicators.append(indicator_label[0])
        indicators.append(indicator_unlabel[0])
  1. We construct a samples (images) array with strong, weak and unlabelled samples of strong aug. (remember, we stabalize training with labelled samples during semi-supervised stage), to parse to the Student.
  2. Then on targets_label_q (strong augs) we append targets_label_k and pseudo_label_k, essentially creating the corresponding targets to enforce.
  3. Similarly, we create indicators, to indicate which corresponding targets contains labelled ground truths for the samples. This is a bit tricky / counter-intiuive implementation, as we know pseudo_label_k contains (some) promoted labels, and now they are labelled as unlabelled (0).

However, look at the Criterion. Indicators is expected and the snippet you reference is a fallback to just enforce everything (1). During semi-supervised stageindicators != None.

Now look at loss_labels( ) in Criterion_semi:

      empty_indicators = []
        for i in range(len(indicators)):
            assert len(targets[i]['labels']) == len(targets[i]['boxes'])
            if len(targets[i]['labels']) > 0:
                empty_indicators.append(1)
            else:
                empty_indicators.append(0)

Here, an itertion over all of the indicators is evaluation wheather or not a corresponding target contains label, constructing empty_indicators (think of it as a boolean array), essentially overwriting the (0) from indicator_unlabel[0], if the pseudo label filter produced a pseudo-label for that prediction. If not, then (0) remains and that prediction was not promoted, hence should not be enforced in sigmoid_weighted_focal_loss().

OK, thanks.