Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hackathon No.26] #40487

Merged
merged 53 commits into from Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ea13abd
'triplet_margin_loss'
yangguohao Mar 12, 2022
352ec13
'test_file_corret'
yangguohao Mar 15, 2022
e2117ab
'2022_03_27'
yangguohao Mar 26, 2022
4a76c1c
2022_04_05
yangguohao Apr 4, 2022
26dac63
Merge branch 'develop' of https://github.com/yangguohao/Paddle into t…
yangguohao Apr 4, 2022
1daff0b
Merge branch 'develop' of https://github.com/yangguohao/Paddle into t…
yangguohao Apr 4, 2022
50a31d0
Merge branch 'triplet_margin_loss' of https://github.com/yangguohao/P…
yangguohao Apr 4, 2022
f0a5251
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 5, 2022
60cf94c
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 8, 2022
59483db
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 17, 2022
30c9c74
2022-04-17_1
yangguohao Apr 17, 2022
0a41311
2022-04-17
yangguohao Apr 17, 2022
d00b398
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 17, 2022
8586f6a
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 17, 2022
4fcd4bc
Merge branch 'develop' into triplet_margin_loss
yangguohao Apr 18, 2022
0ba037d
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 25, 2022
cba8470
2022-04-17_2
yangguohao Apr 17, 2022
b120a36
2022-04-25
yangguohao Apr 25, 2022
326be23
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 26, 2022
2898ed9
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 26, 2022
aae7b16
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Apr 27, 2022
b9817ec
2022-05-02_V1
yangguohao May 2, 2022
d03b871
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao May 2, 2022
0054e8f
2022-05-06_V1
yangguohao May 6, 2022
b9bde0b
2022-05-07_V1
yangguohao May 7, 2022
03f5dc0
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao May 7, 2022
30e5ccf
Update loss.py
yangguohao May 9, 2022
c0bcb93
Update loss.py
yangguohao May 9, 2022
c98c01a
Update loss.py
yangguohao May 9, 2022
ec9e86f
Update loss.py
yangguohao May 9, 2022
8c5e69d
Update loss.py
yangguohao May 13, 2022
6304cc2
Update loss.py
yangguohao May 19, 2022
63a1cb1
Update loss.py
yangguohao May 19, 2022
0339f5a
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao May 19, 2022
0a18f09
Update loss.py
yangguohao May 23, 2022
5ed1cb6
Update loss.py
yangguohao May 23, 2022
da0515f
Update test_triplet_margin_loss.py
yangguohao May 23, 2022
2be018e
Update loss.py
yangguohao May 24, 2022
b7b06e3
Merge branch 'develop' into triplet_margin_loss
yangguohao Jun 1, 2022
f06ad62
2022-06-01_pre-commit
yangguohao Jun 1, 2022
32c0440
2022-06-05
yangguohao Jun 5, 2022
c839fd6
Merge branch 'develop' into triplet_margin_loss
yangguohao Jun 5, 2022
a7d722f
2022-06-06
yangguohao Jun 6, 2022
8921f86
2022-06-06
yangguohao Jun 6, 2022
9f86cc9
Merge branch 'PaddlePaddle:develop' into triplet_margin_loss
yangguohao Jun 7, 2022
719341b
code_style_check
yangguohao Jun 7, 2022
4b72752
code_style_check
yangguohao Jun 7, 2022
463b42d
Update loss.py
yangguohao Jun 7, 2022
234f469
2022-06-07_V2
yangguohao Jun 7, 2022
e6aac2b
Merge branch 'develop' into triplet_margin_loss
yangguohao Jun 8, 2022
187fa6d
Merge branch 'develop' into triplet_margin_loss
yangguohao Jun 13, 2022
e6793b9
Update loss.py
yangguohao Jun 13, 2022
eecb30f
Update loss.py
yangguohao Jun 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
395 changes: 395 additions & 0 deletions python/paddle/fluid/tests/unittests/test_triplet_margin_loss.py
@@ -0,0 +1,395 @@
# 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.
# 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 numpy as np
import unittest


yangguohao marked this conversation as resolved.
Show resolved Hide resolved
def call_TripletMarginLoss_layer(
input,
positive,
negative,
p=2,
margin=0.3,
swap=False,
eps=1e-6,
reduction='mean',
):
triplet_margin_loss = paddle.nn.TripletMarginLoss(p=p,
epsilon=eps,
margin=margin,
swap=swap,
reduction=reduction)
res = triplet_margin_loss(
input=input,
positive=positive,
negative=negative,
)
return res


def call_TripletMarginLoss_functional(
input,
positive,
negative,
p=2,
margin=0.3,
swap=False,
eps=1e-6,
reduction='mean',
):
res = paddle.nn.functional.triplet_margin_loss(input=input,
positive=positive,
negative=negative,
p=p,
epsilon=eps,
margin=margin,
swap=swap,
reduction=reduction)
return res


def test_static(place,
input_np,
positive_np,
negative_np,
p=2,
margin=0.3,
swap=False,
eps=1e-6,
reduction='mean',
functional=False):
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')
feed_dict = {
"input": input_np,
"positive": positive_np,
"negative": negative_np
}

if functional:
res = call_TripletMarginLoss_functional(input=input,
positive=positive,
negative=negative,
p=p,
eps=eps,
margin=margin,
swap=swap,
reduction=reduction)
else:
res = call_TripletMarginLoss_layer(input=input,
positive=positive,
negative=negative,
p=p,
eps=eps,
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,
p=2,
margin=0.3,
swap=False,
eps=1e-6,
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_TripletMarginLoss_functional(input=input,
positive=positive,
negative=negative,
p=p,
eps=eps,
margin=margin,
swap=swap,
reduction=reduction)
else:
dy_res = call_TripletMarginLoss_layer(input=input,
positive=positive,
negative=negative,
p=p,
eps=eps,
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,
p=2,
margin=0.3,
swap=False,
reduction='mean',
):
positive_dist = np.linalg.norm((input - positive), p, axis=1)
negative_dist = np.linalg.norm((input - negative), p, axis=1)

if swap:
swap_dist = np.linalg.norm((positive - negative), p, 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):
shape = (2, 2)
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():
places.append(paddle.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))

yangguohao marked this conversation as resolved.
Show resolved Hide resolved
def test_TripletMarginLoss_error(self):
paddle.disable_static()
self.assertRaises(ValueError,
paddle.nn.loss.TripletMarginLoss,
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_loss,
input=input,
positive=positive,
negative=negative,
reduction="unsupport reduction")
paddle.enable_static()

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_loss,
input=input,
positive=positive,
negative=negative,
)
TMLoss = paddle.nn.loss.TripletMarginLoss()
self.assertRaises(
ValueError,
TMLoss,
input=input,
positive=positive,
negative=negative,
)
paddle.enable_static()

def test_TripletMarginLoss_swap(self):
reduction = 'mean'
place = paddle.CPUPlace()
shape = (2, 2)
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_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_TripletMarginLoss_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_loss,
margin=margin,
input=input,
positive=positive,
negative=negative,
)
paddle.enable_static()

def test_TripletMarginLoss_p(self):
p = 3
shape = (2, 2)
reduction = 'mean'
place = paddle.CPUPlace()
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_loss(input=input,
p=p,
positive=positive,
negative=negative,
reduction=reduction)

dy_result = test_dygraph(
place=place,
p=p,
input=input,
positive=positive,
negative=negative,
reduction=reduction,
)

static_result = test_static(
place=place,
p=p,
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,
p=p,
input_np=input,
positive_np=positive,
negative_np=negative,
reduction=reduction,
functional=True)
dy_functional = test_dygraph(place=place,
p=p,
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))


if __name__ == "__main__":
unittest.main()