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()
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)
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)
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()
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))
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
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))