| 6 | |
| 7 | |
| 8 | class FocalLoss(torch.nn.Module): |
| 9 | def __init__( |
| 10 | self, |
| 11 | gamma: float = 1.0, |
| 12 | alpha: float = 0.5, |
| 13 | dynamic_balance: bool = False, |
| 14 | reduction: str = "mean", |
| 15 | ): |
| 16 | """ |
| 17 | let :math:`p_t = p` if target = 1, :math:`1-p` if target != 1 |
| 18 | |
| 19 | let :math:`a_t = a` if target = 1, :math:`1-p` if target != 1 |
| 20 | |
| 21 | focal loss = :math:`- a_t (1 - p_t)^{\gamma} log(p_t)` |
| 22 | |
| 23 | For details: https://arxiv.org/pdf/1708.02002.pdf |
| 24 | |
| 25 | Args: |
| 26 | gamma (float): |
| 27 | See class description. |
| 28 | alpha (float): |
| 29 | See class description. |
| 30 | dynamic_balance (bool): |
| 31 | If True, balance the classes. |
| 32 | reduction (str): |
| 33 | 'mean', 'none' |
| 34 | """ |
| 35 | super().__init__() |
| 36 | self.gamma = gamma |
| 37 | self.alpha = alpha |
| 38 | self.dynamic_balance = dynamic_balance |
| 39 | self.reduction = reduction |
| 40 | if self.reduction not in {"mean", "none"}: |
| 41 | raise ValueError(f"wrong reduction type {reduction}") |
| 42 | |
| 43 | def forward(self, logits: torch.Tensor, targets: torch.Tensor) -> torch.Tensor: |
| 44 | """ |
| 45 | Args: |
| 46 | logits (N, C): |
| 47 | tensor of logits. |
| 48 | targets (N, ): |
| 49 | :math:`targets_i \in {0,1}` |
| 50 | Returns: |
| 51 | (0,) |
| 52 | """ |
| 53 | BCE_loss = F.binary_cross_entropy_with_logits(logits, targets, reduction="none") |
| 54 | pt = torch.exp(-BCE_loss) # prevents nans when probability 0 |
| 55 | if self.dynamic_balance: |
| 56 | pos = torch.tensor(targets, dtype=torch.float, device=logits.device) |
| 57 | prob_pos = torch.mean(pos) |
| 58 | at = targets * prob_pos + (1 - targets) * (1.0 - prob_pos) |
| 59 | else: |
| 60 | at = targets * self.alpha + (1 - targets) * (1.0 - self.alpha) |
| 61 | loss = 2 * at * (1 - pt).pow(self.gamma) * BCE_loss |
| 62 | if self.reduction == "mean": |
| 63 | return loss.mean() |
| 64 | elif self.reduction == "none": |
| 65 | return loss |
no outgoing calls
no test coverage detected