We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DecoupledSegNet错误
1.环境：（首先安装cpu版本，测试成功）
 
![当前环境](https://user-images.githubusercontent.com/52094265/115170646-aaeba880-a0f3-11eb-8a22-04cd130f4ddb.png)


2.安装GPU版本
命令：python -m pip install paddlepaddle-gpu==2.0.0 -i https://mirror.baidu.com/pypi/simple

3.出现问题
 
![出现问题一](https://user-images.githubusercontent.com/52094265/115170506-62cc8600-a0f3-11eb-8160-fc211569fce5.png)

4.解决方案
（1）env | grep cuda
（2）port LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
（3） /usr/local/cuda/lib64
（4）ln -s libcusolver.so.10 libcusolver.so

5. 运行 
Python./train.py -config ./configs/decoupled_segnet/decoupledsegnet_resnet50_os8_cityscapes_832x832_80k.yml

6.新问题
![出现问题二](https://user-images.githubusercontent.com/52094265/115170587-91e2f780-a0f3-11eb-81a7-42b22cedd807.png)




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `paddleseg/models/decoupled_segnet.py`
Content:
```
1 # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 import cv2
16 import numpy as np
17 import paddle
18 import paddle.nn as nn
19 import paddle.nn.functional as F
20 
21 from paddleseg.cvlibs import manager
22 from paddleseg.models import layers
23 from paddleseg.models.backbones import resnet_vd
24 from paddleseg.models import deeplab
25 from paddleseg.utils import utils
26 
27 
28 @manager.MODELS.add_component
29 class DecoupledSegNet(nn.Layer):
30     """
31     The DecoupledSegNet implementation based on PaddlePaddle.
32 
33     The original article refers to
34     Xiangtai Li, et, al. "Improving Semantic Segmentation via Decoupled Body and Edge Supervision"
35     (https://arxiv.org/pdf/2007.10035.pdf)
36 
37     Args:
38         num_classes (int): The unique number of target classes.
39         backbone (paddle.nn.Layer): Backbone network, currently support Resnet50_vd/Resnet101_vd.
40         backbone_indices (tuple, optional): Two values in the tuple indicate the indices of output of backbone.
41            Default: (0, 3).
42         aspp_ratios (tuple, optional): The dilation rate using in ASSP module.
43             If output_stride=16, aspp_ratios should be set as (1, 6, 12, 18).
44             If output_stride=8, aspp_ratios is (1, 12, 24, 36).
45             Default: (1, 6, 12, 18).
46         aspp_out_channels (int, optional): The output channels of ASPP module. Default: 256.
47         align_corners (bool, optional): An argument of F.interpolate. It should be set to False when the feature size is even,
48             e.g. 1024x512, otherwise it is True, e.g. 769x769. Default: False.
49         pretrained (str, optional): The path or url of pretrained model. Default: None.
50     """
51 
52     def __init__(self,
53                  num_classes,
54                  backbone,
55                  backbone_indices=(0, 3),
56                  aspp_ratios=(1, 6, 12, 18),
57                  aspp_out_channels=256,
58                  align_corners=False,
59                  pretrained=None):
60         super().__init__()
61         self.backbone = backbone
62         backbone_channels = self.backbone.feat_channels
63         self.head = DecoupledSegNetHead(num_classes, backbone_indices,
64                                         backbone_channels, aspp_ratios,
65                                         aspp_out_channels, align_corners)
66         self.align_corners = align_corners
67         self.pretrained = pretrained
68         self.init_weight()
69 
70     def forward(self, x):
71         feat_list = self.backbone(x)
72         logit_list = self.head(feat_list)
73 
74         seg_logit, body_logit, edge_logit = [
75             F.interpolate(
76                 logit,
77                 paddle.shape(x)[2:],
78                 mode='bilinear',
79                 align_corners=self.align_corners) for logit in logit_list
80         ]
81 
82         return [seg_logit, body_logit, edge_logit, (seg_logit, edge_logit)]
83 
84     def init_weight(self):
85         if self.pretrained is not None:
86             utils.load_entire_model(self, self.pretrained)
87 
88 
89 class DecoupledSegNetHead(nn.Layer):
90     """
91     The DecoupledSegNetHead implementation based on PaddlePaddle.
92 
93     Args:
94         num_classes (int): The unique number of target classes.
95         backbone_indices (tuple): Two values in the tuple indicate the indices of output of backbone.
96             the first index will be taken as a low-level feature in Edge presevation component;
97             the second one will be taken as input of ASPP component.
98         backbone_channels (tuple): The channels of output of backbone.
99         aspp_ratios (tuple): The dilation rates using in ASSP module.
100         aspp_out_channels (int): The output channels of ASPP module.
101         align_corners (bool): An argument of F.interpolate. It should be set to False when the output size of feature
102             is even, e.g. 1024x512, otherwise it is True, e.g. 769x769.
103     """
104 
105     def __init__(self, num_classes, backbone_indices, backbone_channels,
106                  aspp_ratios, aspp_out_channels, align_corners):
107         super().__init__()
108         self.backbone_indices = backbone_indices
109         self.align_corners = align_corners
110         self.aspp = layers.ASPPModule(
111             aspp_ratios=aspp_ratios,
112             in_channels=backbone_channels[backbone_indices[1]],
113             out_channels=aspp_out_channels,
114             align_corners=align_corners,
115             image_pooling=True)
116 
117         self.bot_fine = nn.Conv2D(
118             backbone_channels[backbone_indices[0]], 48, 1, bias_attr=False)
119         # decoupled
120         self.squeeze_body_edge = SqueezeBodyEdge(
121             256, align_corners=self.align_corners)
122         self.edge_fusion = nn.Conv2D(256 + 48, 256, 1, bias_attr=False)
123         self.sigmoid_edge = nn.Sigmoid()
124         self.edge_out = nn.Sequential(
125             layers.ConvBNReLU(
126                 in_channels=256,
127                 out_channels=48,
128                 kernel_size=3,
129                 bias_attr=False), nn.Conv2D(48, 1, 1, bias_attr=False))
130         self.dsn_seg_body = nn.Sequential(
131             layers.ConvBNReLU(
132                 in_channels=256,
133                 out_channels=256,
134                 kernel_size=3,
135                 bias_attr=False), nn.Conv2D(
136                     256, num_classes, 1, bias_attr=False))
137 
138         self.final_seg = nn.Sequential(
139             layers.ConvBNReLU(
140                 in_channels=512,
141                 out_channels=256,
142                 kernel_size=3,
143                 bias_attr=False),
144             layers.ConvBNReLU(
145                 in_channels=256,
146                 out_channels=256,
147                 kernel_size=3,
148                 bias_attr=False),
149             nn.Conv2D(256, num_classes, kernel_size=1, bias_attr=False))
150 
151     def forward(self, feat_list):
152         fine_fea = feat_list[self.backbone_indices[0]]
153         fine_size = paddle.shape(fine_fea)
154         x = feat_list[self.backbone_indices[1]]
155         aspp = self.aspp(x)
156 
157         # decoupled
158         seg_body, seg_edge = self.squeeze_body_edge(aspp)
159         # Edge presevation and edge out
160         fine_fea = self.bot_fine(fine_fea)
161         seg_edge = F.interpolate(
162             seg_edge,
163             fine_size[2:],
164             mode='bilinear',
165             align_corners=self.align_corners)
166         seg_edge = self.edge_fusion(paddle.concat([seg_edge, fine_fea], axis=1))
167         seg_edge_out = self.edge_out(seg_edge)
168         seg_edge_out = self.sigmoid_edge(seg_edge_out)  # seg_edge output
169         seg_body_out = self.dsn_seg_body(seg_body)  # body out
170 
171         # seg_final out
172         seg_out = seg_edge + F.interpolate(
173             seg_body,
174             fine_size[2:],
175             mode='bilinear',
176             align_corners=self.align_corners)
177         aspp = F.interpolate(
178             aspp,
179             fine_size[2:],
180             mode='bilinear',
181             align_corners=self.align_corners)
182         seg_out = paddle.concat([aspp, seg_out], axis=1)
183         seg_final_out = self.final_seg(seg_out)
184 
185         return [seg_final_out, seg_body_out, seg_edge_out]
186 
187 
188 class SqueezeBodyEdge(nn.Layer):
189     def __init__(self, inplane, align_corners=False):
190         super().__init__()
191         self.align_corners = align_corners
192         self.down = nn.Sequential(
193             layers.ConvBNReLU(
194                 inplane, inplane, kernel_size=3, groups=inplane, stride=2),
195             layers.ConvBNReLU(
196                 inplane, inplane, kernel_size=3, groups=inplane, stride=2))
197         self.flow_make = nn.Conv2D(
198             inplane * 2, 2, kernel_size=3, padding='same', bias_attr=False)
199 
200     def forward(self, x):
201         size = paddle.shape(x)[2:]
202         seg_down = self.down(x)
203         seg_down = F.interpolate(
204             seg_down,
205             size=size,
206             mode='bilinear',
207             align_corners=self.align_corners)
208         flow = self.flow_make(paddle.concat([x, seg_down], axis=1))
209         seg_flow_warp = self.flow_warp(x, flow, size)
210         seg_edge = x - seg_flow_warp
211         return seg_flow_warp, seg_edge
212 
213     def flow_warp(self, input, flow, size):
214         input_shape = paddle.shape(input)
215         norm = size[::-1].reshape([1, 1, 1, -1])
216         h_grid = paddle.linspace(-1.0, 1.0, size[0]).reshape([-1, 1])
217         h_grid = h_grid.tile([size[1]])
218         w_grid = paddle.linspace(-1.0, 1.0, size[1]).reshape([-1, 1])
219         w_grid = w_grid.tile([size[0]]).transpose([1, 0])
220         grid = paddle.concat([w_grid.unsqueeze(2), h_grid.unsqueeze(2)], axis=2)
221         grid.unsqueeze(0).tile([input_shape[0], 1, 1, 1])
222         grid = grid + paddle.transpose(flow, (0, 2, 3, 1)) / norm
223 
224         output = F.grid_sample(input, grid)
225         return output
226
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/paddleseg/models/decoupled_segnet.py b/paddleseg/models/decoupled_segnet.py
--- a/paddleseg/models/decoupled_segnet.py
+++ b/paddleseg/models/decoupled_segnet.py
@@ -213,6 +213,7 @@
     def flow_warp(self, input, flow, size):
         input_shape = paddle.shape(input)
         norm = size[::-1].reshape([1, 1, 1, -1])
+        norm.stop_gradient = True
         h_grid = paddle.linspace(-1.0, 1.0, size[0]).reshape([-1, 1])
         h_grid = h_grid.tile([size[1]])
         w_grid = paddle.linspace(-1.0, 1.0, size[1]).reshape([-1, 1])

{"golden_diff": "diff --git a/paddleseg/models/decoupled_segnet.py b/paddleseg/models/decoupled_segnet.py\n--- a/paddleseg/models/decoupled_segnet.py\n+++ b/paddleseg/models/decoupled_segnet.py\n@@ -213,6 +213,7 @@\n     def flow_warp(self, input, flow, size):\n         input_shape = paddle.shape(input)\n         norm = size[::-1].reshape([1, 1, 1, -1])\n+        norm.stop_gradient = True\n         h_grid = paddle.linspace(-1.0, 1.0, size[0]).reshape([-1, 1])\n         h_grid = h_grid.tile([size[1]])\n         w_grid = paddle.linspace(-1.0, 1.0, size[1]).reshape([-1, 1])\n", "issue": "DecoupledSegNet\u9519\u8bef\n1.\u73af\u5883\uff1a\uff08\u9996\u5148\u5b89\u88c5cpu\u7248\u672c\uff0c\u6d4b\u8bd5\u6210\u529f\uff09\r\n \r\n![\u5f53\u524d\u73af\u5883](https://user-images.githubusercontent.com/52094265/115170646-aaeba880-a0f3-11eb-8a22-04cd130f4ddb.png)\r\n\r\n\r\n2.\u5b89\u88c5GPU\u7248\u672c\r\n\u547d\u4ee4\uff1apython -m pip install paddlepaddle-gpu==2.0.0 -i https://mirror.baidu.com/pypi/simple\r\n\r\n3.\u51fa\u73b0\u95ee\u9898\r\n \r\n![\u51fa\u73b0\u95ee\u9898\u4e00](https://user-images.githubusercontent.com/52094265/115170506-62cc8600-a0f3-11eb-8160-fc211569fce5.png)\r\n\r\n4.\u89e3\u51b3\u65b9\u6848\r\n\uff081\uff09env | grep cuda\r\n\uff082\uff09port LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64\r\n\uff083\uff09 /usr/local/cuda/lib64\r\n\uff084\uff09ln -s libcusolver.so.10 libcusolver.so\r\n\r\n5. \u8fd0\u884c \r\nPython./train.py -config ./configs/decoupled_segnet/decoupledsegnet_resnet50_os8_cityscapes_832x832_80k.yml\r\n\r\n6.\u65b0\u95ee\u9898\r\n![\u51fa\u73b0\u95ee\u9898\u4e8c](https://user-images.githubusercontent.com/52094265/115170587-91e2f780-a0f3-11eb-81a7-42b22cedd807.png)\r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport cv2\nimport numpy as np\nimport paddle\nimport paddle.nn as nn\nimport paddle.nn.functional as F\n\nfrom paddleseg.cvlibs import manager\nfrom paddleseg.models import layers\nfrom paddleseg.models.backbones import resnet_vd\nfrom paddleseg.models import deeplab\nfrom paddleseg.utils import utils\n\n\n@manager.MODELS.add_component\nclass DecoupledSegNet(nn.Layer):\n    \"\"\"\n    The DecoupledSegNet implementation based on PaddlePaddle.\n\n    The original article refers to\n    Xiangtai Li, et, al. \"Improving Semantic Segmentation via Decoupled Body and Edge Supervision\"\n    (https://arxiv.org/pdf/2007.10035.pdf)\n\n    Args:\n        num_classes (int): The unique number of target classes.\n        backbone (paddle.nn.Layer): Backbone network, currently support Resnet50_vd/Resnet101_vd.\n        backbone_indices (tuple, optional): Two values in the tuple indicate the indices of output of backbone.\n           Default: (0, 3).\n        aspp_ratios (tuple, optional): The dilation rate using in ASSP module.\n            If output_stride=16, aspp_ratios should be set as (1, 6, 12, 18).\n            If output_stride=8, aspp_ratios is (1, 12, 24, 36).\n            Default: (1, 6, 12, 18).\n        aspp_out_channels (int, optional): The output channels of ASPP module. Default: 256.\n        align_corners (bool, optional): An argument of F.interpolate. It should be set to False when the feature size is even,\n            e.g. 1024x512, otherwise it is True, e.g. 769x769. Default: False.\n        pretrained (str, optional): The path or url of pretrained model. Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 num_classes,\n                 backbone,\n                 backbone_indices=(0, 3),\n                 aspp_ratios=(1, 6, 12, 18),\n                 aspp_out_channels=256,\n                 align_corners=False,\n                 pretrained=None):\n        super().__init__()\n        self.backbone = backbone\n        backbone_channels = self.backbone.feat_channels\n        self.head = DecoupledSegNetHead(num_classes, backbone_indices,\n                                        backbone_channels, aspp_ratios,\n                                        aspp_out_channels, align_corners)\n        self.align_corners = align_corners\n        self.pretrained = pretrained\n        self.init_weight()\n\n    def forward(self, x):\n        feat_list = self.backbone(x)\n        logit_list = self.head(feat_list)\n\n        seg_logit, body_logit, edge_logit = [\n            F.interpolate(\n                logit,\n                paddle.shape(x)[2:],\n                mode='bilinear',\n                align_corners=self.align_corners) for logit in logit_list\n        ]\n\n        return [seg_logit, body_logit, edge_logit, (seg_logit, edge_logit)]\n\n    def init_weight(self):\n        if self.pretrained is not None:\n            utils.load_entire_model(self, self.pretrained)\n\n\nclass DecoupledSegNetHead(nn.Layer):\n    \"\"\"\n    The DecoupledSegNetHead implementation based on PaddlePaddle.\n\n    Args:\n        num_classes (int): The unique number of target classes.\n        backbone_indices (tuple): Two values in the tuple indicate the indices of output of backbone.\n            the first index will be taken as a low-level feature in Edge presevation component;\n            the second one will be taken as input of ASPP component.\n        backbone_channels (tuple): The channels of output of backbone.\n        aspp_ratios (tuple): The dilation rates using in ASSP module.\n        aspp_out_channels (int): The output channels of ASPP module.\n        align_corners (bool): An argument of F.interpolate. It should be set to False when the output size of feature\n            is even, e.g. 1024x512, otherwise it is True, e.g. 769x769.\n    \"\"\"\n\n    def __init__(self, num_classes, backbone_indices, backbone_channels,\n                 aspp_ratios, aspp_out_channels, align_corners):\n        super().__init__()\n        self.backbone_indices = backbone_indices\n        self.align_corners = align_corners\n        self.aspp = layers.ASPPModule(\n            aspp_ratios=aspp_ratios,\n            in_channels=backbone_channels[backbone_indices[1]],\n            out_channels=aspp_out_channels,\n            align_corners=align_corners,\n            image_pooling=True)\n\n        self.bot_fine = nn.Conv2D(\n            backbone_channels[backbone_indices[0]], 48, 1, bias_attr=False)\n        # decoupled\n        self.squeeze_body_edge = SqueezeBodyEdge(\n            256, align_corners=self.align_corners)\n        self.edge_fusion = nn.Conv2D(256 + 48, 256, 1, bias_attr=False)\n        self.sigmoid_edge = nn.Sigmoid()\n        self.edge_out = nn.Sequential(\n            layers.ConvBNReLU(\n                in_channels=256,\n                out_channels=48,\n                kernel_size=3,\n                bias_attr=False), nn.Conv2D(48, 1, 1, bias_attr=False))\n        self.dsn_seg_body = nn.Sequential(\n            layers.ConvBNReLU(\n                in_channels=256,\n                out_channels=256,\n                kernel_size=3,\n                bias_attr=False), nn.Conv2D(\n                    256, num_classes, 1, bias_attr=False))\n\n        self.final_seg = nn.Sequential(\n            layers.ConvBNReLU(\n                in_channels=512,\n                out_channels=256,\n                kernel_size=3,\n                bias_attr=False),\n            layers.ConvBNReLU(\n                in_channels=256,\n                out_channels=256,\n                kernel_size=3,\n                bias_attr=False),\n            nn.Conv2D(256, num_classes, kernel_size=1, bias_attr=False))\n\n    def forward(self, feat_list):\n        fine_fea = feat_list[self.backbone_indices[0]]\n        fine_size = paddle.shape(fine_fea)\n        x = feat_list[self.backbone_indices[1]]\n        aspp = self.aspp(x)\n\n        # decoupled\n        seg_body, seg_edge = self.squeeze_body_edge(aspp)\n        # Edge presevation and edge out\n        fine_fea = self.bot_fine(fine_fea)\n        seg_edge = F.interpolate(\n            seg_edge,\n            fine_size[2:],\n            mode='bilinear',\n            align_corners=self.align_corners)\n        seg_edge = self.edge_fusion(paddle.concat([seg_edge, fine_fea], axis=1))\n        seg_edge_out = self.edge_out(seg_edge)\n        seg_edge_out = self.sigmoid_edge(seg_edge_out)  # seg_edge output\n        seg_body_out = self.dsn_seg_body(seg_body)  # body out\n\n        # seg_final out\n        seg_out = seg_edge + F.interpolate(\n            seg_body,\n            fine_size[2:],\n            mode='bilinear',\n            align_corners=self.align_corners)\n        aspp = F.interpolate(\n            aspp,\n            fine_size[2:],\n            mode='bilinear',\n            align_corners=self.align_corners)\n        seg_out = paddle.concat([aspp, seg_out], axis=1)\n        seg_final_out = self.final_seg(seg_out)\n\n        return [seg_final_out, seg_body_out, seg_edge_out]\n\n\nclass SqueezeBodyEdge(nn.Layer):\n    def __init__(self, inplane, align_corners=False):\n        super().__init__()\n        self.align_corners = align_corners\n        self.down = nn.Sequential(\n            layers.ConvBNReLU(\n                inplane, inplane, kernel_size=3, groups=inplane, stride=2),\n            layers.ConvBNReLU(\n                inplane, inplane, kernel_size=3, groups=inplane, stride=2))\n        self.flow_make = nn.Conv2D(\n            inplane * 2, 2, kernel_size=3, padding='same', bias_attr=False)\n\n    def forward(self, x):\n        size = paddle.shape(x)[2:]\n        seg_down = self.down(x)\n        seg_down = F.interpolate(\n            seg_down,\n            size=size,\n            mode='bilinear',\n            align_corners=self.align_corners)\n        flow = self.flow_make(paddle.concat([x, seg_down], axis=1))\n        seg_flow_warp = self.flow_warp(x, flow, size)\n        seg_edge = x - seg_flow_warp\n        return seg_flow_warp, seg_edge\n\n    def flow_warp(self, input, flow, size):\n        input_shape = paddle.shape(input)\n        norm = size[::-1].reshape([1, 1, 1, -1])\n        h_grid = paddle.linspace(-1.0, 1.0, size[0]).reshape([-1, 1])\n        h_grid = h_grid.tile([size[1]])\n        w_grid = paddle.linspace(-1.0, 1.0, size[1]).reshape([-1, 1])\n        w_grid = w_grid.tile([size[0]]).transpose([1, 0])\n        grid = paddle.concat([w_grid.unsqueeze(2), h_grid.unsqueeze(2)], axis=2)\n        grid.unsqueeze(0).tile([input_shape[0], 1, 1, 1])\n        grid = grid + paddle.transpose(flow, (0, 2, 3, 1)) / norm\n\n        output = F.grid_sample(input, grid)\n        return output\n", "path": "paddleseg/models/decoupled_segnet.py"}], "after_files": [{"content": "# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport cv2\nimport numpy as np\nimport paddle\nimport paddle.nn as nn\nimport paddle.nn.functional as F\n\nfrom paddleseg.cvlibs import manager\nfrom paddleseg.models import layers\nfrom paddleseg.models.backbones import resnet_vd\nfrom paddleseg.models import deeplab\nfrom paddleseg.utils import utils\n\n\n@manager.MODELS.add_component\nclass DecoupledSegNet(nn.Layer):\n    \"\"\"\n    The DecoupledSegNet implementation based on PaddlePaddle.\n\n    The original article refers to\n    Xiangtai Li, et, al. \"Improving Semantic Segmentation via Decoupled Body and Edge Supervision\"\n    (https://arxiv.org/pdf/2007.10035.pdf)\n\n    Args:\n        num_classes (int): The unique number of target classes.\n        backbone (paddle.nn.Layer): Backbone network, currently support Resnet50_vd/Resnet101_vd.\n        backbone_indices (tuple, optional): Two values in the tuple indicate the indices of output of backbone.\n           Default: (0, 3).\n        aspp_ratios (tuple, optional): The dilation rate using in ASSP module.\n            If output_stride=16, aspp_ratios should be set as (1, 6, 12, 18).\n            If output_stride=8, aspp_ratios is (1, 12, 24, 36).\n            Default: (1, 6, 12, 18).\n        aspp_out_channels (int, optional): The output channels of ASPP module. Default: 256.\n        align_corners (bool, optional): An argument of F.interpolate. It should be set to False when the feature size is even,\n            e.g. 1024x512, otherwise it is True, e.g. 769x769. Default: False.\n        pretrained (str, optional): The path or url of pretrained model. Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 num_classes,\n                 backbone,\n                 backbone_indices=(0, 3),\n                 aspp_ratios=(1, 6, 12, 18),\n                 aspp_out_channels=256,\n                 align_corners=False,\n                 pretrained=None):\n        super().__init__()\n        self.backbone = backbone\n        backbone_channels = self.backbone.feat_channels\n        self.head = DecoupledSegNetHead(num_classes, backbone_indices,\n                                        backbone_channels, aspp_ratios,\n                                        aspp_out_channels, align_corners)\n        self.align_corners = align_corners\n        self.pretrained = pretrained\n        self.init_weight()\n\n    def forward(self, x):\n        feat_list = self.backbone(x)\n        logit_list = self.head(feat_list)\n\n        seg_logit, body_logit, edge_logit = [\n            F.interpolate(\n                logit,\n                paddle.shape(x)[2:],\n                mode='bilinear',\n                align_corners=self.align_corners) for logit in logit_list\n        ]\n\n        return [seg_logit, body_logit, edge_logit, (seg_logit, edge_logit)]\n\n    def init_weight(self):\n        if self.pretrained is not None:\n            utils.load_entire_model(self, self.pretrained)\n\n\nclass DecoupledSegNetHead(nn.Layer):\n    \"\"\"\n    The DecoupledSegNetHead implementation based on PaddlePaddle.\n\n    Args:\n        num_classes (int): The unique number of target classes.\n        backbone_indices (tuple): Two values in the tuple indicate the indices of output of backbone.\n            the first index will be taken as a low-level feature in Edge presevation component;\n            the second one will be taken as input of ASPP component.\n        backbone_channels (tuple): The channels of output of backbone.\n        aspp_ratios (tuple): The dilation rates using in ASSP module.\n        aspp_out_channels (int): The output channels of ASPP module.\n        align_corners (bool): An argument of F.interpolate. It should be set to False when the output size of feature\n            is even, e.g. 1024x512, otherwise it is True, e.g. 769x769.\n    \"\"\"\n\n    def __init__(self, num_classes, backbone_indices, backbone_channels,\n                 aspp_ratios, aspp_out_channels, align_corners):\n        super().__init__()\n        self.backbone_indices = backbone_indices\n        self.align_corners = align_corners\n        self.aspp = layers.ASPPModule(\n            aspp_ratios=aspp_ratios,\n            in_channels=backbone_channels[backbone_indices[1]],\n            out_channels=aspp_out_channels,\n            align_corners=align_corners,\n            image_pooling=True)\n\n        self.bot_fine = nn.Conv2D(\n            backbone_channels[backbone_indices[0]], 48, 1, bias_attr=False)\n        # decoupled\n        self.squeeze_body_edge = SqueezeBodyEdge(\n            256, align_corners=self.align_corners)\n        self.edge_fusion = nn.Conv2D(256 + 48, 256, 1, bias_attr=False)\n        self.sigmoid_edge = nn.Sigmoid()\n        self.edge_out = nn.Sequential(\n            layers.ConvBNReLU(\n                in_channels=256,\n                out_channels=48,\n                kernel_size=3,\n                bias_attr=False), nn.Conv2D(48, 1, 1, bias_attr=False))\n        self.dsn_seg_body = nn.Sequential(\n            layers.ConvBNReLU(\n                in_channels=256,\n                out_channels=256,\n                kernel_size=3,\n                bias_attr=False), nn.Conv2D(\n                    256, num_classes, 1, bias_attr=False))\n\n        self.final_seg = nn.Sequential(\n            layers.ConvBNReLU(\n                in_channels=512,\n                out_channels=256,\n                kernel_size=3,\n                bias_attr=False),\n            layers.ConvBNReLU(\n                in_channels=256,\n                out_channels=256,\n                kernel_size=3,\n                bias_attr=False),\n            nn.Conv2D(256, num_classes, kernel_size=1, bias_attr=False))\n\n    def forward(self, feat_list):\n        fine_fea = feat_list[self.backbone_indices[0]]\n        fine_size = paddle.shape(fine_fea)\n        x = feat_list[self.backbone_indices[1]]\n        aspp = self.aspp(x)\n\n        # decoupled\n        seg_body, seg_edge = self.squeeze_body_edge(aspp)\n        # Edge presevation and edge out\n        fine_fea = self.bot_fine(fine_fea)\n        seg_edge = F.interpolate(\n            seg_edge,\n            fine_size[2:],\n            mode='bilinear',\n            align_corners=self.align_corners)\n        seg_edge = self.edge_fusion(paddle.concat([seg_edge, fine_fea], axis=1))\n        seg_edge_out = self.edge_out(seg_edge)\n        seg_edge_out = self.sigmoid_edge(seg_edge_out)  # seg_edge output\n        seg_body_out = self.dsn_seg_body(seg_body)  # body out\n\n        # seg_final out\n        seg_out = seg_edge + F.interpolate(\n            seg_body,\n            fine_size[2:],\n            mode='bilinear',\n            align_corners=self.align_corners)\n        aspp = F.interpolate(\n            aspp,\n            fine_size[2:],\n            mode='bilinear',\n            align_corners=self.align_corners)\n        seg_out = paddle.concat([aspp, seg_out], axis=1)\n        seg_final_out = self.final_seg(seg_out)\n\n        return [seg_final_out, seg_body_out, seg_edge_out]\n\n\nclass SqueezeBodyEdge(nn.Layer):\n    def __init__(self, inplane, align_corners=False):\n        super().__init__()\n        self.align_corners = align_corners\n        self.down = nn.Sequential(\n            layers.ConvBNReLU(\n                inplane, inplane, kernel_size=3, groups=inplane, stride=2),\n            layers.ConvBNReLU(\n                inplane, inplane, kernel_size=3, groups=inplane, stride=2))\n        self.flow_make = nn.Conv2D(\n            inplane * 2, 2, kernel_size=3, padding='same', bias_attr=False)\n\n    def forward(self, x):\n        size = paddle.shape(x)[2:]\n        seg_down = self.down(x)\n        seg_down = F.interpolate(\n            seg_down,\n            size=size,\n            mode='bilinear',\n            align_corners=self.align_corners)\n        flow = self.flow_make(paddle.concat([x, seg_down], axis=1))\n        seg_flow_warp = self.flow_warp(x, flow, size)\n        seg_edge = x - seg_flow_warp\n        return seg_flow_warp, seg_edge\n\n    def flow_warp(self, input, flow, size):\n        input_shape = paddle.shape(input)\n        norm = size[::-1].reshape([1, 1, 1, -1])\n        norm.stop_gradient = True\n        h_grid = paddle.linspace(-1.0, 1.0, size[0]).reshape([-1, 1])\n        h_grid = h_grid.tile([size[1]])\n        w_grid = paddle.linspace(-1.0, 1.0, size[1]).reshape([-1, 1])\n        w_grid = w_grid.tile([size[0]]).transpose([1, 0])\n        grid = paddle.concat([w_grid.unsqueeze(2), h_grid.unsqueeze(2)], axis=2)\n        grid.unsqueeze(0).tile([input_shape[0], 1, 1, 1])\n        grid = grid + paddle.transpose(flow, (0, 2, 3, 1)) / norm\n\n        output = F.grid_sample(input, grid)\n        return output\n", "path": "paddleseg/models/decoupled_segnet.py"}]}