Ejemplo n.º 1
0
    def focal_loss(self, label, conf):
        alpha = self.alpha
        gamma = self.gamma

        num_class = conf.size(2)

        one_hot = torch.eye(num_class)

        if torch.cuda.is_available():
            one_hot = one_hot.cuda()

        # ignore ambiguious samples
        mask = label >= 0

        label = label[mask]
        conf = conf[mask]

        tf_map = one_hot[label][..., 1:]
        conf = conf[..., 1:]

        # calculate focal loss
        score = conf.sigmoid()

        p_t = tf_map * score + (1 - tf_map) * (1. - score)
        alpha = tf_map * alpha + (1 - tf_map) * (1. - alpha)

        weight = torch.pow(1. - p_t, gamma) * alpha

        # conf.sigmoid() is applied in binary_cross_entropy_with_logits
        loss = F.binary_cross_entropy_with_logits(conf,
                                                  tf_map,
                                                  weight.detach(),
                                                  reduction='sum')

        return loss / mask.sum()
Ejemplo n.º 2
0
    def focal_loss(self, label, logit):
        num_class = logit.size(2)

        alpha = self.alpha
        gamma = self.gamma

        one_hot = torch.eye(num_class + 1).to(logit.device)

        # ignore ambiguious samples
        mask = label >= 0

        label = label[mask]
        logit = logit[mask]

        target = one_hot[label][..., 1:]

        # calculate focal loss
        p = logit.sigmoid()
        neg_target = 1. - target

        p_t = target * p + neg_target * (1. - p)
        alpha = target * alpha + neg_target * (1. - alpha)

        modulator = torch.pow(1. - p_t, gamma)

        # logit.sigmoid() is applied in binary_cross_entropy_with_logits
        loss = F.binary_cross_entropy_with_logits(logit, target,
                                                  reduction='none')

        return torch.sum(alpha * modulator * loss)
Ejemplo n.º 3
0
    def __call__(self, anchors, objectness, box_regression, targets):
        """
        Arguments:
            anchors (list[BoxList])
            objectness (list[Tensor])
            box_regression (list[Tensor])
            targets (list[BoxList])

        Returns:
            rpn_obj_loss (Tensor)
            box_loss (Tensor
        """
        anchors = [cat_boxlist(anchors_per_image) for anchors_per_image in anchors]
        labels, regression_targets = self.prepare_targets(anchors, targets)
        if not self.sampling_free:
            sampled_pos_inds, sampled_neg_inds = self.fg_bg_sampler(labels)
            sampled_pos_inds = torch.nonzero(torch.cat(sampled_pos_inds, dim=0)).squeeze(1)
            sampled_neg_inds = torch.nonzero(torch.cat(sampled_neg_inds, dim=0)).squeeze(1)
            sampled_inds = torch.cat([sampled_pos_inds, sampled_neg_inds], dim=0)
        
        objectness, box_regression = \
                concat_box_prediction_layers(objectness, box_regression)
        
        objectness = objectness.squeeze()

        labels = torch.cat(labels, dim=0)
        regression_targets = torch.cat(regression_targets, dim=0)
        
        if self.sampling_free:
            positive, valid = labels > 0, labels >= 0
            rpn_loc_loss = 0.5 * smooth_l1_loss(
                box_regression[positive],
                regression_targets[positive],
                beta=1.0 / 9,
                size_average=True,
            ) 

            rpn_obj_loss = self.ce_loss(objectness[valid].view(-1,1), 
                labels[valid].int().view(-1, 1)) / positive.sum()
            
            with torch.no_grad():
                ratio = rpn_loc_loss / rpn_obj_loss
            rpn_obj_loss = ratio * rpn_obj_loss
    
        else:
            rpn_loc_loss = smooth_l1_loss(
                box_regression[sampled_pos_inds],
                regression_targets[sampled_pos_inds],
                beta=1.0 / 9,
                size_average=False,
            ) / (sampled_inds.numel())
            
            rpn_obj_loss = F.binary_cross_entropy_with_logits(
                objectness[sampled_inds], labels[sampled_inds]
            )

        return dict(rpn_obj_loss=rpn_obj_loss, rpn_loc_loss=rpn_loc_loss)
Ejemplo n.º 4
0
    def forward(self, logit, truth):
        logit = logit.view(-1)
        truth = truth.view(-1)
        assert (logit.shape == truth.shape)

        loss = F.binary_cross_entropy_with_logits(logit,
                                                  truth,
                                                  reduction='none')

        return loss.mean()
Ejemplo n.º 5
0
 def __call__(self, scores2d, ious2d):
     #  clamp()的参数
     # input (Tensor) – 输入张量
     # min (Number) – 限制范围下限
     # max (Number) – 限制范围上限
     # out (Tensor, optional) – 输出张量
     # 下面语句的作用也就是将iou之外的置为0/1
     ious2d = self.scale(ious2d).clamp(0, 1)
     # binary_cross_entropy_with_logits
     # 接受任意形状的输入,target要求与输入形状一致。切记:target的值必须在[0,N-1]之间,
     # 其中N为类别数,否则会出现莫名其妙的错误,比如loss为负数。
     # 计算其实就是交叉熵,不过输入不要求在0,1之间,该函数会自动添加sigmoid运算
     # 默认的reduction方式为mean
     return F.binary_cross_entropy_with_logits(
         # mask_select会将满足mask(掩码、遮罩等等,随便翻译)的指示,将满足条件的点选出来
         # 根据掩码张量mask中的二元值,取输入张量中的指定项( mask为一个 ByteTensor),将取值返回到一个新的1D张量,
         # 张量 mask须跟input张量有相同数量的元素数目,但形状或维度不需要相同。
         # 注意: 返回的张量不与原始张量共享内存空间。
         # !!!! 输出的为一维向量
         scores2d.masked_select(self.mask2d),
         ious2d.masked_select(self.mask2d))
Ejemplo n.º 6
0
    def __call__(self, scores2d, ious2d):
        B = ious2d.shape[0]
        ious2d = self.scale(ious2d).clamp(0, 1)
        """
        loss = F.binary_cross_entropy_with_logits(
            scores2d.masked_select(self.mask2d), 
            ious2d.masked_select(self.mask2d),
            reduction='none'
        ).reshape(B,-1)
        sample_weight = torch.empty(B, device='cuda')
        for b in range(B):
            iou2d = ious2d[b]
            indices = torch.nonzero((iou2d==torch.max(iou2d)))[0]
            # Inverted frequency
            sample_weight[b] = torch.log(self.ilf_sum / torch.log(self.frequency[indices[0], indices[1]]))
        loss = loss * sample_weight[:,None]
        loss = loss.mean()
        """
        loss = F.binary_cross_entropy_with_logits(
            scores2d.masked_select(self.mask2d),
            ious2d.masked_select(self.mask2d))

        return loss
Ejemplo n.º 7
0
 def __call__(self, scores2d, ious2d):
     ious2d = self.scale(ious2d).clamp(0, 1)
     return F.binary_cross_entropy_with_logits(
         scores2d.masked_select(self.mask2d),
         ious2d.masked_select(self.mask2d))