From e5ddccf0a27d9059e5d6bec15d1cbb89cda7c67e Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Tue, 15 Mar 2022 00:33:57 +0800 Subject: [PATCH 01/29] 'TripletMarginDistanceLoss' --- python/paddle/nn/__init__.py | 2 + python/paddle/nn/functional/__init__.py | 2 + python/paddle/nn/functional/loss.py | 103 ++++++++++++++++++++++++ python/paddle/nn/layer/__init__.py | 1 + python/paddle/nn/layer/loss.py | 76 +++++++++++++++++ 5 files changed, 184 insertions(+) diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index b83a900059bf4..9a9f88f10dff4 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -105,6 +105,7 @@ from .layer.loss import CTCLoss # noqa: F401 from .layer.loss import SmoothL1Loss # noqa: F401 from .layer.loss import HingeEmbeddingLoss # noqa: F401 +from .layer.loss import TripletMarginDistanceLoss from .layer.norm import BatchNorm # noqa: F401 from .layer.norm import SyncBatchNorm # noqa: F401 from .layer.norm import GroupNorm # noqa: F401 @@ -307,4 +308,5 @@ def weight_norm(*args): 'MaxUnPool3D', 'HingeEmbeddingLoss', 'Identity', + 'TripletMarginDistanceLoss' ] diff --git a/python/paddle/nn/functional/__init__.py b/python/paddle/nn/functional/__init__.py index a24afc45a5995..8162d95655dca 100644 --- a/python/paddle/nn/functional/__init__.py +++ b/python/paddle/nn/functional/__init__.py @@ -89,6 +89,7 @@ from .loss import square_error_cost # noqa: F401 from .loss import ctc_loss # noqa: F401 from .loss import hinge_embedding_loss # noqa: F401 +from .loss import triplet_margin_with_distance_loss from .norm import batch_norm # noqa: F401 from .norm import instance_norm # noqa: F401 from .norm import layer_norm # noqa: F401 @@ -224,4 +225,5 @@ 'class_center_sample', 'sparse_attention', 'fold', + 'triplet_margin_with_distance_loss', ] diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 593cea2d2cf64..5a1ac2f3a0c87 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2195,3 +2195,106 @@ def hinge_embedding_loss(input, label, margin=1.0, reduction='mean', name=None): return paddle.sum(loss, name=name) elif reduction == 'none': return loss + + +def triplet_margin_with_distance_loss(input,positive,negative,distance_function = None, + swap=False, margin=1.0, reduction='mean', + name=None): + """ + Creates a criterion that measures the triplet loss given an input + tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. + This is used for measuring a relative similarity between samples. A triplet + is composed by `input`, `positive` and `negative` (i.e., `input`, `positive examples` and `negative + examples` respectively). The shapes of all input tensors should be + :math:`(N, D)`. + + The distance swap is described in detail in the paper `Learning shallow + convolutional feature descriptors with triplet losses`_ by + V. Balntas, E. Riba et al. + + The loss function for each sample in the mini-batch is: + + .. math:: + L(input, pos, neg) = \max \{d(input_i, pos_i) - d(input_i, neg_i) + {\rm margin}, 0\} + + + where + + .. math:: + d(x_i, y_i) = \left\lVert {\bf x}_i - {\bf y}_i \right\rVert_p + + :param input:Input tensor, the data type is float32 or float64. + the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. + :param positive:Positive tensor containing 1 or -1, the data type is float32 or float64. + The shape of label is the same as the shape of input. + :param negative:Negative tensor containing 1 or -1, the data type is float32 or float64. + The shape of label is the same as the shape of input. + :param distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + :param swap:The distance swap is described in detail in the paperT + `Learning shallow convolutional feature descriptors with triplet losses` by + V. Balntas, E. Riba et al. Default: ``False``. + :param margin:Default: :math:`1`.A nonnegative margin representing the minimum difference + between the positive and negative distances required for the loss to be 0. Larger + margins penalize cases where the negative examples are not distant enough from the + anchors, relative to the positives. + :param reduction:Indicate how to average the loss by batch_size. + 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 summed loss is returned. + Default: ``'mean'`` + :return:Tensor. The tensor variable storing the triplet_margin_loss of input and positive and negative. + + Examples: + .. code-block:: python + + import paddle + import paddle.nn.functional as F + + input = paddle.to_tensor([[1, 5, 3], [0, 3, 2], [1, 4, 1]], dtype=paddle.float32) + positive= paddle.to_tensor([[5, 1, 2], [3, 2, 1], [3, -1, 1]], dtype=paddle.float32) + negative = paddle.to_tensor([[2, 1, -3], [1, 1, -1], [4, -2, 1]], dtype=paddle.float32) + loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='none') + print(loss) + # Tensor([0. , 0.57496738, 0. ]) + + + loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='mean') + print(loss) + # Tensor([0.19165580]) + + """ + if reduction not in ['sum', 'mean', 'none']: + raise ValueError( + "'reduction' in 'triplet_margin_loss' should be 'sum', 'mean' or 'none', " + "but received {}.".format(reduction)) + if margin<0: + raise ValueError( + "margin should not smaller than 0" + ) + if not in_dynamic_mode(): + check_variable_and_dtype(input, 'input', ['float32', 'float64'], + 'triplet_margin_loss') + check_variable_and_dtype(positive, 'positive', ['float32', 'float64'], + 'triplet_margin_loss') + check_variable_and_dtype(negative, 'negative', ['float32', 'float64'], + 'triplet_margin_loss') + + distance_function = distance_function if distance_function is not None \ + else paddle.nn.PairwiseDistance(2) + + positive_dist = distance_function(input, positive) + negative_dist = distance_function(input, negative) + + if swap: + swap_dist = distance_function(positive, negative) + negative_dist = paddle.minimum(negative_dist, swap_dist) + + loss = paddle.clip(positive_dist-negative_dist+margin, min=0.0) + + if reduction == 'mean': + return paddle.mean(loss, name=name) + elif reduction == 'sum': + return paddle.sum(loss, name=name) + elif reduction == 'none': + return loss diff --git a/python/paddle/nn/layer/__init__.py b/python/paddle/nn/layer/__init__.py index 2b50508065605..9c4d2f35e0f1b 100644 --- a/python/paddle/nn/layer/__init__.py +++ b/python/paddle/nn/layer/__init__.py @@ -77,6 +77,7 @@ from .loss import CTCLoss # noqa: F401 from .loss import SmoothL1Loss # noqa: F401 from .loss import HingeEmbeddingLoss # noqa: F401 +from .loss import TripletMarginDistanceLoss from .norm import BatchNorm1D # noqa: F401 from .norm import BatchNorm2D # noqa: F401 from .norm import BatchNorm3D # noqa: F401 diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 7e40c029a02ec..95bd991bf18cb 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1298,3 +1298,79 @@ def forward(self, input, label): reduction=self.reduction, margin=self.margin, name=self.name) + + +class TripletMarginDistanceLoss(Layer): + """ + Creates a criterion that measures the triplet loss given an input + tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. + This is used for measuring a relative similarity between samples. A triplet + is composed by `input`, `positive` and `negative` (i.e., `input`, `positive examples` and `negative + examples` respectively). The shapes of all input tensors should be + :math:`(N, D)`. + + The distance swap is described in detail in the paper `Learning shallow + convolutional feature descriptors with triplet losses`_ by + V. Balntas, E. Riba et al. + + The loss function for each sample in the mini-batch is: + + .. math:: + L(input, pos, neg) = \max \{d(input_i, pos_i) - d(input_i, neg_i) + {\rm margin}, 0\} + + + :param input:Input tensor, the data type is float32 or float64. + the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. + :param positive:Positive tensor containing 1 or -1, the data type is float32 or float64. + The shape of label is the same as the shape of input. + :param negative:Negative tensor containing 1 or -1, the data type is float32 or float64. + The shape of label is the same as the shape of input. + :param distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + :param swap:The distance swap is described in detail in the paperT + `Learning shallow convolutional feature descriptors with triplet losses` by + V. Balntas, E. Riba et al. Default: ``False``. + :param margin:Default: :math:`1`.A nonnegative margin representing the minimum difference + between the positive and negative distances required for the loss to be 0. Larger + margins penalize cases where the negative examples are not distant enough from the + anchors, relative to the positives. + :param reduction:Indicate how to average the loss by batch_size. + 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 summed loss is returned. + Default: ``'mean'`` + :return:Tensor. The tensor variable storing the triplet_margin_loss of input and positive and negative. + + Examples: + .. code-block:: python + + import paddle + import paddle.nn.functional as F + + input = paddle.to_tensor([[1, 5, 3], [0, 3, 2], [1, 4, 1]], dtype=paddle.float32) + positive= paddle.to_tensor([[5, 1, 2], [3, 2, 1], [3, -1, 1]], dtype=paddle.float32) + negative = paddle.to_tensor([[2, 1, -3], [1, 1, -1], [4, -2, 1]], dtype=paddle.float32) + loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='none') + print(loss) + # Tensor([0. , 0.57496738, 0. ]) + + + loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='mean') + print(loss) + # Tensor([0.19165580]) + + """ + def __init__(self, distance_function=None,margin: float = 1.0, swap: bool = False,reduction: str = 'mean'): + super(TripletMarginDistanceLoss, self).__init__() + if reduction not in ['sum', 'mean', 'none']: + raise ValueError( + "The value of 'reduction' in bce_loss should be 'sum', 'mean' or 'none', but " + "received %s, which is not allowed." % reduction) + self.margin = margin + self.swap = swap + self.reduction = reduction + self.distance_function = distance_function + + def forward(self, input, positive, negative): + return F.triplet_margin_with_distance_loss(input, positive, negative, margin=self.margin, + swap=self.swap, reduction=self.reduction) From 97b703f1cf4bbcc3534b49158138a285ac063749 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Tue, 15 Mar 2022 23:30:36 +0800 Subject: [PATCH 02/29] 'test_file' --- .../test_triplet_margin_with_distance_loss.py | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py new file mode 100644 index 0000000000000..6d42d607646f8 --- /dev/null +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -0,0 +1,226 @@ + +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import paddle +import paddle.fluid as fluid +import numpy as np +import unittest + + +def call_TripletMarginDistanceLoss_layer(input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean',): + triplet_margin_with_distance_loss = paddle.nn.TripletMarginDistanceLoss(distance_function=distance_function, + margin=margin,swap=swap,reduction=reduction) + res = triplet_margin_with_distance_loss(input=input,positive=positive,negative=negative,) + return res + + +def call_TripletMaginLoss_functional(input, + positive, + negative, + distance_function = None, + margin=0.3, + swap=False, + reduction='mean',): + res = paddle.nn.functional.triplet_margin_with_distance_loss( + input=input,positive=positive,negative=negative,distance_function=distance_function, + margin=margin,swap=swap,reduction=reduction) + return res + + +def test_static(place, + input_np, + positive_np, + negative_np, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', + functional=False): + paddle.enable_static() + prog = paddle.static.Program() + startup_prog = paddle.static.Program() + with paddle.static.program_guard(prog, startup_prog): + input = paddle.fluid.data( + name='input', shape=input_np.shape, dtype='float64') + positive = paddle.fluid.data( + name='positive', shape=positive_np.shape, dtype='float64') + negative = paddle.fluid.data( + name='negative', shape=negative_np.shape, dtype='float64') + feed_dict = {"input": input_np, "positive": positive_np, "negative":negative_np} + + + if functional: + res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, + margin=margin,swap=swap,reduction=reduction) + else: + res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, + margin=margin,swap=swap,reduction=reduction) + + exe = paddle.static.Executor(place) + static_result = exe.run(prog, feed=feed_dict, fetch_list=[res]) + return static_result + +def test_dygraph(place, + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', + functional=False): + paddle.disable_static() + input = paddle.to_tensor(input) + positive = paddle.to_tensor(positive) + negative = paddle.to_tensor(negative) + + if functional: + dy_res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, + margin=margin,swap=swap,reduction=reduction) + else: + dy_res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, + margin=margin,swap=swap,reduction=reduction) + dy_result = dy_res.numpy() + paddle.enable_static() + return dy_result + + +def calc_triplet_margin_loss(input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean',): + distance_function = distance_function if distance_function is not None else np.linalg.norm + positive_dist = distance_function((input - positive), 2, axis=1) + negative_dist = distance_function((input - negative), 2, axis=1) + + if swap: + swap_dist = np.linalg.norm((positive - negative), 2, axis=1) + negative_dist = np.minimum(negative_dist, swap_dist) + expected = np.maximum(positive_dist - negative_dist + margin, 0) + + if reduction == 'mean': + expected = np.mean(expected) + elif reduction == 'sum': + expected = np.sum(expected) + else: + expected = expected + + return expected + + +class TestTripletMarginLoss(unittest.TestCase): + def test_TripletMarginLoss(self): + input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) + positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) + negative = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) + + places = [fluid.CPUPlace()] + if fluid.core.is_compiled_with_cuda(): + places.append(fluid.CUDAPlace(0)) + reductions = ['sum', 'mean', 'none'] + for place in places: + for reduction in reductions: + expected = calc_triplet_margin_loss(input=input, positive=positive, negative=negative, + reduction=reduction) + + dy_result = test_dygraph(place=place, + input=input, positive=positive, negative=negative, + reduction=reduction,) + + static_result = test_static(place=place, + input_np=input, positive_np=positive, negative_np=negative, + reduction=reduction,) + self.assertTrue(np.allclose(static_result, expected)) + self.assertTrue(np.allclose(static_result, dy_result)) + self.assertTrue(np.allclose(dy_result, expected)) + static_functional = test_static(place=place, + input_np=input, positive_np=positive, negative_np=negative, + reduction=reduction, + functional=True) + dy_functional = test_dygraph( + place=place, + input=input, positive=positive, negative=negative, + reduction=reduction, + functional=True) + self.assertTrue(np.allclose(static_functional, expected)) + self.assertTrue(np.allclose(static_functional, dy_functional)) + self.assertTrue(np.allclose(dy_functional, expected)) + + def test_BCEWithLogitsLoss_error(self): + paddle.disable_static() + self.assertRaises( + ValueError, + paddle.nn.TripletMarginDistanceLoss, + reduction="unsupport reduction") + input = paddle.to_tensor([[0.1, 0.3]], dtype='float32') + positive = paddle.to_tensor([[0.0, 1.0]], dtype='float32') + negative = paddle.to_tensor([[0.2, 0.1]], dtype='float32') + self.assertRaises( + ValueError, + paddle.nn.functional.triplet_margin_with_distance_loss, + input=input, + positive=positive, + negative=negative, + reduction="unsupport reduction") + paddle.enable_static() + + def test_TripletMarginDistanceLoss_distance_function(self): + distance_function_1 = lambda x, y: 1.0 - paddle.nn.functional.cosine_similarity(x, y) + def distance_function_2(x1,x2): + return paddle.max(paddle.abs(x1-x2),axis=1) + distance_function_list = [distance_function_1,distance_function_2] + input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) + positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) + negative = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) + + places = [fluid.CPUPlace()] + #if fluid.core.is_compiled_with_cuda(): + #places.append(fluid.CUDAPlace(0)) + reductions = ['sum', 'mean', 'none'] + for place in places: + for reduction in reductions: + for distance_function in distance_function_list: + dy_result = test_dygraph(place=place, + input=input, positive=positive, negative=negative,distance_function=distance_function, + reduction=reduction,) + + static_result = test_static(place=place, + input_np=input, positive_np=positive, negative_np=negative,distance_function=distance_function, + reduction=reduction,) + self.assertTrue(np.allclose(static_result, dy_result)) + static_functional = test_static(place=place, + input_np=input, positive_np=positive, negative_np=negative,distance_function=distance_function, + reduction=reduction, + functional=True) + dy_functional = test_dygraph( + place=place, + input=input, positive=positive, negative=negative,distance_function=distance_function, + reduction=reduction, + functional=True) + self.assertTrue(np.allclose(static_functional, dy_functional)) + + + +if __name__ == "__main__": + unittest.main() From ff3e76133c3e2f6afb7e1682aa4a8a20d652e05d Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sun, 27 Mar 2022 01:20:13 +0800 Subject: [PATCH 03/29] '2022_03_27' --- .../test_triplet_margin_with_distance_loss.py | 12 ++++++------ python/paddle/nn/functional/loss.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index 6d42d607646f8..45f63c5cb76a5 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -32,7 +32,7 @@ def call_TripletMarginDistanceLoss_layer(input, return res -def call_TripletMaginLoss_functional(input, +def call_TripletMaginDistanceLoss_functional(input, positive, negative, distance_function = None, @@ -68,7 +68,7 @@ def test_static(place, if functional: - res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, + res = call_TripletMaginDistanceLoss_functional(input=input,positive=positive,negative=negative,distance_function=distance_function, margin=margin,swap=swap,reduction=reduction) else: res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, @@ -93,7 +93,7 @@ def test_dygraph(place, negative = paddle.to_tensor(negative) if functional: - dy_res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, + dy_res = call_TripletMaginDistanceLoss_functional(input=input,positive=positive,negative=negative,distance_function=distance_function, margin=margin,swap=swap,reduction=reduction) else: dy_res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, @@ -103,7 +103,7 @@ def test_dygraph(place, return dy_result -def calc_triplet_margin_loss(input, +def calc_triplet_margin_distance_loss(input, positive, negative, distance_function=None, @@ -141,7 +141,7 @@ def test_TripletMarginLoss(self): reductions = ['sum', 'mean', 'none'] for place in places: for reduction in reductions: - expected = calc_triplet_margin_loss(input=input, positive=positive, negative=negative, + expected = calc_triplet_margin_distance_loss(input=input, positive=positive, negative=negative, reduction=reduction) dy_result = test_dygraph(place=place, @@ -167,7 +167,7 @@ def test_TripletMarginLoss(self): self.assertTrue(np.allclose(static_functional, dy_functional)) self.assertTrue(np.allclose(dy_functional, expected)) - def test_BCEWithLogitsLoss_error(self): + def test_TripletMarginDistanceLoss_error(self): paddle.disable_static() self.assertRaises( ValueError, diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 5a1ac2f3a0c87..45f42ca27c244 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2280,6 +2280,17 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function check_variable_and_dtype(negative, 'negative', ['float32', 'float64'], 'triplet_margin_loss') + # reshape to [batch_size, N] + input = input.flatten(start_axis=1,stop_axis=-1) + positive = positive.flatten(start_axis=1,stop_axis=-1) + negative = negative.flatten(start_axis=1,stop_axis=-1) + if not(input.shape==positive.shape==negative.shape): + raise ValueError( + "input's shape must equal to " + "positive's shape and " + "negative's shape") + + distance_function = distance_function if distance_function is not None \ else paddle.nn.PairwiseDistance(2) From a0919dee7a6ee4155a303c09df3f04c68aaf43f7 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Thu, 31 Mar 2022 00:07:43 +0800 Subject: [PATCH 04/29] 2022-03-31 --- .../test_triplet_margin_with_distance_loss.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index 45f63c5cb76a5..2347b21cffdb6 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -220,7 +220,26 @@ def distance_function_2(x1,x2): functional=True) self.assertTrue(np.allclose(static_functional, dy_functional)) + def test_TripletMarginLoss_dimension(self): + paddle.disable_static() + input = paddle.to_tensor([[0.1, 0.3], [1, 2]], dtype='float32') + positive = paddle.to_tensor([[0.0, 1.0]], dtype='float32') + negative = paddle.to_tensor([[0.2, 0.1]], dtype='float32') + self.assertRaises( + ValueError, + paddle.nn.functional.triplet_margin_with_distance_loss, + input=input, + positive=positive, + negative=negative, ) + TMDLoss = paddle.nn.TripletMarginDistanceLoss + self.assertRaises( + ValueError, + TMDLoss, + input=input, + positive=positive, + negative=negative, ) + paddle.enable_static() if __name__ == "__main__": unittest.main() From a15eae3bd698b7ef86a3427fa5c6c72c15b8a85d Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Tue, 5 Apr 2022 19:04:41 +0800 Subject: [PATCH 05/29] 2022-04-05 --- .../test_triplet_margin_with_distance_loss.py | 15 ++++----------- python/paddle/nn/functional/loss.py | 4 ++-- python/paddle/nn/layer/loss.py | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index 2347b21cffdb6..f4cb67c0b9ec6 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -26,7 +26,7 @@ def call_TripletMarginDistanceLoss_layer(input, margin=0.3, swap=False, reduction='mean',): - triplet_margin_with_distance_loss = paddle.nn.TripletMarginDistanceLoss(distance_function=distance_function, + triplet_margin_with_distance_loss = paddle.nn.TripletMarginWithDistanceLoss(distance_function=distance_function, margin=margin,swap=swap,reduction=reduction) res = triplet_margin_with_distance_loss(input=input,positive=positive,negative=negative,) return res @@ -130,7 +130,7 @@ def calc_triplet_margin_distance_loss(input, class TestTripletMarginLoss(unittest.TestCase): - def test_TripletMarginLoss(self): + def test_TripletMarginDistanceLoss(self): input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) @@ -171,7 +171,7 @@ def test_TripletMarginDistanceLoss_error(self): paddle.disable_static() self.assertRaises( ValueError, - paddle.nn.TripletMarginDistanceLoss, + paddle.nn.TripletMarginWithDistanceLoss, reduction="unsupport reduction") input = paddle.to_tensor([[0.1, 0.3]], dtype='float32') positive = paddle.to_tensor([[0.0, 1.0]], dtype='float32') @@ -220,7 +220,7 @@ def distance_function_2(x1,x2): functional=True) self.assertTrue(np.allclose(static_functional, dy_functional)) - def test_TripletMarginLoss_dimension(self): + def test_TripletMarginDistanceLoss_dimension(self): paddle.disable_static() input = paddle.to_tensor([[0.1, 0.3], [1, 2]], dtype='float32') @@ -232,13 +232,6 @@ def test_TripletMarginLoss_dimension(self): input=input, positive=positive, negative=negative, ) - TMDLoss = paddle.nn.TripletMarginDistanceLoss - self.assertRaises( - ValueError, - TMDLoss, - input=input, - positive=positive, - negative=negative, ) paddle.enable_static() if __name__ == "__main__": diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 45f42ca27c244..ac52e32577999 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -37,7 +37,7 @@ from paddle import _C_ops from paddle import in_dynamic_mode from paddle.framework import core -from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode, _non_static_mode +from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode,_non_static_mode __all__ = [] @@ -2272,7 +2272,7 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function raise ValueError( "margin should not smaller than 0" ) - if not in_dynamic_mode(): + if not _non_static_mode(): check_variable_and_dtype(input, 'input', ['float32', 'float64'], 'triplet_margin_loss') check_variable_and_dtype(positive, 'positive', ['float32', 'float64'], diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 95bd991bf18cb..e0962cd1d2108 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1300,7 +1300,7 @@ def forward(self, input, label): name=self.name) -class TripletMarginDistanceLoss(Layer): +class TripletMarginWithDistanceLoss(Layer): """ Creates a criterion that measures the triplet loss given an input tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. @@ -1361,7 +1361,7 @@ class TripletMarginDistanceLoss(Layer): """ def __init__(self, distance_function=None,margin: float = 1.0, swap: bool = False,reduction: str = 'mean'): - super(TripletMarginDistanceLoss, self).__init__() + super(TripletMarginWithDistanceLoss, self).__init__() if reduction not in ['sum', 'mean', 'none']: raise ValueError( "The value of 'reduction' in bce_loss should be 'sum', 'mean' or 'none', but " From 5ad881a1b17cd652dedc70837ed1bd4c71c19126 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Tue, 5 Apr 2022 20:45:35 +0800 Subject: [PATCH 06/29] 2 --- python/paddle/nn/__init__.py | 4 ++-- python/paddle/nn/functional/loss.py | 2 +- python/paddle/nn/layer/__init__.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index 9a9f88f10dff4..8c256a365cd3e 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -105,7 +105,7 @@ from .layer.loss import CTCLoss # noqa: F401 from .layer.loss import SmoothL1Loss # noqa: F401 from .layer.loss import HingeEmbeddingLoss # noqa: F401 -from .layer.loss import TripletMarginDistanceLoss +from .layer.loss import TripletMarginWithDistanceLoss from .layer.norm import BatchNorm # noqa: F401 from .layer.norm import SyncBatchNorm # noqa: F401 from .layer.norm import GroupNorm # noqa: F401 @@ -308,5 +308,5 @@ def weight_norm(*args): 'MaxUnPool3D', 'HingeEmbeddingLoss', 'Identity', - 'TripletMarginDistanceLoss' + 'TripletMarginWithDistanceLoss' ] diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index ac52e32577999..0bf338b397b0e 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -37,7 +37,7 @@ from paddle import _C_ops from paddle import in_dynamic_mode from paddle.framework import core -from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode,_non_static_mode +from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode, _non_static_mode __all__ = [] diff --git a/python/paddle/nn/layer/__init__.py b/python/paddle/nn/layer/__init__.py index 9c4d2f35e0f1b..f391640b5e7e1 100644 --- a/python/paddle/nn/layer/__init__.py +++ b/python/paddle/nn/layer/__init__.py @@ -77,7 +77,7 @@ from .loss import CTCLoss # noqa: F401 from .loss import SmoothL1Loss # noqa: F401 from .loss import HingeEmbeddingLoss # noqa: F401 -from .loss import TripletMarginDistanceLoss +from .loss import TripletMarginWithDistanceLoss from .norm import BatchNorm1D # noqa: F401 from .norm import BatchNorm2D # noqa: F401 from .norm import BatchNorm3D # noqa: F401 From 282d91eb6b19c86158a20c75de4a2a37f9345218 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sun, 17 Apr 2022 14:40:16 +0800 Subject: [PATCH 07/29] 2022-04-17 --- python/paddle/nn/functional/loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index cf1f712e10f08..d27025360eff7 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -36,8 +36,8 @@ from paddle.utils import deprecated from paddle import _C_ops from paddle import in_dynamic_mode -from paddle.framework import core -from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode, _non_static_mode +from paddle.framework import core, _non_static_mode +from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode, __all__ = [] From 6dfe4fc2e420550da8868e74d714f9e5b0c11d73 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sun, 17 Apr 2022 14:51:21 +0800 Subject: [PATCH 08/29] 2022-04-17_2 --- python/paddle/nn/functional/loss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index d27025360eff7..cf1f712e10f08 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -36,8 +36,8 @@ from paddle.utils import deprecated from paddle import _C_ops from paddle import in_dynamic_mode -from paddle.framework import core, _non_static_mode -from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode, +from paddle.framework import core +from ...fluid.framework import _in_legacy_dygraph, in_dygraph_mode, _non_static_mode __all__ = [] From bf098a8316ed90c0e187b919dddbd1979ec951bd Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sun, 17 Apr 2022 15:01:23 +0800 Subject: [PATCH 09/29] 2022-04-17_3 --- .../tests/unittests/test_triplet_margin_with_distance_loss.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index f4cb67c0b9ec6..75fdeecd3be60 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -76,6 +76,7 @@ def test_static(place, exe = paddle.static.Executor(place) static_result = exe.run(prog, feed=feed_dict, fetch_list=[res]) + paddle.disable_static() return static_result def test_dygraph(place, @@ -129,7 +130,7 @@ def calc_triplet_margin_distance_loss(input, return expected -class TestTripletMarginLoss(unittest.TestCase): +class TestTripletMarginWithDistanceLoss(unittest.TestCase): def test_TripletMarginDistanceLoss(self): input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) From 9afaf1cce8bd1e06c09b57fd130814f4283de037 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sun, 17 Apr 2022 16:03:24 +0800 Subject: [PATCH 10/29] 2022-04-17_4 --- .../test_triplet_margin_with_distance_loss.py | 128 +++++++++++++----- python/paddle/nn/functional/loss.py | 9 +- python/paddle/nn/layer/loss.py | 26 ++-- 3 files changed, 116 insertions(+), 47 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index 75fdeecd3be60..dab42ac75aef0 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -26,9 +26,13 @@ def call_TripletMarginDistanceLoss_layer(input, margin=0.3, swap=False, reduction='mean',): - triplet_margin_with_distance_loss = paddle.nn.TripletMarginWithDistanceLoss(distance_function=distance_function, - margin=margin,swap=swap,reduction=reduction) - res = triplet_margin_with_distance_loss(input=input,positive=positive,negative=negative,) + triplet_margin_with_distance_loss = paddle.nn.loss.TripletMarginWithDistanceLoss(distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) + res = triplet_margin_with_distance_loss(input=input, + positive=positive, + negative=negative,) return res @@ -40,8 +44,13 @@ def call_TripletMaginDistanceLoss_functional(input, swap=False, reduction='mean',): res = paddle.nn.functional.triplet_margin_with_distance_loss( - input=input,positive=positive,negative=negative,distance_function=distance_function, - margin=margin,swap=swap,reduction=reduction) + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) return res @@ -54,7 +63,6 @@ def test_static(place, swap=False, reduction='mean', functional=False): - paddle.enable_static() prog = paddle.static.Program() startup_prog = paddle.static.Program() with paddle.static.program_guard(prog, startup_prog): @@ -64,19 +72,28 @@ def test_static(place, name='positive', shape=positive_np.shape, dtype='float64') negative = paddle.fluid.data( name='negative', shape=negative_np.shape, dtype='float64') - feed_dict = {"input": input_np, "positive": positive_np, "negative":negative_np} - + feed_dict = {"input": input_np, "positive": positive_np, "negative": negative_np} if functional: - res = call_TripletMaginDistanceLoss_functional(input=input,positive=positive,negative=negative,distance_function=distance_function, - margin=margin,swap=swap,reduction=reduction) + res = call_TripletMaginDistanceLoss_functional(input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) else: - res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, - margin=margin,swap=swap,reduction=reduction) + res = call_TripletMarginDistanceLoss_layer(input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) exe = paddle.static.Executor(place) static_result = exe.run(prog, feed=feed_dict, fetch_list=[res]) - paddle.disable_static() + return static_result def test_dygraph(place, @@ -94,11 +111,21 @@ def test_dygraph(place, negative = paddle.to_tensor(negative) if functional: - dy_res = call_TripletMaginDistanceLoss_functional(input=input,positive=positive,negative=negative,distance_function=distance_function, - margin=margin,swap=swap,reduction=reduction) + dy_res = call_TripletMaginDistanceLoss_functional(input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) else: - dy_res = call_TripletMarginDistanceLoss_layer(input=input,positive=positive,negative=negative,distance_function=distance_function, - margin=margin,swap=swap,reduction=reduction) + dy_res = call_TripletMarginDistanceLoss_layer(input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) dy_result = dy_res.numpy() paddle.enable_static() return dy_result @@ -107,11 +134,11 @@ def test_dygraph(place, def calc_triplet_margin_distance_loss(input, positive, negative, - distance_function=None, + distance_function=None, margin=0.3, swap=False, reduction='mean',): - distance_function = distance_function if distance_function is not None else np.linalg.norm + distance_function = np.linalg.norm positive_dist = distance_function((input - positive), 2, axis=1) negative_dist = distance_function((input - negative), 2, axis=1) @@ -142,26 +169,36 @@ def test_TripletMarginDistanceLoss(self): reductions = ['sum', 'mean', 'none'] for place in places: for reduction in reductions: - expected = calc_triplet_margin_distance_loss(input=input, positive=positive, negative=negative, - reduction=reduction) + expected = calc_triplet_margin_distance_loss(input=input, + positive=positive, + negative=negative, + reduction=reduction) dy_result = test_dygraph(place=place, - input=input, positive=positive, negative=negative, + input=input, + positive=positive, + negative=negative, reduction=reduction,) static_result = test_static(place=place, - input_np=input, positive_np=positive, negative_np=negative, + input_np=input, + positive_np=positive, + negative_np=negative, reduction=reduction,) self.assertTrue(np.allclose(static_result, expected)) self.assertTrue(np.allclose(static_result, dy_result)) self.assertTrue(np.allclose(dy_result, expected)) static_functional = test_static(place=place, - input_np=input, positive_np=positive, negative_np=negative, + input_np=input, + positive_np=positive, + negative_np=negative, reduction=reduction, functional=True) dy_functional = test_dygraph( place=place, - input=input, positive=positive, negative=negative, + input=input, + positive=positive, + negative=negative, reduction=reduction, functional=True) self.assertTrue(np.allclose(static_functional, expected)) @@ -187,36 +224,52 @@ def test_TripletMarginDistanceLoss_error(self): paddle.enable_static() def test_TripletMarginDistanceLoss_distance_function(self): - distance_function_1 = lambda x, y: 1.0 - paddle.nn.functional.cosine_similarity(x, y) - def distance_function_2(x1,x2): - return paddle.max(paddle.abs(x1-x2),axis=1) + + def distance_function_1(x1, x2): + return 1.0 - paddle.nn.functional.cosine_similarity(x1, x2) + + def distance_function_2(x1, x2): + return paddle.max(paddle.abs(x1-x2), axis=1) + distance_function_list = [distance_function_1,distance_function_2] input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) places = [fluid.CPUPlace()] - #if fluid.core.is_compiled_with_cuda(): - #places.append(fluid.CUDAPlace(0)) + if fluid.core.is_compiled_with_cuda(): + places.append(fluid.CUDAPlace(0)) reductions = ['sum', 'mean', 'none'] for place in places: for reduction in reductions: for distance_function in distance_function_list: dy_result = test_dygraph(place=place, - input=input, positive=positive, negative=negative,distance_function=distance_function, + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, reduction=reduction,) static_result = test_static(place=place, - input_np=input, positive_np=positive, negative_np=negative,distance_function=distance_function, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, reduction=reduction,) self.assertTrue(np.allclose(static_result, dy_result)) static_functional = test_static(place=place, - input_np=input, positive_np=positive, negative_np=negative,distance_function=distance_function, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, reduction=reduction, functional=True) dy_functional = test_dygraph( place=place, - input=input, positive=positive, negative=negative,distance_function=distance_function, + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, reduction=reduction, functional=True) self.assertTrue(np.allclose(static_functional, dy_functional)) @@ -233,6 +286,13 @@ def test_TripletMarginDistanceLoss_dimension(self): input=input, positive=positive, negative=negative, ) + triplet_margin_with_distance_loss = paddle.nn.loss.TripletMarginWithDistanceLoss() + self.assertRaises( + ValueError, + triplet_margin_with_distance_loss, + input=input, + positive=positive, + negative=negative, ) paddle.enable_static() if __name__ == "__main__": diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index cf1f712e10f08..ed4893720cd64 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2243,7 +2243,7 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function If :attr:`reduction` is ``'mean'``, the reduced mean loss is returned; If :attr:`reduction` is ``'sum'``, the summed loss is returned. Default: ``'mean'`` - :return:Tensor. The tensor variable storing the triplet_margin_loss of input and positive and negative. + :return:Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. Examples: .. code-block:: python @@ -2254,19 +2254,20 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function input = paddle.to_tensor([[1, 5, 3], [0, 3, 2], [1, 4, 1]], dtype=paddle.float32) positive= paddle.to_tensor([[5, 1, 2], [3, 2, 1], [3, -1, 1]], dtype=paddle.float32) negative = paddle.to_tensor([[2, 1, -3], [1, 1, -1], [4, -2, 1]], dtype=paddle.float32) - loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='none') + loss = F.triplet_margin_with_distance_loss(input, positive, negative, margin=1.0, reduction='none') print(loss) # Tensor([0. , 0.57496738, 0. ]) - loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='mean') + loss = F.triplet_margin_with_distance_loss(input, positive, negative, margin=1.0, reduction='mean') print(loss) # Tensor([0.19165580]) """ if reduction not in ['sum', 'mean', 'none']: raise ValueError( - "'reduction' in 'triplet_margin_loss' should be 'sum', 'mean' or 'none', " + "'reduction' in 'triplet_margin_with_distance_loss' " + "should be 'sum', 'mean' or 'none', " "but received {}.".format(reduction)) if margin<0: raise ValueError( diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index e0962cd1d2108..de58bc3c5be4f 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1339,38 +1339,46 @@ class TripletMarginWithDistanceLoss(Layer): If :attr:`reduction` is ``'mean'``, the reduced mean loss is returned; If :attr:`reduction` is ``'sum'``, the summed loss is returned. Default: ``'mean'`` - :return:Tensor. The tensor variable storing the triplet_margin_loss of input and positive and negative. + :return:Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. Examples: .. code-block:: python import paddle - import paddle.nn.functional as F + from paddle.nn import TripletMarginWithDistanceLoss input = paddle.to_tensor([[1, 5, 3], [0, 3, 2], [1, 4, 1]], dtype=paddle.float32) positive= paddle.to_tensor([[5, 1, 2], [3, 2, 1], [3, -1, 1]], dtype=paddle.float32) negative = paddle.to_tensor([[2, 1, -3], [1, 1, -1], [4, -2, 1]], dtype=paddle.float32) - loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='none') + triplet_margin_with_distance_loss = TripletMarginWithDistanceLoss(reduction='none') + loss = triplet_margin_with_distance_loss(input, positive, negative,) print(loss) # Tensor([0. , 0.57496738, 0. ]) - - loss = F.triplet_margin_loss(input, positive, negative, margin=1.0, reduction='mean') + triplet_margin_with_distance_loss = TripletMarginWithDistanceLoss(reduction='mean') + loss = triplet_margin_with_distance_loss(input, positive, negative,) print(loss) # Tensor([0.19165580]) """ - def __init__(self, distance_function=None,margin: float = 1.0, swap: bool = False,reduction: str = 'mean'): + def __init__(self, distance_function=None, margin=1.0, swap=False, reduction: str = 'mean', name=None): super(TripletMarginWithDistanceLoss, self).__init__() if reduction not in ['sum', 'mean', 'none']: raise ValueError( - "The value of 'reduction' in bce_loss should be 'sum', 'mean' or 'none', but " + "The value of 'reduction' in TripletMarginWithDistanceLoss " + "should be 'sum', 'mean' or 'none', but " "received %s, which is not allowed." % reduction) self.margin = margin self.swap = swap self.reduction = reduction self.distance_function = distance_function + self.name = name def forward(self, input, positive, negative): - return F.triplet_margin_with_distance_loss(input, positive, negative, margin=self.margin, - swap=self.swap, reduction=self.reduction) + return F.triplet_margin_with_distance_loss(input, + positive, + negative, + margin=self.margin, + swap=self.swap, + reduction=self.reduction, + name=self.name) From 0a9d495e7c4bb976702e1c4dec0800368a4348a5 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Mon, 25 Apr 2022 21:28:39 +0800 Subject: [PATCH 11/29] 2022-04-25 --- .../test_triplet_margin_with_distance_loss.py | 149 +++++++++++++----- python/paddle/nn/functional/loss.py | 35 ++-- python/paddle/nn/layer/loss.py | 49 +++--- 3 files changed, 145 insertions(+), 88 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index dab42ac75aef0..b0a31daa63485 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -1,5 +1,4 @@ - -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -160,8 +159,8 @@ def calc_triplet_margin_distance_loss(input, class TestTripletMarginWithDistanceLoss(unittest.TestCase): def test_TripletMarginDistanceLoss(self): input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) - positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) - negative = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) + positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) places = [fluid.CPUPlace()] if fluid.core.is_compiled_with_cuda(): @@ -233,46 +232,61 @@ def distance_function_2(x1, x2): distance_function_list = [distance_function_1,distance_function_2] input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) - positive = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) - negative = np.random.randint(0, 2, size=(20, 30)).astype(np.float64) + positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + + place = fluid.CPUPlace() + reduction = 'mean' + for distance_function in distance_function_list: + dy_result = test_dygraph(place=place, + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + reduction=reduction,) + + static_result = test_static(place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, + reduction=reduction,) + self.assertTrue(np.allclose(static_result, dy_result)) + static_functional = test_static(place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, + reduction=reduction, + functional=True) + dy_functional = test_dygraph( + place=place, + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + reduction=reduction, + functional=True) + self.assertTrue(np.allclose(static_functional, dy_functional)) + + def test_TripletMarginWithDistanceLoss_distance_funtion_error(self): + paddle.disable_static() - places = [fluid.CPUPlace()] - if fluid.core.is_compiled_with_cuda(): - places.append(fluid.CUDAPlace(0)) - reductions = ['sum', 'mean', 'none'] - for place in places: - for reduction in reductions: - for distance_function in distance_function_list: - dy_result = test_dygraph(place=place, - input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - reduction=reduction,) - - static_result = test_static(place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - distance_function=distance_function, - reduction=reduction,) - self.assertTrue(np.allclose(static_result, dy_result)) - static_functional = test_static(place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - distance_function=distance_function, - reduction=reduction, - functional=True) - dy_functional = test_dygraph( - place=place, - input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - reduction=reduction, - functional=True) - self.assertTrue(np.allclose(static_functional, dy_functional)) + def distance_function(x1,x2): + return -1.0 - paddle.nn.functional.cosine_similarity(x1, x2) + func = distance_function + input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) + positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + + self.assertRaises( + ValueError, + paddle.nn.functional.triplet_margin_with_distance_loss, + input=input, + positive=positive, + negative=negative, + distance_function=func,) + paddle.enable_static() def test_TripletMarginDistanceLoss_dimension(self): paddle.disable_static() @@ -295,5 +309,54 @@ def test_TripletMarginDistanceLoss_dimension(self): negative=negative, ) paddle.enable_static() + def test_TripletMarginWithDistanceLoss_swap(self): + reduction = 'mean' + place = fluid.CPUPlace() + input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) + positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + expected = calc_triplet_margin_distance_loss(input=input, swap=True, positive=positive, negative=negative, + reduction=reduction) + + dy_result = test_dygraph(place=place, swap=True, + input=input, positive=positive, negative=negative, + reduction=reduction, ) + + static_result = test_static(place=place, swap=True, + input_np=input, positive_np=positive, negative_np=negative, + reduction=reduction, ) + self.assertTrue(np.allclose(static_result, expected)) + self.assertTrue(np.allclose(static_result, dy_result)) + self.assertTrue(np.allclose(dy_result, expected)) + static_functional = test_static(place=place, swap=True, + input_np=input, positive_np=positive, negative_np=negative, + reduction=reduction, + functional=True) + dy_functional = test_dygraph( + place=place, swap=True, + input=input, positive=positive, negative=negative, + reduction=reduction, + functional=True) + self.assertTrue(np.allclose(static_functional, expected)) + self.assertTrue(np.allclose(static_functional, dy_functional)) + self.assertTrue(np.allclose(dy_functional, expected)) + + def test_TripletMarginWithDistanceLoss_margin(self): + paddle.disable_static() + + input = paddle.to_tensor([[0.1, 0.3]], dtype='float32') + positive = paddle.to_tensor([[0.0, 1.0]], dtype='float32') + negative = paddle.to_tensor([[0.2, 0.1]], dtype='float32') + margin = -0.5 + self.assertRaises( + ValueError, + paddle.nn.functional.triplet_margin_with_distance_loss, + margin=margin, + input=input, + positive=positive, + negative=negative, ) + paddle.enable_static() + + if __name__ == "__main__": unittest.main() diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 844c8dc40df2f..d8bca2b433b6a 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2238,35 +2238,30 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function examples` respectively). The shapes of all input tensors should be :math:`(N, D)`. - The distance swap is described in detail in the paper `Learning shallow - convolutional feature descriptors with triplet losses`_ by - V. Balntas, E. Riba et al. - The loss function for each sample in the mini-batch is: .. math:: L(input, pos, neg) = \max \{d(input_i, pos_i) - d(input_i, neg_i) + {\rm margin}, 0\} - where + where the default distance function .. math:: d(x_i, y_i) = \left\lVert {\bf x}_i - {\bf y}_i \right\rVert_p + or user can defined their own distance functions. + :param input:Input tensor, the data type is float32 or float64. the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. - :param positive:Positive tensor containing 1 or -1, the data type is float32 or float64. + :param positive:Positive tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. - :param negative:Negative tensor containing 1 or -1, the data type is float32 or float64. + :param negative:Negative tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. :param distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - :param swap:The distance swap is described in detail in the paperT - `Learning shallow convolutional feature descriptors with triplet losses` by - V. Balntas, E. Riba et al. Default: ``False``. + :param swap:The distance swap changes the negative distance to the swap distance (distance between positive samples + and negative samples) if swap distance smaller than negative distance. Default: ``False``. :param margin:Default: :math:`1`.A nonnegative margin representing the minimum difference - between the positive and negative distances required for the loss to be 0. Larger - margins penalize cases where the negative examples are not distant enough from the - anchors, relative to the positives. + between the positive and negative distances required for the loss to be 0. :param reduction:Indicate how to average the loss by batch_size. the candicates are ``'none'`` | ``'mean'`` | ``'sum'``. If :attr:`reduction` is ``'none'``, the unreduced loss is returned; @@ -2299,9 +2294,9 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function "'reduction' in 'triplet_margin_with_distance_loss' " "should be 'sum', 'mean' or 'none', " "but received {}.".format(reduction)) - if margin<0: + if margin < 0: raise ValueError( - "margin should not smaller than 0" + "The margin between positive samples and negative samples should be greater than 0." ) if not _non_static_mode(): check_variable_and_dtype(input, 'input', ['float32', 'float64'], @@ -2311,17 +2306,12 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function check_variable_and_dtype(negative, 'negative', ['float32', 'float64'], 'triplet_margin_loss') - # reshape to [batch_size, N] - input = input.flatten(start_axis=1,stop_axis=-1) - positive = positive.flatten(start_axis=1,stop_axis=-1) - negative = negative.flatten(start_axis=1,stop_axis=-1) if not(input.shape==positive.shape==negative.shape): raise ValueError( "input's shape must equal to " "positive's shape and " "negative's shape") - distance_function = distance_function if distance_function is not None \ else paddle.nn.PairwiseDistance(2) @@ -2332,6 +2322,11 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function swap_dist = distance_function(positive, negative) negative_dist = paddle.minimum(negative_dist, swap_dist) + if not paddle.all(positive_dist > 0) or not paddle.all(negative_dist > 0): + raise ValueError( + "The positive distance or negative distance should be greater than 0, " + "The distance functions should be checked.") + loss = paddle.clip(positive_dist-negative_dist+margin, min=0.0) if reduction == 'mean': diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 284dd7769586d..591487be44d11 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1313,37 +1313,36 @@ class TripletMarginWithDistanceLoss(Layer): examples` respectively). The shapes of all input tensors should be :math:`(N, D)`. - The distance swap is described in detail in the paper `Learning shallow - convolutional feature descriptors with triplet losses`_ by - V. Balntas, E. Riba et al. - The loss function for each sample in the mini-batch is: .. math:: L(input, pos, neg) = \max \{d(input_i, pos_i) - d(input_i, neg_i) + {\rm margin}, 0\} + Parameters: + distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + swap:The distance swap changes the negative distance to the swap distance (distance between positive samples + and negative samples) if swap distance smaller than negative distance. Default: ``False``. + margin:Default: :math:`1`.A nonnegative margin representing the minimum difference + between the positive and negative distances required for the loss to be 0. Larger + margins penalize cases where the negative examples are not distant enough from the + anchors, relative to the positives. + reduction:Indicate how to average the loss by batch_size. + 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 summed loss is returned. + Default: ``'mean'`` - :param input:Input tensor, the data type is float32 or float64. - the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. - :param positive:Positive tensor containing 1 or -1, the data type is float32 or float64. - The shape of label is the same as the shape of input. - :param negative:Negative tensor containing 1 or -1, the data type is float32 or float64. - The shape of label is the same as the shape of input. - :param distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - :param swap:The distance swap is described in detail in the paperT - `Learning shallow convolutional feature descriptors with triplet losses` by - V. Balntas, E. Riba et al. Default: ``False``. - :param margin:Default: :math:`1`.A nonnegative margin representing the minimum difference - between the positive and negative distances required for the loss to be 0. Larger - margins penalize cases where the negative examples are not distant enough from the - anchors, relative to the positives. - :param reduction:Indicate how to average the loss by batch_size. - 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 summed loss is returned. - Default: ``'mean'`` - :return:Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. + Call Parameters: + input:Input tensor, the data type is float32 or float64. + the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. + positive:Positive tensor, the data type is float32 or float64. + The shape of label is the same as the shape of input. + negative:Negative tensor, the data type is float32 or float64. + The shape of label is the same as the shape of input. + + Return: + Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. Examples: .. code-block:: python From a474af24cb4845d940ce093482bd5f901e12493d Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Mon, 2 May 2022 18:19:56 +0800 Subject: [PATCH 12/29] 2022-05-02_V1 --- .../test_triplet_margin_with_distance_loss.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index b0a31daa63485..ae807778fdbd6 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -13,7 +13,6 @@ # limitations under the License. import paddle -import paddle.fluid as fluid import numpy as np import unittest @@ -65,11 +64,11 @@ def test_static(place, prog = paddle.static.Program() startup_prog = paddle.static.Program() with paddle.static.program_guard(prog, startup_prog): - input = paddle.fluid.data( + input = paddle.static.data( name='input', shape=input_np.shape, dtype='float64') - positive = paddle.fluid.data( + positive = paddle.static.data( name='positive', shape=positive_np.shape, dtype='float64') - negative = paddle.fluid.data( + negative = paddle.static.data( name='negative', shape=negative_np.shape, dtype='float64') feed_dict = {"input": input_np, "positive": positive_np, "negative": negative_np} @@ -162,9 +161,9 @@ def test_TripletMarginDistanceLoss(self): positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - places = [fluid.CPUPlace()] - if fluid.core.is_compiled_with_cuda(): - places.append(fluid.CUDAPlace(0)) + places = [paddle.CPUPlace()] + if paddle.device.is_compiled_with_cuda(): + places.append(paddle.CUDAPlace(0)) reductions = ['sum', 'mean', 'none'] for place in places: for reduction in reductions: @@ -235,7 +234,7 @@ def distance_function_2(x1, x2): positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - place = fluid.CPUPlace() + place = paddle.CPUPlace() reduction = 'mean' for distance_function in distance_function_list: dy_result = test_dygraph(place=place, @@ -311,7 +310,7 @@ def test_TripletMarginDistanceLoss_dimension(self): def test_TripletMarginWithDistanceLoss_swap(self): reduction = 'mean' - place = fluid.CPUPlace() + place = paddle.CPUPlace() input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) From 8e8175da3b103d0032c59280484d95009fedc620 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Fri, 6 May 2022 22:14:50 +0800 Subject: [PATCH 13/29] 2022-05-06_V1 --- .../test_triplet_margin_with_distance_loss.py | 2 +- python/paddle/nn/functional/loss.py | 31 ++++++++++++------- python/paddle/nn/layer/loss.py | 2 +- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index ae807778fdbd6..61318c436c74b 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -24,7 +24,7 @@ def call_TripletMarginDistanceLoss_layer(input, margin=0.3, swap=False, reduction='mean',): - triplet_margin_with_distance_loss = paddle.nn.loss.TripletMarginWithDistanceLoss(distance_function=distance_function, + triplet_margin_with_distance_loss = paddle.nn.TripletMarginWithDistanceLoss(distance_function=distance_function, margin=margin, swap=swap, reduction=reduction) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index d8bca2b433b6a..73c0b9eb10b03 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2230,8 +2230,8 @@ def hinge_embedding_loss(input, label, margin=1.0, reduction='mean', name=None): def triplet_margin_with_distance_loss(input,positive,negative,distance_function = None, swap=False, margin=1.0, reduction='mean', name=None): - """ - Creates a criterion that measures the triplet loss given an input + r""" + Measures the triplet loss given an input tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. This is used for measuring a relative similarity between samples. A triplet is composed by `input`, `positive` and `negative` (i.e., `input`, `positive examples` and `negative @@ -2251,26 +2251,35 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function or user can defined their own distance functions. - :param input:Input tensor, the data type is float32 or float64. + Parameters: + + input:Input tensor, the data type is float32 or float64. the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. - :param positive:Positive tensor, the data type is float32 or float64. + + positive:Positive tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. - :param negative:Negative tensor, the data type is float32 or float64. + + negative:Negative tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. - :param distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - :param swap:The distance swap changes the negative distance to the swap distance (distance between positive samples + + distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + + swap:The distance swap changes the negative distance to the swap distance (distance between positive samples and negative samples) if swap distance smaller than negative distance. Default: ``False``. - :param margin:Default: :math:`1`.A nonnegative margin representing the minimum difference + + margin:Default: :math:`1`.A nonnegative margin representing the minimum difference between the positive and negative distances required for the loss to be 0. - :param reduction:Indicate how to average the loss by batch_size. + + reduction:Indicate how to average the loss by batch_size. 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 summed loss is returned. Default: ``'mean'`` - :return:Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. + Returns: + Output: Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. - Examples: + Examples: .. code-block:: python import paddle diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 591487be44d11..fade6b37012c4 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1305,7 +1305,7 @@ def forward(self, input, label): class TripletMarginWithDistanceLoss(Layer): - """ + r""" Creates a criterion that measures the triplet loss given an input tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. This is used for measuring a relative similarity between samples. A triplet From 8c9e9d252abb80233c83882ce326770c469610af Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sat, 7 May 2022 22:04:24 +0800 Subject: [PATCH 14/29] 2022-05-07_V1 --- python/paddle/nn/functional/loss.py | 1 + python/paddle/nn/layer/loss.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 73c0b9eb10b03..86b763f3e0b7d 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2276,6 +2276,7 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function If :attr:`reduction` is ``'mean'``, the reduced mean loss is returned; If :attr:`reduction` is ``'sum'``, the summed loss is returned. Default: ``'mean'`` + Returns: Output: Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index fade6b37012c4..5a430b0b5622c 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1320,12 +1320,15 @@ class TripletMarginWithDistanceLoss(Layer): Parameters: distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + swap:The distance swap changes the negative distance to the swap distance (distance between positive samples and negative samples) if swap distance smaller than negative distance. Default: ``False``. + margin:Default: :math:`1`.A nonnegative margin representing the minimum difference between the positive and negative distances required for the loss to be 0. Larger margins penalize cases where the negative examples are not distant enough from the anchors, relative to the positives. + reduction:Indicate how to average the loss by batch_size. the candicates are ``'none'`` | ``'mean'`` | ``'sum'``. If :attr:`reduction` is ``'none'``, the unreduced loss is returned; @@ -1336,8 +1339,10 @@ class TripletMarginWithDistanceLoss(Layer): Call Parameters: input:Input tensor, the data type is float32 or float64. the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. + positive:Positive tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. + negative:Negative tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. From 4b31fd1096a19828f328ad6b9092bdf712c8ccc3 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Mon, 9 May 2022 17:51:37 +0800 Subject: [PATCH 15/29] Update loss.py --- python/paddle/nn/layer/loss.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 5a430b0b5622c..6b13c26ee2c6e 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1335,7 +1335,9 @@ class TripletMarginWithDistanceLoss(Layer): If :attr:`reduction` is ``'mean'``, the reduced mean loss is returned; If :attr:`reduction` is ``'sum'``, the summed loss is returned. Default: ``'mean'`` - + name (str, optional): Name for the operation (optional, default is None). + For more information, please refer to :ref:`api_guide_Name`. + Call Parameters: input:Input tensor, the data type is float32 or float64. the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. From 6b9aec6f1adce177f67bac4b469354046e6d5c05 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Mon, 9 May 2022 18:04:47 +0800 Subject: [PATCH 16/29] Update loss.py --- python/paddle/nn/functional/loss.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 86b763f3e0b7d..39502481f3b3f 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2227,9 +2227,14 @@ def hinge_embedding_loss(input, label, margin=1.0, reduction='mean', name=None): return loss -def triplet_margin_with_distance_loss(input,positive,negative,distance_function = None, - swap=False, margin=1.0, reduction='mean', - name=None): +def triplet_margin_with_distance_loss(input, + positive, + negative, + distance_function = None, + swap=False, + margin=1.0, + reduction='mean', + name=None): r""" Measures the triplet loss given an input tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. @@ -2276,7 +2281,9 @@ def triplet_margin_with_distance_loss(input,positive,negative,distance_function If :attr:`reduction` is ``'mean'``, the reduced mean loss is returned; If :attr:`reduction` is ``'sum'``, the summed loss is returned. Default: ``'mean'`` - + name (str, optional): Name for the operation (optional, default is None). + For more information, please refer to :ref:`api_guide_Name`. + Returns: Output: Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. From b48c99854825c45bc1bffa35de911dd0e89546a2 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Mon, 9 May 2022 21:49:41 +0800 Subject: [PATCH 17/29] Update loss.py --- python/paddle/nn/layer/loss.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 6b13c26ee2c6e..d4c0fe2448efc 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1319,17 +1319,17 @@ class TripletMarginWithDistanceLoss(Layer): L(input, pos, neg) = \max \{d(input_i, pos_i) - d(input_i, neg_i) + {\rm margin}, 0\} Parameters: - distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + distance_function (Callable, Optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - swap:The distance swap changes the negative distance to the swap distance (distance between positive samples + swap (bool, Optional):The distance swap changes the negative distance to the swap distance (distance between positive samples and negative samples) if swap distance smaller than negative distance. Default: ``False``. - margin:Default: :math:`1`.A nonnegative margin representing the minimum difference + margin (float, Optional):Default: :math:`1`.A nonnegative margin representing the minimum difference between the positive and negative distances required for the loss to be 0. Larger margins penalize cases where the negative examples are not distant enough from the anchors, relative to the positives. - reduction:Indicate how to average the loss by batch_size. + reduction (str, Optional):Indicate how to average the loss by batch_size. 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; @@ -1339,14 +1339,14 @@ class TripletMarginWithDistanceLoss(Layer): For more information, please refer to :ref:`api_guide_Name`. Call Parameters: - input:Input tensor, the data type is float32 or float64. - the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. + input (Tensor):Input tensor, the data type is float32 or float64. + the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. - positive:Positive tensor, the data type is float32 or float64. - The shape of label is the same as the shape of input. + positive (Tensor):Positive tensor, the data type is float32 or float64. + The shape of label is the same as the shape of input. - negative:Negative tensor, the data type is float32 or float64. - The shape of label is the same as the shape of input. + negative (Tensor):Negative tensor, the data type is float32 or float64. + The shape of label is the same as the shape of input. Return: Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. From a9959a6e5ba2a62c2e7d0c3560a6ec0fbe5413f9 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Mon, 9 May 2022 21:56:23 +0800 Subject: [PATCH 18/29] Update loss.py --- python/paddle/nn/functional/loss.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 39502481f3b3f..0d2652debdd8a 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2258,24 +2258,24 @@ def triplet_margin_with_distance_loss(input, Parameters: - input:Input tensor, the data type is float32 or float64. + input (Tensor):Input tensor, the data type is float32 or float64. the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. - positive:Positive tensor, the data type is float32 or float64. + positive (Tensor):Positive tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. - negative:Negative tensor, the data type is float32 or float64. + negative (Tensor):Negative tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. - distance_function: Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. + distance_function (callable, optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - swap:The distance swap changes the negative distance to the swap distance (distance between positive samples + swap (bool, optional):The distance swap changes the negative distance to the swap distance (distance between positive samples and negative samples) if swap distance smaller than negative distance. Default: ``False``. - margin:Default: :math:`1`.A nonnegative margin representing the minimum difference + margin (float, optional):Default: :math:`1`.A nonnegative margin representing the minimum difference between the positive and negative distances required for the loss to be 0. - reduction:Indicate how to average the loss by batch_size. + reduction (str, optional):Indicate how to average the loss by batch_size. 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; @@ -2317,11 +2317,11 @@ def triplet_margin_with_distance_loss(input, ) if not _non_static_mode(): check_variable_and_dtype(input, 'input', ['float32', 'float64'], - 'triplet_margin_loss') + 'triplet_margin_with_distance_loss') check_variable_and_dtype(positive, 'positive', ['float32', 'float64'], - 'triplet_margin_loss') + 'triplet_margin_with_distance_loss') check_variable_and_dtype(negative, 'negative', ['float32', 'float64'], - 'triplet_margin_loss') + 'triplet_margin_with_distance_loss') if not(input.shape==positive.shape==negative.shape): raise ValueError( From a48404eb07a578aaa543bcc1bb7b9ff1a21d53ac Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Mon, 9 May 2022 21:57:56 +0800 Subject: [PATCH 19/29] Update loss.py --- python/paddle/nn/layer/loss.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index d4c0fe2448efc..2b16a94bf647e 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1320,14 +1320,14 @@ class TripletMarginWithDistanceLoss(Layer): Parameters: distance_function (Callable, Optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - - swap (bool, Optional):The distance swap changes the negative distance to the swap distance (distance between positive samples - and negative samples) if swap distance smaller than negative distance. Default: ``False``. - + margin (float, Optional):Default: :math:`1`.A nonnegative margin representing the minimum difference between the positive and negative distances required for the loss to be 0. Larger margins penalize cases where the negative examples are not distant enough from the anchors, relative to the positives. + + swap (bool, Optional):The distance swap changes the negative distance to the swap distance (distance between positive samples + and negative samples) if swap distance smaller than negative distance. Default: ``False``. reduction (str, Optional):Indicate how to average the loss by batch_size. the candicates are ``'none'`` | ``'mean'`` | ``'sum'``. From 14adb6fc262f6154efea0568391a8cdc8e64485a Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Tue, 17 May 2022 12:01:24 +0800 Subject: [PATCH 20/29] Update loss.py --- python/paddle/nn/layer/loss.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 2b16a94bf647e..1dfb1dc6299e2 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1318,6 +1318,15 @@ class TripletMarginWithDistanceLoss(Layer): .. math:: L(input, pos, neg) = \max \{d(input_i, pos_i) - d(input_i, neg_i) + {\rm margin}, 0\} + where the default `distance_function` + + .. math:: + d(x_i, y_i) = \left\lVert {\bf x}_i - {\bf y}_i \right\rVert_2 + + or user can define their own distance function. `margin` is a nonnegative margin representing the minimum difference + between the positive and negative distances that is required for the loss to be 0. If `swap` is true, it will compare distance of (input, negative) with + distance of (negative, positive) and change it to the smaller one. + Parameters: distance_function (Callable, Optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. @@ -1338,7 +1347,7 @@ class TripletMarginWithDistanceLoss(Layer): name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`. - Call Parameters: + Shapes: input (Tensor):Input tensor, the data type is float32 or float64. the shape is [N, \*], N is batch size and `\*` means any number of additional dimensions, available dtype is float32, float64. @@ -1347,9 +1356,11 @@ class TripletMarginWithDistanceLoss(Layer): negative (Tensor):Negative tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. + + output(Tensor): The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. Return: - Tensor. The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. + A callable object of TripletMarginWithDistanceLoss Examples: .. code-block:: python From 9e8f696d3562537cadf65ca5406297fabe31e5d9 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Tue, 17 May 2022 12:04:29 +0800 Subject: [PATCH 21/29] Update loss.py --- python/paddle/nn/functional/loss.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 0d2652debdd8a..76a3e2b5aa4b6 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2254,7 +2254,9 @@ def triplet_margin_with_distance_loss(input, .. math:: d(x_i, y_i) = \left\lVert {\bf x}_i - {\bf y}_i \right\rVert_p - or user can defined their own distance functions. + or user can defined their own distance functions.`margin` is a nonnegative margin representing the minimum difference + between the positive and negative distances that is required for the loss to be 0. If `swap` is true, it will compare distance of (input, negative) with + distance of (negative, positive) and change it to the smaller one. For more details see http://www.bmva.org/bmvc/2016/papers/paper119/paper119.pdf. Parameters: From f617d14a7b0c0328892cdf1a58b672bc69f8be93 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Tue, 17 May 2022 12:04:49 +0800 Subject: [PATCH 22/29] Update loss.py --- python/paddle/nn/layer/loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 1dfb1dc6299e2..f7568ded376eb 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1325,7 +1325,7 @@ class TripletMarginWithDistanceLoss(Layer): or user can define their own distance function. `margin` is a nonnegative margin representing the minimum difference between the positive and negative distances that is required for the loss to be 0. If `swap` is true, it will compare distance of (input, negative) with - distance of (negative, positive) and change it to the smaller one. + distance of (negative, positive) and change it to the smaller one. For more details see http://www.bmva.org/bmvc/2016/papers/paper119/paper119.pdf. Parameters: distance_function (Callable, Optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. From 6e583432ed1990a8ec82c959bc4b3530ef3b2cfd Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Tue, 17 May 2022 12:10:07 +0800 Subject: [PATCH 23/29] Update loss.py --- python/paddle/nn/functional/loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 76a3e2b5aa4b6..6a7e79b4a392f 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2254,7 +2254,7 @@ def triplet_margin_with_distance_loss(input, .. math:: d(x_i, y_i) = \left\lVert {\bf x}_i - {\bf y}_i \right\rVert_p - or user can defined their own distance functions.`margin` is a nonnegative margin representing the minimum difference + or user can defined their own distance functions. `margin` is a nonnegative margin representing the minimum difference between the positive and negative distances that is required for the loss to be 0. If `swap` is true, it will compare distance of (input, negative) with distance of (negative, positive) and change it to the smaller one. For more details see http://www.bmva.org/bmvc/2016/papers/paper119/paper119.pdf. From b0ae52a2c8d48ecea47100fe10653fca6dad3cc7 Mon Sep 17 00:00:00 2001 From: yangguohao <70266361+yangguohao@users.noreply.github.com> Date: Fri, 20 May 2022 17:14:24 +0800 Subject: [PATCH 24/29] Update loss.py --- python/paddle/nn/functional/loss.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 6a7e79b4a392f..1a3f3f25302a6 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2231,8 +2231,8 @@ def triplet_margin_with_distance_loss(input, positive, negative, distance_function = None, - swap=False, margin=1.0, + swap=False, reduction='mean', name=None): r""" @@ -2270,13 +2270,13 @@ def triplet_margin_with_distance_loss(input, The shape of label is the same as the shape of input. distance_function (callable, optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - + + margin (float, optional):Default: :math:`1`.A nonnegative margin representing the minimum difference + between the positive and negative distances required for the loss to be 0. + swap (bool, optional):The distance swap changes the negative distance to the swap distance (distance between positive samples and negative samples) if swap distance smaller than negative distance. Default: ``False``. - margin (float, optional):Default: :math:`1`.A nonnegative margin representing the minimum difference - between the positive and negative distances required for the loss to be 0. - reduction (str, optional):Indicate how to average the loss by batch_size. the candicates are ``'none'`` | ``'mean'`` | ``'sum'``. If :attr:`reduction` is ``'none'``, the unreduced loss is returned; From a6c17b040355dd30c82635b424134590b2e166fe Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Wed, 1 Jun 2022 22:47:29 +0800 Subject: [PATCH 25/29] 2022-06-01_pre-commit --- python/paddle/nn/functional/loss.py | 34 ++++++++++++++--------------- python/paddle/nn/layer/loss.py | 25 +++++++++++++-------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 8df6257b89dcd..7c297667f6732 100755 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2232,13 +2232,13 @@ def hinge_embedding_loss(input, label, margin=1.0, reduction='mean', name=None): def triplet_margin_with_distance_loss(input, - positive, - negative, - distance_function = None, - margin=1.0, - swap=False, - reduction='mean', - name=None): + positive, + negative, + distance_function=None, + margin=1.0, + swap=False, + reduction='mean', + name=None): r""" Measures the triplet loss given an input tensors :math:`x1`, :math:`x2`, :math:`x3` and a margin with a value greater than :math:`0`. @@ -2275,7 +2275,7 @@ def triplet_margin_with_distance_loss(input, distance_function (callable, optional): Quantifies the distance between two tensors. if not specified, 2 norm functions will be used. - margin (float, optional):Default: :math:`1`.A nonnegative margin representing the minimum difference + margin (float, optional):Default: :math:`1`.A nonnegative margin representing the minimum difference between the positive and negative distances required for the loss to be 0. swap (bool, optional):The distance swap changes the negative distance to the swap distance (distance between positive samples @@ -2313,10 +2313,9 @@ def triplet_margin_with_distance_loss(input, """ if reduction not in ['sum', 'mean', 'none']: - raise ValueError( - "'reduction' in 'triplet_margin_with_distance_loss' " - "should be 'sum', 'mean' or 'none', " - "but received {}.".format(reduction)) + raise ValueError("'reduction' in 'triplet_margin_with_distance_loss' " + "should be 'sum', 'mean' or 'none', " + "but received {}.".format(reduction)) if margin < 0: raise ValueError( "The margin between positive samples and negative samples should be greater than 0." @@ -2329,11 +2328,10 @@ def triplet_margin_with_distance_loss(input, check_variable_and_dtype(negative, 'negative', ['float32', 'float64'], 'triplet_margin_with_distance_loss') - if not(input.shape==positive.shape==negative.shape): - raise ValueError( - "input's shape must equal to " - "positive's shape and " - "negative's shape") + if not (input.shape == positive.shape == negative.shape): + raise ValueError("input's shape must equal to " + "positive's shape and " + "negative's shape") distance_function = distance_function if distance_function is not None \ else paddle.nn.PairwiseDistance(2) @@ -2350,7 +2348,7 @@ def triplet_margin_with_distance_loss(input, "The positive distance or negative distance should be greater than 0, " "The distance functions should be checked.") - loss = paddle.clip(positive_dist-negative_dist+margin, min=0.0) + loss = paddle.clip(positive_dist - negative_dist + margin, min=0.0) if reduction == 'mean': return paddle.mean(loss, name=name) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index 0a17420ab4ff6..ca76fc0d8f050 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1361,7 +1361,7 @@ class TripletMarginWithDistanceLoss(Layer): negative (Tensor):Negative tensor, the data type is float32 or float64. The shape of label is the same as the shape of input. - output(Tensor): The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. + output(Tensor): The tensor variable storing the triplet_margin_with_distance_loss of input and positive and negative. Return: A callable object of TripletMarginWithDistanceLoss @@ -1386,7 +1386,13 @@ class TripletMarginWithDistanceLoss(Layer): # Tensor([0.19165580]) """ - def __init__(self, distance_function=None, margin=1.0, swap=False, reduction: str = 'mean', name=None): + + def __init__(self, + distance_function=None, + margin=1.0, + swap=False, + reduction: str='mean', + name=None): super(TripletMarginWithDistanceLoss, self).__init__() if reduction not in ['sum', 'mean', 'none']: raise ValueError( @@ -1400,10 +1406,11 @@ def __init__(self, distance_function=None, margin=1.0, swap=False, reduction: st self.name = name def forward(self, input, positive, negative): - return F.triplet_margin_with_distance_loss(input, - positive, - negative, - margin=self.margin, - swap=self.swap, - reduction=self.reduction, - name=self.name) + return F.triplet_margin_with_distance_loss( + input, + positive, + negative, + margin=self.margin, + swap=self.swap, + reduction=self.reduction, + name=self.name) From 8b00df1faa0db3bb5ebc54d6a5b0eb191b4177c6 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Sun, 5 Jun 2022 17:41:09 +0800 Subject: [PATCH 26/29] 2022-06-05 --- .../test_triplet_margin_with_distance_loss.py | 281 ++++++++++-------- 1 file changed, 161 insertions(+), 120 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index 61318c436c74b..5a24ee8a305d3 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -17,30 +17,34 @@ import unittest -def call_TripletMarginDistanceLoss_layer(input, - positive, - negative, - distance_function=None, - margin=0.3, - swap=False, - reduction='mean',): - triplet_margin_with_distance_loss = paddle.nn.TripletMarginWithDistanceLoss(distance_function=distance_function, - margin=margin, - swap=swap, - reduction=reduction) - res = triplet_margin_with_distance_loss(input=input, - positive=positive, - negative=negative,) +def call_TripletMarginDistanceLoss_layer( + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', ): + triplet_margin_with_distance_loss = paddle.nn.TripletMarginWithDistanceLoss( + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) + res = triplet_margin_with_distance_loss( + input=input, + positive=positive, + negative=negative, ) return res -def call_TripletMaginDistanceLoss_functional(input, - positive, - negative, - distance_function = None, - margin=0.3, - swap=False, - reduction='mean',): +def call_TripletMaginDistanceLoss_functional( + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', ): res = paddle.nn.functional.triplet_margin_with_distance_loss( input=input, positive=positive, @@ -70,30 +74,37 @@ def test_static(place, name='positive', shape=positive_np.shape, dtype='float64') negative = paddle.static.data( name='negative', shape=negative_np.shape, dtype='float64') - feed_dict = {"input": input_np, "positive": positive_np, "negative": negative_np} + feed_dict = { + "input": input_np, + "positive": positive_np, + "negative": negative_np + } if functional: - res = call_TripletMaginDistanceLoss_functional(input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - margin=margin, - swap=swap, - reduction=reduction) + res = call_TripletMaginDistanceLoss_functional( + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) else: - res = call_TripletMarginDistanceLoss_layer(input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - margin=margin, - swap=swap, - reduction=reduction) + res = call_TripletMarginDistanceLoss_layer( + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) exe = paddle.static.Executor(place) static_result = exe.run(prog, feed=feed_dict, fetch_list=[res]) return static_result + def test_dygraph(place, input, positive, @@ -109,33 +120,36 @@ def test_dygraph(place, negative = paddle.to_tensor(negative) if functional: - dy_res = call_TripletMaginDistanceLoss_functional(input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - margin=margin, - swap=swap, - reduction=reduction) + dy_res = call_TripletMaginDistanceLoss_functional( + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) else: - dy_res = call_TripletMarginDistanceLoss_layer(input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - margin=margin, - swap=swap, - reduction=reduction) + dy_res = call_TripletMarginDistanceLoss_layer( + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + margin=margin, + swap=swap, + reduction=reduction) dy_result = dy_res.numpy() paddle.enable_static() return dy_result -def calc_triplet_margin_distance_loss(input, - positive, - negative, - distance_function=None, - margin=0.3, - swap=False, - reduction='mean',): +def calc_triplet_margin_distance_loss( + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', ): distance_function = np.linalg.norm positive_dist = distance_function((input - positive), 2, axis=1) negative_dist = distance_function((input - negative), 2, axis=1) @@ -167,31 +181,35 @@ def test_TripletMarginDistanceLoss(self): reductions = ['sum', 'mean', 'none'] for place in places: for reduction in reductions: - expected = calc_triplet_margin_distance_loss(input=input, - positive=positive, - negative=negative, - reduction=reduction) - - dy_result = test_dygraph(place=place, - input=input, - positive=positive, - negative=negative, - reduction=reduction,) - - static_result = test_static(place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - reduction=reduction,) + expected = calc_triplet_margin_distance_loss( + input=input, + positive=positive, + negative=negative, + reduction=reduction) + + dy_result = test_dygraph( + place=place, + input=input, + positive=positive, + negative=negative, + reduction=reduction, ) + + static_result = test_static( + place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + reduction=reduction, ) self.assertTrue(np.allclose(static_result, expected)) self.assertTrue(np.allclose(static_result, dy_result)) self.assertTrue(np.allclose(dy_result, expected)) - static_functional = test_static(place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - reduction=reduction, - functional=True) + static_functional = test_static( + place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + reduction=reduction, + functional=True) dy_functional = test_dygraph( place=place, input=input, @@ -222,14 +240,13 @@ def test_TripletMarginDistanceLoss_error(self): paddle.enable_static() def test_TripletMarginDistanceLoss_distance_function(self): - def distance_function_1(x1, x2): return 1.0 - paddle.nn.functional.cosine_similarity(x1, x2) def distance_function_2(x1, x2): - return paddle.max(paddle.abs(x1-x2), axis=1) + return paddle.max(paddle.abs(x1 - x2), axis=1) - distance_function_list = [distance_function_1,distance_function_2] + distance_function_list = [distance_function_1, distance_function_2] input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) @@ -237,27 +254,30 @@ def distance_function_2(x1, x2): place = paddle.CPUPlace() reduction = 'mean' for distance_function in distance_function_list: - dy_result = test_dygraph(place=place, - input=input, - positive=positive, - negative=negative, - distance_function=distance_function, - reduction=reduction,) - - static_result = test_static(place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - distance_function=distance_function, - reduction=reduction,) + dy_result = test_dygraph( + place=place, + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + reduction=reduction, ) + + static_result = test_static( + place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, + reduction=reduction, ) self.assertTrue(np.allclose(static_result, dy_result)) - static_functional = test_static(place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - distance_function=distance_function, - reduction=reduction, - functional=True) + static_functional = test_static( + place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, + reduction=reduction, + functional=True) dy_functional = test_dygraph( place=place, input=input, @@ -271,8 +291,9 @@ def distance_function_2(x1, x2): def test_TripletMarginWithDistanceLoss_distance_funtion_error(self): paddle.disable_static() - def distance_function(x1,x2): + def distance_function(x1, x2): return -1.0 - paddle.nn.functional.cosine_similarity(x1, x2) + func = distance_function input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) @@ -284,7 +305,7 @@ def distance_function(x1,x2): input=input, positive=positive, negative=negative, - distance_function=func,) + distance_function=func, ) paddle.enable_static() def test_TripletMarginDistanceLoss_dimension(self): @@ -299,7 +320,8 @@ def test_TripletMarginDistanceLoss_dimension(self): input=input, positive=positive, negative=negative, ) - triplet_margin_with_distance_loss = paddle.nn.loss.TripletMarginWithDistanceLoss() + triplet_margin_with_distance_loss = paddle.nn.loss.TripletMarginWithDistanceLoss( + ) self.assertRaises( ValueError, triplet_margin_with_distance_loss, @@ -314,26 +336,45 @@ def test_TripletMarginWithDistanceLoss_swap(self): input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - expected = calc_triplet_margin_distance_loss(input=input, swap=True, positive=positive, negative=negative, - reduction=reduction) - - dy_result = test_dygraph(place=place, swap=True, - input=input, positive=positive, negative=negative, - reduction=reduction, ) + expected = calc_triplet_margin_distance_loss( + input=input, + swap=True, + positive=positive, + negative=negative, + reduction=reduction) - static_result = test_static(place=place, swap=True, - input_np=input, positive_np=positive, negative_np=negative, - reduction=reduction, ) + dy_result = test_dygraph( + place=place, + swap=True, + input=input, + positive=positive, + negative=negative, + reduction=reduction, ) + + static_result = test_static( + place=place, + swap=True, + input_np=input, + positive_np=positive, + negative_np=negative, + reduction=reduction, ) self.assertTrue(np.allclose(static_result, expected)) self.assertTrue(np.allclose(static_result, dy_result)) self.assertTrue(np.allclose(dy_result, expected)) - static_functional = test_static(place=place, swap=True, - input_np=input, positive_np=positive, negative_np=negative, - reduction=reduction, - functional=True) + static_functional = test_static( + place=place, + swap=True, + input_np=input, + positive_np=positive, + negative_np=negative, + reduction=reduction, + functional=True) dy_functional = test_dygraph( - place=place, swap=True, - input=input, positive=positive, negative=negative, + place=place, + swap=True, + input=input, + positive=positive, + negative=negative, reduction=reduction, functional=True) self.assertTrue(np.allclose(static_functional, expected)) From 5dce71763941d1b5aac8c2586c6a5297000c7eea Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Mon, 6 Jun 2022 23:57:16 +0800 Subject: [PATCH 27/29] 2022-06-06 --- .../test_triplet_margin_with_distance_loss.py | 227 ++++++++++-------- 1 file changed, 121 insertions(+), 106 deletions(-) diff --git a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py index 5a24ee8a305d3..0fb8ae22c26a6 100644 --- a/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py +++ b/python/paddle/fluid/tests/unittests/test_triplet_margin_with_distance_loss.py @@ -18,13 +18,14 @@ def call_TripletMarginDistanceLoss_layer( - input, - positive, - negative, - distance_function=None, - margin=0.3, - swap=False, - reduction='mean', ): + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', +): triplet_margin_with_distance_loss = paddle.nn.TripletMarginWithDistanceLoss( distance_function=distance_function, margin=margin, @@ -33,18 +34,20 @@ def call_TripletMarginDistanceLoss_layer( res = triplet_margin_with_distance_loss( input=input, positive=positive, - negative=negative, ) + negative=negative, + ) return res def call_TripletMaginDistanceLoss_functional( - input, - positive, - negative, - distance_function=None, - margin=0.3, - swap=False, - reduction='mean', ): + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', +): res = paddle.nn.functional.triplet_margin_with_distance_loss( input=input, positive=positive, @@ -68,12 +71,15 @@ def test_static(place, prog = paddle.static.Program() startup_prog = paddle.static.Program() with paddle.static.program_guard(prog, startup_prog): - input = paddle.static.data( - name='input', shape=input_np.shape, dtype='float64') - positive = paddle.static.data( - name='positive', shape=positive_np.shape, dtype='float64') - negative = paddle.static.data( - name='negative', shape=negative_np.shape, dtype='float64') + input = paddle.static.data(name='input', + shape=input_np.shape, + dtype='float64') + positive = paddle.static.data(name='positive', + shape=positive_np.shape, + dtype='float64') + negative = paddle.static.data(name='negative', + shape=negative_np.shape, + dtype='float64') feed_dict = { "input": input_np, "positive": positive_np, @@ -143,13 +149,14 @@ def test_dygraph(place, def calc_triplet_margin_distance_loss( - input, - positive, - negative, - distance_function=None, - margin=0.3, - swap=False, - reduction='mean', ): + input, + positive, + negative, + distance_function=None, + margin=0.3, + swap=False, + reduction='mean', +): distance_function = np.linalg.norm positive_dist = distance_function((input - positive), 2, axis=1) negative_dist = distance_function((input - negative), 2, axis=1) @@ -170,10 +177,12 @@ def calc_triplet_margin_distance_loss( class TestTripletMarginWithDistanceLoss(unittest.TestCase): + def test_TripletMarginDistanceLoss(self): - input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) - positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + shape = (5, 5) + input = np.random.uniform(0.1, 0.8, size=shape).astype(np.float64) + positive = np.random.uniform(0, 2, size=shape).astype(np.float64) + negative = np.random.uniform(0, 2, size=shape).astype(np.float64) places = [paddle.CPUPlace()] if paddle.device.is_compiled_with_cuda(): @@ -192,41 +201,40 @@ def test_TripletMarginDistanceLoss(self): input=input, positive=positive, negative=negative, - reduction=reduction, ) + reduction=reduction, + ) static_result = test_static( place=place, input_np=input, positive_np=positive, negative_np=negative, - reduction=reduction, ) + reduction=reduction, + ) self.assertTrue(np.allclose(static_result, expected)) self.assertTrue(np.allclose(static_result, dy_result)) self.assertTrue(np.allclose(dy_result, expected)) - static_functional = test_static( - place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - reduction=reduction, - functional=True) - dy_functional = test_dygraph( - place=place, - input=input, - positive=positive, - negative=negative, - reduction=reduction, - functional=True) + static_functional = test_static(place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + reduction=reduction, + functional=True) + dy_functional = test_dygraph(place=place, + input=input, + positive=positive, + negative=negative, + reduction=reduction, + functional=True) self.assertTrue(np.allclose(static_functional, expected)) self.assertTrue(np.allclose(static_functional, dy_functional)) self.assertTrue(np.allclose(dy_functional, expected)) def test_TripletMarginDistanceLoss_error(self): paddle.disable_static() - self.assertRaises( - ValueError, - paddle.nn.TripletMarginWithDistanceLoss, - reduction="unsupport reduction") + self.assertRaises(ValueError, + paddle.nn.TripletMarginWithDistanceLoss, + reduction="unsupport reduction") input = paddle.to_tensor([[0.1, 0.3]], dtype='float32') positive = paddle.to_tensor([[0.0, 1.0]], dtype='float32') negative = paddle.to_tensor([[0.2, 0.1]], dtype='float32') @@ -240,6 +248,7 @@ def test_TripletMarginDistanceLoss_error(self): paddle.enable_static() def test_TripletMarginDistanceLoss_distance_function(self): + def distance_function_1(x1, x2): return 1.0 - paddle.nn.functional.cosine_similarity(x1, x2) @@ -247,9 +256,10 @@ def distance_function_2(x1, x2): return paddle.max(paddle.abs(x1 - x2), axis=1) distance_function_list = [distance_function_1, distance_function_2] - input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) - positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + shape = (5, 5) + input = np.random.uniform(0.1, 0.8, size=shape).astype(np.float64) + positive = np.random.uniform(0, 2, size=shape).astype(np.float64) + negative = np.random.uniform(0, 2, size=shape).astype(np.float64) place = paddle.CPUPlace() reduction = 'mean' @@ -260,7 +270,8 @@ def distance_function_2(x1, x2): positive=positive, negative=negative, distance_function=distance_function, - reduction=reduction, ) + reduction=reduction, + ) static_result = test_static( place=place, @@ -268,24 +279,23 @@ def distance_function_2(x1, x2): positive_np=positive, negative_np=negative, distance_function=distance_function, - reduction=reduction, ) - self.assertTrue(np.allclose(static_result, dy_result)) - static_functional = test_static( - place=place, - input_np=input, - positive_np=positive, - negative_np=negative, - distance_function=distance_function, - reduction=reduction, - functional=True) - dy_functional = test_dygraph( - place=place, - input=input, - positive=positive, - negative=negative, - distance_function=distance_function, reduction=reduction, - functional=True) + ) + self.assertTrue(np.allclose(static_result, dy_result)) + static_functional = test_static(place=place, + input_np=input, + positive_np=positive, + negative_np=negative, + distance_function=distance_function, + reduction=reduction, + functional=True) + dy_functional = test_dygraph(place=place, + input=input, + positive=positive, + negative=negative, + distance_function=distance_function, + reduction=reduction, + functional=True) self.assertTrue(np.allclose(static_functional, dy_functional)) def test_TripletMarginWithDistanceLoss_distance_funtion_error(self): @@ -295,9 +305,10 @@ def distance_function(x1, x2): return -1.0 - paddle.nn.functional.cosine_similarity(x1, x2) func = distance_function - input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) - positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) + shape = (5, 5) + input = np.random.uniform(0.1, 0.8, size=shape).astype(np.float64) + positive = np.random.uniform(0, 2, size=shape).astype(np.float64) + negative = np.random.uniform(0, 2, size=shape).astype(np.float64) self.assertRaises( ValueError, @@ -305,7 +316,8 @@ def distance_function(x1, x2): input=input, positive=positive, negative=negative, - distance_function=func, ) + distance_function=func, + ) paddle.enable_static() def test_TripletMarginDistanceLoss_dimension(self): @@ -319,7 +331,8 @@ def test_TripletMarginDistanceLoss_dimension(self): paddle.nn.functional.triplet_margin_with_distance_loss, input=input, positive=positive, - negative=negative, ) + negative=negative, + ) triplet_margin_with_distance_loss = paddle.nn.loss.TripletMarginWithDistanceLoss( ) self.assertRaises( @@ -327,21 +340,22 @@ def test_TripletMarginDistanceLoss_dimension(self): triplet_margin_with_distance_loss, input=input, positive=positive, - negative=negative, ) + negative=negative, + ) paddle.enable_static() def test_TripletMarginWithDistanceLoss_swap(self): reduction = 'mean' place = paddle.CPUPlace() - input = np.random.uniform(0.1, 0.8, size=(20, 30)).astype(np.float64) - positive = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - negative = np.random.uniform(0, 2, size=(20, 30)).astype(np.float64) - expected = calc_triplet_margin_distance_loss( - input=input, - swap=True, - positive=positive, - negative=negative, - reduction=reduction) + shape = (5, 5) + input = np.random.uniform(0.1, 0.8, size=shape).astype(np.float64) + positive = np.random.uniform(0, 2, size=shape).astype(np.float64) + negative = np.random.uniform(0, 2, size=shape).astype(np.float64) + expected = calc_triplet_margin_distance_loss(input=input, + swap=True, + positive=positive, + negative=negative, + reduction=reduction) dy_result = test_dygraph( place=place, @@ -349,7 +363,8 @@ def test_TripletMarginWithDistanceLoss_swap(self): input=input, positive=positive, negative=negative, - reduction=reduction, ) + reduction=reduction, + ) static_result = test_static( place=place, @@ -357,26 +372,25 @@ def test_TripletMarginWithDistanceLoss_swap(self): input_np=input, positive_np=positive, negative_np=negative, - reduction=reduction, ) + reduction=reduction, + ) self.assertTrue(np.allclose(static_result, expected)) self.assertTrue(np.allclose(static_result, dy_result)) self.assertTrue(np.allclose(dy_result, expected)) - static_functional = test_static( - place=place, - swap=True, - input_np=input, - positive_np=positive, - negative_np=negative, - reduction=reduction, - functional=True) - dy_functional = test_dygraph( - place=place, - swap=True, - input=input, - positive=positive, - negative=negative, - reduction=reduction, - functional=True) + static_functional = test_static(place=place, + swap=True, + input_np=input, + positive_np=positive, + negative_np=negative, + reduction=reduction, + functional=True) + dy_functional = test_dygraph(place=place, + swap=True, + input=input, + positive=positive, + negative=negative, + reduction=reduction, + functional=True) self.assertTrue(np.allclose(static_functional, expected)) self.assertTrue(np.allclose(static_functional, dy_functional)) self.assertTrue(np.allclose(dy_functional, expected)) @@ -394,7 +408,8 @@ def test_TripletMarginWithDistanceLoss_margin(self): margin=margin, input=input, positive=positive, - negative=negative, ) + negative=negative, + ) paddle.enable_static() From 8f9d5be122b1559a1304b4310844c9f5c5b3f3c3 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Tue, 7 Jun 2022 18:36:22 +0800 Subject: [PATCH 28/29] 2022-06-07 --- python/paddle/nn/__init__.py | 5 ++--- python/paddle/nn/functional/__init__.py | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index 5e2321f7765fd..f120604f99c4d 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -154,7 +154,7 @@ from . import initializer # noqa: F401 from . import quant # noqa: F401 -#TODO: remove 'diag_embed', 'remove_weight_norm', 'weight_norm' months later. +# TODO: remove 'diag_embed', 'remove_weight_norm', 'weight_norm' months later. import paddle.utils.deprecated as deprecated @@ -191,8 +191,7 @@ def weight_norm(*args): return utils.weight_norm(*args) - -__all__ = [ #noqa +__all__ = [ # noqa 'BatchNorm', 'CELU', 'GroupNorm', diff --git a/python/paddle/nn/functional/__init__.py b/python/paddle/nn/functional/__init__.py index 0cd4799a5d9ea..d3c64c3bc5311 100644 --- a/python/paddle/nn/functional/__init__.py +++ b/python/paddle/nn/functional/__init__.py @@ -125,8 +125,7 @@ from .sparse_attention import sparse_attention - -__all__ = [ #noqa +__all__ = [ # noqa 'celu', 'conv1d', 'conv1d_transpose', From f468086791fd332d330848e3feea89c9647a8b17 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Tue, 7 Jun 2022 21:15:27 +0800 Subject: [PATCH 29/29] 2022-06-07_V2 --- python/paddle/nn/layer/loss.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/python/paddle/nn/layer/loss.py b/python/paddle/nn/layer/loss.py index e93205ec94ec5..3431dd802d24a 100644 --- a/python/paddle/nn/layer/loss.py +++ b/python/paddle/nn/layer/loss.py @@ -1394,7 +1394,7 @@ def __init__(self, distance_function=None, margin=1.0, swap=False, - reduction: str='mean', + reduction: str = 'mean', name=None): super(TripletMarginWithDistanceLoss, self).__init__() if reduction not in ['sum', 'mean', 'none']: @@ -1409,11 +1409,10 @@ def __init__(self, self.name = name def forward(self, input, positive, negative): - return F.triplet_margin_with_distance_loss( - input, - positive, - negative, - margin=self.margin, - swap=self.swap, - reduction=self.reduction, - name=self.name) + return F.triplet_margin_with_distance_loss(input, + positive, + negative, + margin=self.margin, + swap=self.swap, + reduction=self.reduction, + name=self.name)