From 7906fe9944d9c43d187eca4613373192fe0ae44c Mon Sep 17 00:00:00 2001 From: wen <1464777360@qq.com> Date: Wed, 27 Jan 2021 19:04:41 +0800 Subject: [PATCH 1/6] Remove redundant code, Solve the data type inconsistency bug --- bootstrapped_cross_entropy.py | 71 +++++++++++++++++++ .../losses/bootstrapped_cross_entropy.py | 6 +- 2 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 bootstrapped_cross_entropy.py diff --git a/bootstrapped_cross_entropy.py b/bootstrapped_cross_entropy.py new file mode 100644 index 0000000000..5338dde5ca --- /dev/null +++ b/bootstrapped_cross_entropy.py @@ -0,0 +1,71 @@ +# 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 +from paddle import nn +import paddle.nn.functional as F + +from paddleseg.cvlibs import manager + + +@manager.LOSSES.add_component +class BootstrappedCrossEntropyLoss(nn.Layer): + """ + Implements the cross entropy loss function. + + Args: + min_K (int): the minimum number of pixels to be counted in loss computation. + loss_th (float): the loss threshold. Only loss that is larger than the threshold + would be calculated. + weight (tuple|list, optional): The weight for different classes. Default: None. + ignore_index (int, optional): Specifies a target value that is ignored + and does not contribute to the input gradient. Default: 255. + """ + + def __init__(self, min_K, loss_th, weight=None, ignore_index=255): + super().__init__() + self.ignore_index = ignore_index + self.K = min_K + self.threshold = loss_th + self.weight = paddle.to_tensor(weight) # 修复weight与F.cross_entropy需要的weight数据类型不一致的bug + # 删除重复的self.ignore_index = ignore_index + def forward(self, logit, label): + + n, c, h, w = logit.shape + total_loss = 0.0 + if len(label.shape) != len(logit.shape): + label = paddle.unsqueeze(label, 1) + + for i in range(n): + x = paddle.unsqueeze(logit[i], 0) + y = paddle.unsqueeze(label[i], 0) + x = paddle.transpose(x, (0, 2, 3, 1)) + y = paddle.transpose(y, (0, 2, 3, 1)) + x = paddle.reshape(x, shape=(-1, c)) + y = paddle.reshape(y, shape=(-1, )) + loss = F.cross_entropy( + x, + y, + weight=self.weight, + ignore_index=self.ignore_index, + reduction="none") + sorted_loss = paddle.sort(loss, descending=True) + if sorted_loss[self.K] > self.threshold: + new_indices = paddle.nonzero(sorted_loss > self.threshold) + loss = paddle.gather(sorted_loss, new_indices) + else: + loss = sorted_loss[:self.K] + + total_loss += paddle.mean(loss) + return total_loss / float(n) diff --git a/paddleseg/models/losses/bootstrapped_cross_entropy.py b/paddleseg/models/losses/bootstrapped_cross_entropy.py index 5ca95feb69..5338dde5ca 100644 --- a/paddleseg/models/losses/bootstrapped_cross_entropy.py +++ b/paddleseg/models/losses/bootstrapped_cross_entropy.py @@ -38,9 +38,8 @@ def __init__(self, min_K, loss_th, weight=None, ignore_index=255): self.ignore_index = ignore_index self.K = min_K self.threshold = loss_th - self.weight = weight - self.ignore_index = ignore_index - + self.weight = paddle.to_tensor(weight) # 修复weight与F.cross_entropy需要的weight数据类型不一致的bug + # 删除重复的self.ignore_index = ignore_index def forward(self, logit, label): n, c, h, w = logit.shape @@ -55,7 +54,6 @@ def forward(self, logit, label): y = paddle.transpose(y, (0, 2, 3, 1)) x = paddle.reshape(x, shape=(-1, c)) y = paddle.reshape(y, shape=(-1, )) - loss = F.cross_entropy( x, y, From 9b75ab7128e4417b104c9d485a729b35e08c1c9d Mon Sep 17 00:00:00 2001 From: wen <1464777360@qq.com> Date: Wed, 27 Jan 2021 19:49:05 +0800 Subject: [PATCH 2/6] Remove redundant code, Solve the data type inconsistency bug --- paddleseg/models/losses/bootstrapped_cross_entropy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/paddleseg/models/losses/bootstrapped_cross_entropy.py b/paddleseg/models/losses/bootstrapped_cross_entropy.py index 5338dde5ca..c97092b878 100644 --- a/paddleseg/models/losses/bootstrapped_cross_entropy.py +++ b/paddleseg/models/losses/bootstrapped_cross_entropy.py @@ -38,8 +38,9 @@ def __init__(self, min_K, loss_th, weight=None, ignore_index=255): self.ignore_index = ignore_index self.K = min_K self.threshold = loss_th - self.weight = paddle.to_tensor(weight) # 修复weight与F.cross_entropy需要的weight数据类型不一致的bug - # 删除重复的self.ignore_index = ignore_index + if weight is not None: + weight = paddle.to_tensor(weight, dtype='float32') + self.weight = weight def forward(self, logit, label): n, c, h, w = logit.shape From 1a67cda07772848c003ca1721ac71d2a1479aa5b Mon Sep 17 00:00:00 2001 From: wen <1464777360@qq.com> Date: Wed, 27 Jan 2021 19:54:52 +0800 Subject: [PATCH 3/6] Remove redundant code,Solve the data type inconsistency bug --- paddleseg/models/losses/bootstrapped_cross_entropy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/paddleseg/models/losses/bootstrapped_cross_entropy.py b/paddleseg/models/losses/bootstrapped_cross_entropy.py index c97092b878..6443ccffec 100644 --- a/paddleseg/models/losses/bootstrapped_cross_entropy.py +++ b/paddleseg/models/losses/bootstrapped_cross_entropy.py @@ -41,6 +41,7 @@ def __init__(self, min_K, loss_th, weight=None, ignore_index=255): if weight is not None: weight = paddle.to_tensor(weight, dtype='float32') self.weight = weight + def forward(self, logit, label): n, c, h, w = logit.shape From a73a2ed4eb09a51aa96df2c9e02d2052381f9e18 Mon Sep 17 00:00:00 2001 From: Liu Wenlong <51303942+wen-flow@users.noreply.github.com> Date: Wed, 27 Jan 2021 19:56:23 +0800 Subject: [PATCH 4/6] Delete bootstrapped_cross_entropy.py --- bootstrapped_cross_entropy.py | 71 ----------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 bootstrapped_cross_entropy.py diff --git a/bootstrapped_cross_entropy.py b/bootstrapped_cross_entropy.py deleted file mode 100644 index 5338dde5ca..0000000000 --- a/bootstrapped_cross_entropy.py +++ /dev/null @@ -1,71 +0,0 @@ -# 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 -from paddle import nn -import paddle.nn.functional as F - -from paddleseg.cvlibs import manager - - -@manager.LOSSES.add_component -class BootstrappedCrossEntropyLoss(nn.Layer): - """ - Implements the cross entropy loss function. - - Args: - min_K (int): the minimum number of pixels to be counted in loss computation. - loss_th (float): the loss threshold. Only loss that is larger than the threshold - would be calculated. - weight (tuple|list, optional): The weight for different classes. Default: None. - ignore_index (int, optional): Specifies a target value that is ignored - and does not contribute to the input gradient. Default: 255. - """ - - def __init__(self, min_K, loss_th, weight=None, ignore_index=255): - super().__init__() - self.ignore_index = ignore_index - self.K = min_K - self.threshold = loss_th - self.weight = paddle.to_tensor(weight) # 修复weight与F.cross_entropy需要的weight数据类型不一致的bug - # 删除重复的self.ignore_index = ignore_index - def forward(self, logit, label): - - n, c, h, w = logit.shape - total_loss = 0.0 - if len(label.shape) != len(logit.shape): - label = paddle.unsqueeze(label, 1) - - for i in range(n): - x = paddle.unsqueeze(logit[i], 0) - y = paddle.unsqueeze(label[i], 0) - x = paddle.transpose(x, (0, 2, 3, 1)) - y = paddle.transpose(y, (0, 2, 3, 1)) - x = paddle.reshape(x, shape=(-1, c)) - y = paddle.reshape(y, shape=(-1, )) - loss = F.cross_entropy( - x, - y, - weight=self.weight, - ignore_index=self.ignore_index, - reduction="none") - sorted_loss = paddle.sort(loss, descending=True) - if sorted_loss[self.K] > self.threshold: - new_indices = paddle.nonzero(sorted_loss > self.threshold) - loss = paddle.gather(sorted_loss, new_indices) - else: - loss = sorted_loss[:self.K] - - total_loss += paddle.mean(loss) - return total_loss / float(n) From 9729c529cb3d9baf0daee60514af6abf217090cb Mon Sep 17 00:00:00 2001 From: Liu Wenlong <51303942+wen-flow@users.noreply.github.com> Date: Wed, 27 Jan 2021 19:57:31 +0800 Subject: [PATCH 5/6] Update bootstrapped_cross_entropy.py --- paddleseg/models/losses/bootstrapped_cross_entropy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/paddleseg/models/losses/bootstrapped_cross_entropy.py b/paddleseg/models/losses/bootstrapped_cross_entropy.py index 6443ccffec..c97092b878 100644 --- a/paddleseg/models/losses/bootstrapped_cross_entropy.py +++ b/paddleseg/models/losses/bootstrapped_cross_entropy.py @@ -41,7 +41,6 @@ def __init__(self, min_K, loss_th, weight=None, ignore_index=255): if weight is not None: weight = paddle.to_tensor(weight, dtype='float32') self.weight = weight - def forward(self, logit, label): n, c, h, w = logit.shape From cc18ef1d4d06166539bbeb90c44c79a21d1b8df4 Mon Sep 17 00:00:00 2001 From: Liu Wenlong <51303942+wen-flow@users.noreply.github.com> Date: Wed, 27 Jan 2021 19:59:01 +0800 Subject: [PATCH 6/6] Update bootstrapped_cross_entropy.py --- paddleseg/models/losses/bootstrapped_cross_entropy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/paddleseg/models/losses/bootstrapped_cross_entropy.py b/paddleseg/models/losses/bootstrapped_cross_entropy.py index c97092b878..6443ccffec 100644 --- a/paddleseg/models/losses/bootstrapped_cross_entropy.py +++ b/paddleseg/models/losses/bootstrapped_cross_entropy.py @@ -41,6 +41,7 @@ def __init__(self, min_K, loss_th, weight=None, ignore_index=255): if weight is not None: weight = paddle.to_tensor(weight, dtype='float32') self.weight = weight + def forward(self, logit, label): n, c, h, w = logit.shape