def sigmoid_focal_loss(x, label, fg_num, gamma=2.0, alpha=0.25):
    '\n\t:alias_main: paddle.nn.functional.sigmoid_focal_loss\n\t:alias: paddle.nn.functional.sigmoid_focal_loss,paddle.nn.functional.loss.sigmoid_focal_loss\n\t:old_api: paddle.fluid.layers.sigmoid_focal_loss\n\n    **Sigmoid Focal Loss Operator.**\n\n    `Focal Loss <https://arxiv.org/abs/1708.02002>`_ is used to address the foreground-background\n    class imbalance existed on the training phase of many computer vision tasks. This OP computes\n    the sigmoid value for each element in the input tensor :attr:`x`, after which focal loss is\n    measured between the sigmoid value and target label. \n\n    The focal loss is given as followed:\n\n    .. math::\n  \n        \\mathop{loss_{i,\\,j}}\\limits_{i\\in\\mathbb{[0,\\,N-1]},\\,j\\in\\mathbb{[0,\\,C-1]}}=\\left\\{\n        \\begin{array}{rcl}\n        - \\frac{1}{fg\\_num} * \\alpha * {(1 - \\sigma(x_{i,\\,j}))}^{\\gamma} * \\log(\\sigma(x_{i,\\,j})) & & {(j +1) = label_{i,\\,0}} \\\\\n        - \\frac{1}{fg\\_num} * (1 - \\alpha) * {\\sigma(x_{i,\\,j})}^{ \\gamma} * \\log(1 - \\sigma(x_{i,\\,j})) & & {(j +1)!= label_{i,\\,0}}\n        \\end{array} \\right.\n\n\n    We know that\n    \n    .. math::\n        \\sigma(x_j) = \\frac{1}{1 + \\exp(-x_j)}\n\n\n    Args:\n        x(Variable): A 2-D tensor with shape :math:`[N, C]` represents the predicted categories of\n            all samples. :math:`N` is the number of all samples responsible for optimization in\n            a mini-batch, for example, samples are anchor boxes for object detection and :math:`N`\n            is the total number of positive and negative samples in a mini-batch; Samples are images\n            for image classification and :math:`N` is the number of images in a mini-batch. :math:`C`\n            is the number of classes (**Notice: excluding background**). The data type of :attr:`x` is\n            float32 or float64.\n        label(Variable): A 2-D tensor with shape :math:`[N, 1]` represents the target labels for\n            classification. :math:`N` is the number of all samples responsible for optimization in a\n            mini-batch, each sample has one target category. The values for positive samples are in the\n            range of :math:`[1, C]`, and the values for negative samples are 0. The data type of :attr:`label`\n            is int32.\n        fg_num(Variable): A 1-D tensor with shape [1] represents the number of positive samples in a\n            mini-batch, which should be obtained before this OP. The data type of :attr:`fg_num` is int32.\n        gamma(int|float): Hyper-parameter to balance the easy and hard examples. Default value is\n            set to 2.0.\n        alpha(int|float): Hyper-parameter to balance the positive and negative example. Default value\n            is set to 0.25.\n\n    Returns:\n        Variable(the data type is float32 or float64): \n            A 2-D tensor with shape :math:`[N, C]`, which is the focal loss of each element in the input\n            tensor :attr:`x`.\n\n    Examples:\n        .. code-block:: python\n\n            import numpy as np\n            import paddle.fluid as fluid\n            \n            num_classes = 10  # exclude background\n            image_width = 16\n            image_height = 16\n            batch_size = 32\n            max_iter = 20\n            \n            \n            def gen_train_data():\n                x_data = np.random.uniform(0, 255, (batch_size, 3, image_height,\n                                                    image_width)).astype(\'float64\')\n                label_data = np.random.randint(0, num_classes,\n                                               (batch_size, 1)).astype(\'int32\')\n                return {"x": x_data, "label": label_data}\n            \n            \n            def get_focal_loss(pred, label, fg_num, num_classes):\n                pred = fluid.layers.reshape(pred, [-1, num_classes])\n                label = fluid.layers.reshape(label, [-1, 1])\n                label.stop_gradient = True\n                loss = fluid.layers.sigmoid_focal_loss(\n                    pred, label, fg_num, gamma=2.0, alpha=0.25)\n                loss = fluid.layers.reduce_sum(loss)\n                return loss\n            \n            \n            def build_model(mode=\'train\'):\n                x = fluid.data(name="x", shape=[-1, 3, -1, -1], dtype=\'float64\')\n                output = fluid.layers.pool2d(input=x, pool_type=\'avg\', global_pooling=True)\n                output = fluid.layers.fc(\n                    input=output,\n                    size=num_classes,\n                    # Notice: size is set to be the number of target classes (excluding backgorund)\n                    # because sigmoid activation will be done in the sigmoid_focal_loss op.\n                    act=None)\n                if mode == \'train\':\n                    label = fluid.data(name="label", shape=[-1, 1], dtype=\'int32\')\n                    # Obtain the fg_num needed by the sigmoid_focal_loss op:\n                    # 0 in label represents background, >=1 in label represents foreground,\n                    # find the elements in label which are greater or equal than 1, then\n                    # computed the numbers of these elements.\n                    data = fluid.layers.fill_constant(shape=[1], value=1, dtype=\'int32\')\n                    fg_label = fluid.layers.greater_equal(label, data)\n                    fg_label = fluid.layers.cast(fg_label, dtype=\'int32\')\n                    fg_num = fluid.layers.reduce_sum(fg_label)\n                    fg_num.stop_gradient = True\n                    avg_loss = get_focal_loss(output, label, fg_num, num_classes)\n                    return avg_loss\n                else:\n                    # During evaluating or testing phase,\n                    # output of the final fc layer should be connected to a sigmoid layer.\n                    pred = fluid.layers.sigmoid(output)\n                    return pred\n            \n            \n            loss = build_model(\'train\')\n            moment_optimizer = fluid.optimizer.MomentumOptimizer(\n                learning_rate=0.001, momentum=0.9)\n            moment_optimizer.minimize(loss)\n            place = fluid.CPUPlace()\n            exe = fluid.Executor(place)\n            exe.run(fluid.default_startup_program())\n            for i in range(max_iter):\n                outs = exe.run(feed=gen_train_data(), fetch_list=[loss.name])\n                print(outs)\n    '
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'sigmoid_focal_loss')
    check_variable_and_dtype(label, 'label', ['int32'], 'sigmoid_focal_loss')
    check_variable_and_dtype(fg_num, 'fg_num', ['int32'], 'sigmoid_focal_loss')
    helper = LayerHelper('sigmoid_focal_loss', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    helper.append_op(type='sigmoid_focal_loss', inputs={'X': x, 'Label': label, 'FgNum': fg_num}, attrs={'gamma': gamma, 'alpha': alpha}, outputs={'Out': out})
    return out
:alias_main: paddle.nn.functional.sigmoid_focal_loss
    :alias: paddle.nn.functional.sigmoid_focal_loss,paddle.nn.functional.loss.sigmoid_focal_loss
    :old_api: paddle.fluid.layers.sigmoid_focal_loss

**Sigmoid Focal Loss Operator.**

`Focal Loss <https://arxiv.org/abs/1708.02002>`_ is used to address the foreground-background
class imbalance existed on the training phase of many computer vision tasks. This OP computes
the sigmoid value for each element in the input tensor :attr:`x`, after which focal loss is
measured between the sigmoid value and target label. 

The focal loss is given as followed:

.. math::

    \mathop{loss_{i,\,j}}\limits_{i\in\mathbb{[0,\,N-1]},\,j\in\mathbb{[0,\,C-1]}}=\left\{
    \begin{array}{rcl}
    - \frac{1}{fg\_num} * \alpha * {(1 - \sigma(x_{i,\,j}))}^{\gamma} * \log(\sigma(x_{i,\,j})) & & {(j +1) = label_{i,\,0}} \\
    - \frac{1}{fg\_num} * (1 - \alpha) * {\sigma(x_{i,\,j})}^{ \gamma} * \log(1 - \sigma(x_{i,\,j})) & & {(j +1)!= label_{i,\,0}}
    \end{array} \right.


We know that

.. math::
    \sigma(x_j) = \frac{1}{1 + \exp(-x_j)}


Args:
    x(Variable): A 2-D tensor with shape :math:`[N, C]` represents the predicted categories of
        all samples. :math:`N` is the number of all samples responsible for optimization in
        a mini-batch, for example, samples are anchor boxes for object detection and :math:`N`
        is the total number of positive and negative samples in a mini-batch; Samples are images
        for image classification and :math:`N` is the number of images in a mini-batch. :math:`C`
        is the number of classes (**Notice: excluding background**). The data type of :attr:`x` is
        float32 or float64.
    label(Variable): A 2-D tensor with shape :math:`[N, 1]` represents the target labels for
        classification. :math:`N` is the number of all samples responsible for optimization in a
        mini-batch, each sample has one target category. The values for positive samples are in the
        range of :math:`[1, C]`, and the values for negative samples are 0. The data type of :attr:`label`
        is int32.
    fg_num(Variable): A 1-D tensor with shape [1] represents the number of positive samples in a
        mini-batch, which should be obtained before this OP. The data type of :attr:`fg_num` is int32.
    gamma(int|float): Hyper-parameter to balance the easy and hard examples. Default value is
        set to 2.0.
    alpha(int|float): Hyper-parameter to balance the positive and negative example. Default value
        is set to 0.25.

Returns:
    Variable(the data type is float32 or float64): 
        A 2-D tensor with shape :math:`[N, C]`, which is the focal loss of each element in the input
        tensor :attr:`x`.

Examples:
    .. code-block:: python

        import numpy as np
        import paddle.fluid as fluid
        
        num_classes = 10  # exclude background
        image_width = 16
        image_height = 16
        batch_size = 32
        max_iter = 20
        
        
        def gen_train_data():
            x_data = np.random.uniform(0, 255, (batch_size, 3, image_height,
                                                image_width)).astype('float64')
            label_data = np.random.randint(0, num_classes,
                                           (batch_size, 1)).astype('int32')
            return {"x": x_data, "label": label_data}
        
        
        def get_focal_loss(pred, label, fg_num, num_classes):
            pred = fluid.layers.reshape(pred, [-1, num_classes])
            label = fluid.layers.reshape(label, [-1, 1])
            label.stop_gradient = True
            loss = fluid.layers.sigmoid_focal_loss(
                pred, label, fg_num, gamma=2.0, alpha=0.25)
            loss = fluid.layers.reduce_sum(loss)
            return loss
        
        
        def build_model(mode='train'):
            x = fluid.data(name="x", shape=[-1, 3, -1, -1], dtype='float64')
            output = fluid.layers.pool2d(input=x, pool_type='avg', global_pooling=True)
            output = fluid.layers.fc(
                input=output,
                size=num_classes,
                # Notice: size is set to be the number of target classes (excluding backgorund)
                # because sigmoid activation will be done in the sigmoid_focal_loss op.
                act=None)
            if mode == 'train':
                label = fluid.data(name="label", shape=[-1, 1], dtype='int32')
                # Obtain the fg_num needed by the sigmoid_focal_loss op:
                # 0 in label represents background, >=1 in label represents foreground,
                # find the elements in label which are greater or equal than 1, then
                # computed the numbers of these elements.
                data = fluid.layers.fill_constant(shape=[1], value=1, dtype='int32')
                fg_label = fluid.layers.greater_equal(label, data)
                fg_label = fluid.layers.cast(fg_label, dtype='int32')
                fg_num = fluid.layers.reduce_sum(fg_label)
                fg_num.stop_gradient = True
                avg_loss = get_focal_loss(output, label, fg_num, num_classes)
                return avg_loss
            else:
                # During evaluating or testing phase,
                # output of the final fc layer should be connected to a sigmoid layer.
                pred = fluid.layers.sigmoid(output)
                return pred
        
        
        loss = build_model('train')
        moment_optimizer = fluid.optimizer.MomentumOptimizer(
            learning_rate=0.001, momentum=0.9)
        moment_optimizer.minimize(loss)
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        exe.run(fluid.default_startup_program())
        for i in range(max_iter):
            outs = exe.run(feed=gen_train_data(), fetch_list=[loss.name])
            print(outs)
def sigmoid_focal_loss(x, label, fg_num, gamma=2.0, alpha=0.25):
    '\n\t:alias_main: paddle.nn.functional.sigmoid_focal_loss\n\t:alias: paddle.nn.functional.sigmoid_focal_loss,paddle.nn.functional.loss.sigmoid_focal_loss\n\t:old_api: paddle.fluid.layers.sigmoid_focal_loss\n\n    **Sigmoid Focal Loss Operator.**\n\n    `Focal Loss <https://arxiv.org/abs/1708.02002>`_ is used to address the foreground-background\n    class imbalance existed on the training phase of many computer vision tasks. This OP computes\n    the sigmoid value for each element in the input tensor :attr:`x`, after which focal loss is\n    measured between the sigmoid value and target label. \n\n    The focal loss is given as followed:\n\n    .. math::\n  \n        \\mathop{loss_{i,\\,j}}\\limits_{i\\in\\mathbb{[0,\\,N-1]},\\,j\\in\\mathbb{[0,\\,C-1]}}=\\left\\{\n        \\begin{array}{rcl}\n        - \\frac{1}{fg\\_num} * \\alpha * {(1 - \\sigma(x_{i,\\,j}))}^{\\gamma} * \\log(\\sigma(x_{i,\\,j})) & & {(j +1) = label_{i,\\,0}} \\\\\n        - \\frac{1}{fg\\_num} * (1 - \\alpha) * {\\sigma(x_{i,\\,j})}^{ \\gamma} * \\log(1 - \\sigma(x_{i,\\,j})) & & {(j +1)!= label_{i,\\,0}}\n        \\end{array} \\right.\n\n\n    We know that\n    \n    .. math::\n        \\sigma(x_j) = \\frac{1}{1 + \\exp(-x_j)}\n\n\n    Args:\n        x(Variable): A 2-D tensor with shape :math:`[N, C]` represents the predicted categories of\n            all samples. :math:`N` is the number of all samples responsible for optimization in\n            a mini-batch, for example, samples are anchor boxes for object detection and :math:`N`\n            is the total number of positive and negative samples in a mini-batch; Samples are images\n            for image classification and :math:`N` is the number of images in a mini-batch. :math:`C`\n            is the number of classes (**Notice: excluding background**). The data type of :attr:`x` is\n            float32 or float64.\n        label(Variable): A 2-D tensor with shape :math:`[N, 1]` represents the target labels for\n            classification. :math:`N` is the number of all samples responsible for optimization in a\n            mini-batch, each sample has one target category. The values for positive samples are in the\n            range of :math:`[1, C]`, and the values for negative samples are 0. The data type of :attr:`label`\n            is int32.\n        fg_num(Variable): A 1-D tensor with shape [1] represents the number of positive samples in a\n            mini-batch, which should be obtained before this OP. The data type of :attr:`fg_num` is int32.\n        gamma(int|float): Hyper-parameter to balance the easy and hard examples. Default value is\n            set to 2.0.\n        alpha(int|float): Hyper-parameter to balance the positive and negative example. Default value\n            is set to 0.25.\n\n    Returns:\n        Variable(the data type is float32 or float64): \n            A 2-D tensor with shape :math:`[N, C]`, which is the focal loss of each element in the input\n            tensor :attr:`x`.\n\n    Examples:\n        .. code-block:: python\n\n            import numpy as np\n            import paddle.fluid as fluid\n            \n            num_classes = 10  # exclude background\n            image_width = 16\n            image_height = 16\n            batch_size = 32\n            max_iter = 20\n            \n            \n            def gen_train_data():\n                x_data = np.random.uniform(0, 255, (batch_size, 3, image_height,\n                                                    image_width)).astype(\'float64\')\n                label_data = np.random.randint(0, num_classes,\n                                               (batch_size, 1)).astype(\'int32\')\n                return {"x": x_data, "label": label_data}\n            \n            \n            def get_focal_loss(pred, label, fg_num, num_classes):\n                pred = fluid.layers.reshape(pred, [-1, num_classes])\n                label = fluid.layers.reshape(label, [-1, 1])\n                label.stop_gradient = True\n                loss = fluid.layers.sigmoid_focal_loss(\n                    pred, label, fg_num, gamma=2.0, alpha=0.25)\n                loss = fluid.layers.reduce_sum(loss)\n                return loss\n            \n            \n            def build_model(mode=\'train\'):\n                x = fluid.data(name="x", shape=[-1, 3, -1, -1], dtype=\'float64\')\n                output = fluid.layers.pool2d(input=x, pool_type=\'avg\', global_pooling=True)\n                output = fluid.layers.fc(\n                    input=output,\n                    size=num_classes,\n                    # Notice: size is set to be the number of target classes (excluding backgorund)\n                    # because sigmoid activation will be done in the sigmoid_focal_loss op.\n                    act=None)\n                if mode == \'train\':\n                    label = fluid.data(name="label", shape=[-1, 1], dtype=\'int32\')\n                    # Obtain the fg_num needed by the sigmoid_focal_loss op:\n                    # 0 in label represents background, >=1 in label represents foreground,\n                    # find the elements in label which are greater or equal than 1, then\n                    # computed the numbers of these elements.\n                    data = fluid.layers.fill_constant(shape=[1], value=1, dtype=\'int32\')\n                    fg_label = fluid.layers.greater_equal(label, data)\n                    fg_label = fluid.layers.cast(fg_label, dtype=\'int32\')\n                    fg_num = fluid.layers.reduce_sum(fg_label)\n                    fg_num.stop_gradient = True\n                    avg_loss = get_focal_loss(output, label, fg_num, num_classes)\n                    return avg_loss\n                else:\n                    # During evaluating or testing phase,\n                    # output of the final fc layer should be connected to a sigmoid layer.\n                    pred = fluid.layers.sigmoid(output)\n                    return pred\n            \n            \n            loss = build_model(\'train\')\n            moment_optimizer = fluid.optimizer.MomentumOptimizer(\n                learning_rate=0.001, momentum=0.9)\n            moment_optimizer.minimize(loss)\n            place = fluid.CPUPlace()\n            exe = fluid.Executor(place)\n            exe.run(fluid.default_startup_program())\n            for i in range(max_iter):\n                outs = exe.run(feed=gen_train_data(), fetch_list=[loss.name])\n                print(outs)\n    '
    check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'sigmoid_focal_loss')
    check_variable_and_dtype(label, 'label', ['int32'], 'sigmoid_focal_loss')
    check_variable_and_dtype(fg_num, 'fg_num', ['int32'], 'sigmoid_focal_loss')
    helper = LayerHelper('sigmoid_focal_loss', **locals())
    out = helper.create_variable_for_type_inference(dtype=x.dtype)
    helper.append_op(type='sigmoid_focal_loss', inputs={'X': x, 'Label': label, 'FgNum': fg_num}, attrs={'gamma': gamma, 'alpha': alpha}, outputs={'Out': out})
    return out