-   Notifications  You must be signed in to change notification settings 
- Fork 5.9k
fix paddle.nn.loss.L1Loss OP, add paddle.nn.functional.l1_loss OP for API2.0, test=develop #26040
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -13,6 +13,10 @@ | |
| # limitations under the License. | ||
|  | ||
| # TODO: define loss functions of neural network | ||
| import paddle | ||
| import paddle.fluid as fluid | ||
| from ...fluid.framework import core, in_dygraph_mode | ||
| from ...fluid.layers.nn import _elementwise_op_in_dygraph | ||
| from ...fluid.layers import bpr_loss #DEFINE_ALIAS | ||
| from ...fluid.layers import center_loss #DEFINE_ALIAS | ||
| from ...fluid.layers import cross_entropy #DEFINE_ALIAS | ||
|  | @@ -45,6 +49,7 @@ | |
| 'huber_loss', | ||
| 'iou_similarity', | ||
| 'kldiv_loss', | ||
| 'l1_loss', | ||
| 'log_loss', | ||
| 'margin_rank_loss', | ||
| 'mse_loss', | ||
|  | @@ -60,3 +65,92 @@ | |
| 'ssd_loss', | ||
| 'teacher_student_sigmoid_loss' | ||
| ] | ||
|  | ||
|  | ||
| def l1_loss(x, label, reduction='mean', name=None): | ||
| """ | ||
| This operator computes the L1 Loss of Tensor ``x`` and ``label`` as follows. | ||
|  | ||
| If :attr:`reduction` set to ``'none'``, the loss is: | ||
|  | ||
| .. math:: | ||
| Out = \lvert x - label\rvert | ||
|  | ||
| If :attr:`reduction` set to ``'mean'``, the loss is: | ||
|  | ||
| .. math:: | ||
| Out = MEAN(\lvert x - label\rvert) | ||
|  | ||
| If :attr:`reduction` set to ``'sum'``, the loss is: | ||
|  | ||
| .. math:: | ||
| Out = SUM(\lvert x - label\rvert) | ||
|  | ||
|  | ||
| Parameters: | ||
| x (Tensor): The input tensor. The shapes is [N, *], where N is batch size and `*` means any number of additional dimensions. It's data type should be float32, float64, int32, int64. | ||
| label (Tensor): label. The shapes is [N, *], same shape as ``x`` . It's data type should be float32, float64, int32, int64. | ||
| reduction (str, optional): Indicate the reduction to apply to the loss, | ||
| the candicates are ``'none'`` | ``'mean'`` | ``'sum'``. | ||
| If :attr:`reduction` is ``'none'``, the unreduced loss is returned; | ||
| If :attr:`reduction` is ``'mean'``, the reduced mean loss is returned. | ||
| If :attr:`reduction` is ``'sum'``, the reduced sum loss is returned. | ||
| Default is ``'mean'``. | ||
| name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`. | ||
| Returns: | ||
| Tensor, the L1 Loss of Tensor ``x`` and ``label``. | ||
| If :attr:`reduction` is ``'none'``, the shape of output loss is [N, *], the same as ``x`` . | ||
| If :attr:`reduction` is ``'mean'`` or ``'sum'``, the shape of output loss is [1], which means the output is a scalar. | ||
| Examples: | ||
| .. code-block:: python | ||
| import paddle | ||
| import numpy as np | ||
|  | ||
| paddle.disable_static() | ||
| x_data = np.array([[1.5, 0.8], [0.2, 1.3]]).astype("float32") | ||
| label_data = np.array([[1.7, 1], [0.4, 0.5]]).astype("float32") | ||
| x = paddle.to_variable(x_data) | ||
| label = paddle.to_variable(label_data) | ||
|  | ||
| l1_loss = paddle.nn.functional.l1_loss(x, label) | ||
| print(l1_loss.numpy()) | ||
| # [0.35] | ||
|  | ||
| l1_loss = paddle.nn.functional.l1_loss(x, label, reduction='none') | ||
| print(l1_loss.numpy()) | ||
| # [[0.20000005 0.19999999] | ||
| # [0.2 0.79999995]] | ||
|  | ||
| l1_loss = paddle.nn.functional.l1_loss(x, label, reduction='sum') | ||
| print(l1_loss.numpy()) | ||
| # [1.4] | ||
| """ | ||
| if reduction not in ['sum', 'mean', 'none']: | ||
|   | ||
| raise ValueError( | ||
| "The value of 'reduction' in L1Loss should be 'sum', 'mean' or 'none', but " | ||
| "received %s, which is not allowed." % reduction) | ||
|  | ||
| if in_dygraph_mode(): | ||
| unreduced = _elementwise_op_in_dygraph( | ||
| x, label, axis=-1, act='abs', op_name='elementwise_sub') | ||
| if reduction == 'mean': | ||
| return core.ops.mean(unreduced) | ||
| elif reduction == 'sum': | ||
| return core.ops.reduce_sum(unreduced, 'dim', [0], 'keep_dim', False, | ||
| 'reduce_all', True) | ||
| else: | ||
| return unreduced | ||
|  | ||
| fluid.data_feeder.check_variable_and_dtype( | ||
| x, 'x', ['float32', 'float64', 'int32', 'int64'], 'l1_loss') | ||
| fluid.data_feeder.check_variable_and_dtype( | ||
| label, 'label', ['float32', 'float64', 'int32', 'int64'], 'l1_loss') | ||
|  | ||
| if reduction == 'sum': | ||
| unreduced = paddle.elementwise_sub(x, label, act='abs') | ||
| return paddle.sum(unreduced, name=name) | ||
| elif reduction == 'mean': | ||
| unreduced = paddle.elementwise_sub(x, label, act='abs') | ||
| return paddle.mean(unreduced, name=name) | ||
| else: | ||
|   | ||
| return paddle.elementwise_sub(x, label, act='abs', name=name) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是否需要多一行?none mean下面都空了一行
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done