prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  STDC training on fp16: Input type (torch.cuda.FloatTensor) and weight type (torch.cuda.HalfTensor) should be the same
  在stdc1_512x1024_80k_cityscapes.py中添加了
  ```
  optimizer_config = dict(type='Fp16OptimizerHook', loss_scale='dynamic')
  fp16 = dict()
  ```
  后再次进行训练则出现了以下报错
  ![avatar](https://img-blog.csdnimg.cn/97204a9e0c434537b3ee297a5d589968.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: `mmseg/models/decode_heads/stdc_head.py`
  Content:
  ```
  1 # Copyright (c) OpenMMLab. All rights reserved.
  2 import torch
  3 import torch.nn.functional as F
  4 
  5 from ..builder import HEADS
  6 from .fcn_head import FCNHead
  7 
  8 
  9 @HEADS.register_module()
  10 class STDCHead(FCNHead):
  11     """This head is the implementation of `Rethinking BiSeNet For Real-time
  12     Semantic Segmentation <https://arxiv.org/abs/2104.13188>`_.
  13 
  14     Args:
  15         boundary_threshold (float): The threshold of calculating boundary.
  16             Default: 0.1.
  17     """
  18 
  19     def __init__(self, boundary_threshold=0.1, **kwargs):
  20         super(STDCHead, self).__init__(**kwargs)
  21         self.boundary_threshold = boundary_threshold
  22         # Using register buffer to make laplacian kernel on the same
  23         # device of `seg_label`.
  24         self.register_buffer(
  25             'laplacian_kernel',
  26             torch.tensor([-1, -1, -1, -1, 8, -1, -1, -1, -1],
  27                          dtype=torch.float32,
  28                          requires_grad=False).reshape((1, 1, 3, 3)))
  29         self.fusion_kernel = torch.nn.Parameter(
  30             torch.tensor([[6. / 10], [3. / 10], [1. / 10]],
  31                          dtype=torch.float32).reshape(1, 3, 1, 1),
  32             requires_grad=False)
  33 
  34     def losses(self, seg_logit, seg_label):
  35         """Compute Detail Aggregation Loss."""
  36         # Note: The paper claims `fusion_kernel` is a trainable 1x1 conv
  37         # parameters. However, it is a constant in original repo and other
  38         # codebase because it would not be added into computation graph
  39         # after threshold operation.
  40         seg_label = seg_label.float()
  41         boundary_targets = F.conv2d(
  42             seg_label, self.laplacian_kernel, padding=1)
  43         boundary_targets = boundary_targets.clamp(min=0)
  44         boundary_targets[boundary_targets > self.boundary_threshold] = 1
  45         boundary_targets[boundary_targets <= self.boundary_threshold] = 0
  46 
  47         boundary_targets_x2 = F.conv2d(
  48             seg_label, self.laplacian_kernel, stride=2, padding=1)
  49         boundary_targets_x2 = boundary_targets_x2.clamp(min=0)
  50 
  51         boundary_targets_x4 = F.conv2d(
  52             seg_label, self.laplacian_kernel, stride=4, padding=1)
  53         boundary_targets_x4 = boundary_targets_x4.clamp(min=0)
  54 
  55         boundary_targets_x4_up = F.interpolate(
  56             boundary_targets_x4, boundary_targets.shape[2:], mode='nearest')
  57         boundary_targets_x2_up = F.interpolate(
  58             boundary_targets_x2, boundary_targets.shape[2:], mode='nearest')
  59 
  60         boundary_targets_x2_up[
  61             boundary_targets_x2_up > self.boundary_threshold] = 1
  62         boundary_targets_x2_up[
  63             boundary_targets_x2_up <= self.boundary_threshold] = 0
  64 
  65         boundary_targets_x4_up[
  66             boundary_targets_x4_up > self.boundary_threshold] = 1
  67         boundary_targets_x4_up[
  68             boundary_targets_x4_up <= self.boundary_threshold] = 0
  69 
  70         boudary_targets_pyramids = torch.stack(
  71             (boundary_targets, boundary_targets_x2_up, boundary_targets_x4_up),
  72             dim=1)
  73 
  74         boudary_targets_pyramids = boudary_targets_pyramids.squeeze(2)
  75         boudary_targets_pyramid = F.conv2d(boudary_targets_pyramids,
  76                                            self.fusion_kernel)
  77 
  78         boudary_targets_pyramid[
  79             boudary_targets_pyramid > self.boundary_threshold] = 1
  80         boudary_targets_pyramid[
  81             boudary_targets_pyramid <= self.boundary_threshold] = 0
  82 
  83         loss = super(STDCHead, self).losses(seg_logit,
  84                                             boudary_targets_pyramid.long())
  85         return loss
  86
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/mmseg/models/decode_heads/stdc_head.py b/mmseg/models/decode_heads/stdc_head.py
  --- a/mmseg/models/decode_heads/stdc_head.py
  +++ b/mmseg/models/decode_heads/stdc_head.py
  @@ -37,7 +37,7 @@
           # parameters. However, it is a constant in original repo and other
           # codebase because it would not be added into computation graph
           # after threshold operation.
  -        seg_label = seg_label.float()
  +        seg_label = seg_label.to(self.laplacian_kernel)
           boundary_targets = F.conv2d(
               seg_label, self.laplacian_kernel, padding=1)
           boundary_targets = boundary_targets.clamp(min=0)
  
verification_info: {"golden_diff": "diff --git a/mmseg/models/decode_heads/stdc_head.py b/mmseg/models/decode_heads/stdc_head.py\n--- a/mmseg/models/decode_heads/stdc_head.py\n+++ b/mmseg/models/decode_heads/stdc_head.py\n@@ -37,7 +37,7 @@\n         # parameters. However, it is a constant in original repo and other\n         # codebase because it would not be added into computation graph\n         # after threshold operation.\n-        seg_label = seg_label.float()\n+        seg_label = seg_label.to(self.laplacian_kernel)\n         boundary_targets = F.conv2d(\n             seg_label, self.laplacian_kernel, padding=1)\n         boundary_targets = boundary_targets.clamp(min=0)\n", "issue": "STDC training on fp16: Input type (torch.cuda.FloatTensor) and weight type (torch.cuda.HalfTensor) should be the same\n\u5728stdc1_512x1024_80k_cityscapes.py\u4e2d\u6dfb\u52a0\u4e86\r\n```\r\noptimizer_config = dict(type='Fp16OptimizerHook', loss_scale='dynamic')\r\nfp16 = dict()\r\n```\r\n\u540e\u518d\u6b21\u8fdb\u884c\u8bad\u7ec3\u5219\u51fa\u73b0\u4e86\u4ee5\u4e0b\u62a5\u9519\r\n![avatar](https://img-blog.csdnimg.cn/97204a9e0c434537b3ee297a5d589968.png)\r\n\r\n\u8bf7\u95ee\u8be5\u5982\u4f55\u4fee\u6539\r\n\r\n\n", "before_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn.functional as F\n\nfrom ..builder import HEADS\nfrom .fcn_head import FCNHead\n\n\n@HEADS.register_module()\nclass STDCHead(FCNHead):\n    \"\"\"This head is the implementation of `Rethinking BiSeNet For Real-time\n    Semantic Segmentation <https://arxiv.org/abs/2104.13188>`_.\n\n    Args:\n        boundary_threshold (float): The threshold of calculating boundary.\n            Default: 0.1.\n    \"\"\"\n\n    def __init__(self, boundary_threshold=0.1, **kwargs):\n        super(STDCHead, self).__init__(**kwargs)\n        self.boundary_threshold = boundary_threshold\n        # Using register buffer to make laplacian kernel on the same\n        # device of `seg_label`.\n        self.register_buffer(\n            'laplacian_kernel',\n            torch.tensor([-1, -1, -1, -1, 8, -1, -1, -1, -1],\n                         dtype=torch.float32,\n                         requires_grad=False).reshape((1, 1, 3, 3)))\n        self.fusion_kernel = torch.nn.Parameter(\n            torch.tensor([[6. / 10], [3. / 10], [1. / 10]],\n                         dtype=torch.float32).reshape(1, 3, 1, 1),\n            requires_grad=False)\n\n    def losses(self, seg_logit, seg_label):\n        \"\"\"Compute Detail Aggregation Loss.\"\"\"\n        # Note: The paper claims `fusion_kernel` is a trainable 1x1 conv\n        # parameters. However, it is a constant in original repo and other\n        # codebase because it would not be added into computation graph\n        # after threshold operation.\n        seg_label = seg_label.float()\n        boundary_targets = F.conv2d(\n            seg_label, self.laplacian_kernel, padding=1)\n        boundary_targets = boundary_targets.clamp(min=0)\n        boundary_targets[boundary_targets > self.boundary_threshold] = 1\n        boundary_targets[boundary_targets <= self.boundary_threshold] = 0\n\n        boundary_targets_x2 = F.conv2d(\n            seg_label, self.laplacian_kernel, stride=2, padding=1)\n        boundary_targets_x2 = boundary_targets_x2.clamp(min=0)\n\n        boundary_targets_x4 = F.conv2d(\n            seg_label, self.laplacian_kernel, stride=4, padding=1)\n        boundary_targets_x4 = boundary_targets_x4.clamp(min=0)\n\n        boundary_targets_x4_up = F.interpolate(\n            boundary_targets_x4, boundary_targets.shape[2:], mode='nearest')\n        boundary_targets_x2_up = F.interpolate(\n            boundary_targets_x2, boundary_targets.shape[2:], mode='nearest')\n\n        boundary_targets_x2_up[\n            boundary_targets_x2_up > self.boundary_threshold] = 1\n        boundary_targets_x2_up[\n            boundary_targets_x2_up <= self.boundary_threshold] = 0\n\n        boundary_targets_x4_up[\n            boundary_targets_x4_up > self.boundary_threshold] = 1\n        boundary_targets_x4_up[\n            boundary_targets_x4_up <= self.boundary_threshold] = 0\n\n        boudary_targets_pyramids = torch.stack(\n            (boundary_targets, boundary_targets_x2_up, boundary_targets_x4_up),\n            dim=1)\n\n        boudary_targets_pyramids = boudary_targets_pyramids.squeeze(2)\n        boudary_targets_pyramid = F.conv2d(boudary_targets_pyramids,\n                                           self.fusion_kernel)\n\n        boudary_targets_pyramid[\n            boudary_targets_pyramid > self.boundary_threshold] = 1\n        boudary_targets_pyramid[\n            boudary_targets_pyramid <= self.boundary_threshold] = 0\n\n        loss = super(STDCHead, self).losses(seg_logit,\n                                            boudary_targets_pyramid.long())\n        return loss\n", "path": "mmseg/models/decode_heads/stdc_head.py"}], "after_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn.functional as F\n\nfrom ..builder import HEADS\nfrom .fcn_head import FCNHead\n\n\n@HEADS.register_module()\nclass STDCHead(FCNHead):\n    \"\"\"This head is the implementation of `Rethinking BiSeNet For Real-time\n    Semantic Segmentation <https://arxiv.org/abs/2104.13188>`_.\n\n    Args:\n        boundary_threshold (float): The threshold of calculating boundary.\n            Default: 0.1.\n    \"\"\"\n\n    def __init__(self, boundary_threshold=0.1, **kwargs):\n        super(STDCHead, self).__init__(**kwargs)\n        self.boundary_threshold = boundary_threshold\n        # Using register buffer to make laplacian kernel on the same\n        # device of `seg_label`.\n        self.register_buffer(\n            'laplacian_kernel',\n            torch.tensor([-1, -1, -1, -1, 8, -1, -1, -1, -1],\n                         dtype=torch.float32,\n                         requires_grad=False).reshape((1, 1, 3, 3)))\n        self.fusion_kernel = torch.nn.Parameter(\n            torch.tensor([[6. / 10], [3. / 10], [1. / 10]],\n                         dtype=torch.float32).reshape(1, 3, 1, 1),\n            requires_grad=False)\n\n    def losses(self, seg_logit, seg_label):\n        \"\"\"Compute Detail Aggregation Loss.\"\"\"\n        # Note: The paper claims `fusion_kernel` is a trainable 1x1 conv\n        # parameters. However, it is a constant in original repo and other\n        # codebase because it would not be added into computation graph\n        # after threshold operation.\n        seg_label = seg_label.to(self.laplacian_kernel)\n        boundary_targets = F.conv2d(\n            seg_label, self.laplacian_kernel, padding=1)\n        boundary_targets = boundary_targets.clamp(min=0)\n        boundary_targets[boundary_targets > self.boundary_threshold] = 1\n        boundary_targets[boundary_targets <= self.boundary_threshold] = 0\n\n        boundary_targets_x2 = F.conv2d(\n            seg_label, self.laplacian_kernel, stride=2, padding=1)\n        boundary_targets_x2 = boundary_targets_x2.clamp(min=0)\n\n        boundary_targets_x4 = F.conv2d(\n            seg_label, self.laplacian_kernel, stride=4, padding=1)\n        boundary_targets_x4 = boundary_targets_x4.clamp(min=0)\n\n        boundary_targets_x4_up = F.interpolate(\n            boundary_targets_x4, boundary_targets.shape[2:], mode='nearest')\n        boundary_targets_x2_up = F.interpolate(\n            boundary_targets_x2, boundary_targets.shape[2:], mode='nearest')\n\n        boundary_targets_x2_up[\n            boundary_targets_x2_up > self.boundary_threshold] = 1\n        boundary_targets_x2_up[\n            boundary_targets_x2_up <= self.boundary_threshold] = 0\n\n        boundary_targets_x4_up[\n            boundary_targets_x4_up > self.boundary_threshold] = 1\n        boundary_targets_x4_up[\n            boundary_targets_x4_up <= self.boundary_threshold] = 0\n\n        boudary_targets_pyramids = torch.stack(\n            (boundary_targets, boundary_targets_x2_up, boundary_targets_x4_up),\n            dim=1)\n\n        boudary_targets_pyramids = boudary_targets_pyramids.squeeze(2)\n        boudary_targets_pyramid = F.conv2d(boudary_targets_pyramids,\n                                           self.fusion_kernel)\n\n        boudary_targets_pyramid[\n            boudary_targets_pyramid > self.boundary_threshold] = 1\n        boudary_targets_pyramid[\n            boudary_targets_pyramid <= self.boundary_threshold] = 0\n\n        loss = super(STDCHead, self).losses(seg_logit,\n                                            boudary_targets_pyramid.long())\n        return loss\n", "path": "mmseg/models/decode_heads/stdc_head.py"}]}