| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| from __future__ import absolute_import |
| from __future__ import division |
| from __future__ import print_function |
|
|
| import paddle |
|
|
| from ppdet.core.workspace import register, serializable |
|
|
| __all__ = ['CTFocalLoss'] |
|
|
|
|
| @register |
| @serializable |
| class CTFocalLoss(object): |
| """ |
| CTFocalLoss: CornerNet & CenterNet Focal Loss |
| Args: |
| loss_weight (float): loss weight |
| gamma (float): gamma parameter for Focal Loss |
| """ |
|
|
| def __init__(self, loss_weight=1., gamma=2.0): |
| self.loss_weight = loss_weight |
| self.gamma = gamma |
|
|
| def __call__(self, pred, target): |
| """ |
| Calculate the loss |
| Args: |
| pred (Tensor): heatmap prediction |
| target (Tensor): target for positive samples |
| Return: |
| ct_focal_loss (Tensor): Focal Loss used in CornerNet & CenterNet. |
| Note that the values in target are in [0, 1] since gaussian is |
| used to reduce the punishment and we treat [0, 1) as neg example. |
| """ |
| fg_map = paddle.cast(target == 1, 'float32') |
| fg_map.stop_gradient = True |
| bg_map = paddle.cast(target < 1, 'float32') |
| bg_map.stop_gradient = True |
|
|
| neg_weights = paddle.pow(1 - target, 4) |
| pos_loss = 0 - paddle.log(pred) * paddle.pow(1 - pred, |
| self.gamma) * fg_map |
|
|
| neg_loss = 0 - paddle.log(1 - pred) * paddle.pow( |
| pred, self.gamma) * neg_weights * bg_map |
| pos_loss = paddle.sum(pos_loss) |
| neg_loss = paddle.sum(neg_loss) |
|
|
| fg_num = paddle.sum(fg_map) |
| ct_focal_loss = (pos_loss + neg_loss) / ( |
| fg_num + paddle.cast(fg_num == 0, 'float32')) |
| return ct_focal_loss * self.loss_weight |
|
|