|
23 | 23 | 'SigmoidBinaryCrossEntropyLoss', 'SigmoidBCELoss',
|
24 | 24 | 'SoftmaxCrossEntropyLoss', 'SoftmaxCELoss',
|
25 | 25 | 'KLDivLoss', 'CTCLoss', 'HuberLoss', 'HingeLoss',
|
26 |
| - 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss'] |
| 26 | + 'SquaredHingeLoss', 'LogisticLoss', 'TripletLoss', 'PoissonNLLLoss'] |
27 | 27 |
|
| 28 | +import numpy as np |
28 | 29 | from .. import ndarray
|
29 | 30 | from ..base import numeric_types
|
30 | 31 | from .block import HybridBlock
|
@@ -706,3 +707,63 @@ def hybrid_forward(self, F, pred, positive, negative):
|
706 | 707 | axis=self._batch_axis, exclude=True)
|
707 | 708 | loss = F.relu(loss + self._margin)
|
708 | 709 | return _apply_weighting(F, loss, self._weight, None)
|
| 710 | + |
| 711 | + |
| 712 | +class PoissonNLLLoss(Loss): |
| 713 | + r"""For a target (Random Variable) in a Poisson distribution, the function calculates the Negative |
| 714 | + Log likelihood loss. |
| 715 | + PoissonNLLLoss measures the loss accrued from a poisson regression prediction made by the model. |
| 716 | +
|
| 717 | + .. math:: |
| 718 | + L = \text{pred} - \text{target} * \log(\text{pred}) +\log(\text{target!}) |
| 719 | +
|
| 720 | + `pred`, `target` can have arbitrary shape as long as they have the same number of elements. |
| 721 | +
|
| 722 | + Parameters |
| 723 | + ---------- |
| 724 | + from_logits : boolean, default True |
| 725 | + indicating whether log(predicted) value has already been computed. If True, the loss is computed as |
| 726 | + :math:`\exp(\text{pred}) - \text{target} * \text{pred}`, and if False, then loss is computed as |
| 727 | + :math:`\text{pred} - \text{target} * \log(\text{pred}+\text{epsilon})`.The default value |
| 728 | + weight : float or None |
| 729 | + Global scalar weight for loss. |
| 730 | + batch_axis : int, default 0 |
| 731 | + The axis that represents mini-batch. |
| 732 | + compute_full: boolean, default False |
| 733 | + Indicates whether to add an approximation(Stirling factor) for the Factorial term in the formula for the loss. |
| 734 | + The Stirling factor is: |
| 735 | + :math:`\text{target} * \log(\text{target}) - \text{target} + 0.5 * \log(2 * \pi * \text{target})` |
| 736 | + epsilon: float, default 1e-08 |
| 737 | + This is to avoid calculating log(0) which is not defined. |
| 738 | +
|
| 739 | +
|
| 740 | + Inputs: |
| 741 | + - **pred**: Predicted value |
| 742 | + - **target**: Random variable(count or number) which belongs to a Poisson distribution. |
| 743 | + - **sample_weight**: element-wise weighting tensor. Must be broadcastable |
| 744 | + to the same shape as pred. For example, if pred has shape (64, 10) |
| 745 | + and you want to weigh each sample in the batch separately, |
| 746 | + sample_weight should have shape (64, 1). |
| 747 | +
|
| 748 | + Outputs: |
| 749 | + - **loss**: Average loss (shape=(1,1)) of the loss tensor with shape (batch_size,). |
| 750 | + """ |
| 751 | + def __init__(self, weight=None, from_logits=True, batch_axis=0, compute_full=False, **kwargs): |
| 752 | + super(PoissonNLLLoss, self).__init__(weight, batch_axis, **kwargs) |
| 753 | + self._from_logits = from_logits |
| 754 | + self._compute_full = compute_full |
| 755 | + |
| 756 | + def hybrid_forward(self, F, pred, target, sample_weight=None, epsilon=1e-08): |
| 757 | + target = _reshape_like(F, target, pred) |
| 758 | + if self._from_logits: |
| 759 | + loss = F.exp(pred) - target * pred |
| 760 | + else: |
| 761 | + loss = pred - target * F.log(pred + epsilon) |
| 762 | + if self._compute_full: |
| 763 | + # Using numpy's pi value |
| 764 | + stirling_factor = target * F.log(target)- target + 0.5 * F.log(2 * target * np.pi) |
| 765 | + target_gt_1 = target > 1 |
| 766 | + stirling_factor *= target_gt_1 |
| 767 | + loss += stirling_factor |
| 768 | + loss = _apply_weighting(F, loss, self._weight, sample_weight) |
| 769 | + return F.mean(loss) |
0 commit comments