code: from __future__ import division
  
  import torch
  import torch.nn as nn
  import torch.nn.functional as F
  
  from .segbase import SegBaseModel
  from .model_zoo import MODEL_REGISTRY
  from ..modules import _FCNHead, PAM_Module, CAM_Module
  
  __all__ = ['DANet']
  
  
  @MODEL_REGISTRY.register()
  class DANet(SegBaseModel):
      r"""DANet model from the paper `"Dual Attention Network for Scene Segmentation"
      <https://arxiv.org/abs/1809.02983.pdf>`
      """
      def __init__(self):
          super(DANet, self).__init__()
          self.head = DANetHead(2048, self.nclass)
          if self.aux:
              self.auxlayer = _FCNHead(728, self.nclass)
          self.__setattr__('decoder', ['head', 'auxlayer'] if self.aux else ['head'])
  
      def forward(self, x):
          imsize = x.size()[2:]
          _, _, c3, c4 = self.encoder(x)
  
          x = self.head(c4)
          x = list(x)
          x[0] = F.interpolate(x[0], imsize, mode='bilinear', align_corners=True)
          x[1] = F.interpolate(x[1], imsize, mode='bilinear', align_corners=True)
          x[2] = F.interpolate(x[2], imsize, mode='bilinear', align_corners=True)
  
          outputs = list()
          outputs.append(x[0])
          outputs.append(x[1])
          outputs.append(x[2])
  
          return tuple(outputs)
  
  
  class DANetHead(nn.Module):
      def __init__(self, in_channels, out_channels, norm_layer=nn.BatchNorm2d):
          super(DANetHead, self).__init__()
          inter_channels = in_channels // 4
          self.conv5a = nn.Sequential(nn.Conv2d(in_channels, inter_channels, 3, padding=1, bias=False),
                                     norm_layer(inter_channels),
                                     nn.ReLU())
          
          self.conv5c = nn.Sequential(nn.Conv2d(in_channels, inter_channels, 3, padding=1, bias=False),
                                     norm_layer(inter_channels),
                                     nn.ReLU())
  
          self.sa = PAM_Module(inter_channels)
          self.sc = CAM_Module(inter_channels)
          self.conv51 = nn.Sequential(nn.Conv2d(inter_channels, inter_channels, 3, padding=1, bias=False),
                                     norm_layer(inter_channels),
                                     nn.ReLU())
          self.conv52 = nn.Sequential(nn.Conv2d(inter_channels, inter_channels, 3, padding=1, bias=False),
                                     norm_layer(inter_channels),
                                     nn.ReLU())
  
          self.conv6 = nn.Sequential(nn.Dropout2d(0.1, False), nn.Conv2d(512, out_channels, 1))
          self.conv7 = nn.Sequential(nn.Dropout2d(0.1, False), nn.Conv2d(512, out_channels, 1))
  
          self.conv8 = nn.Sequential(nn.Dropout2d(0.1, False), nn.Conv2d(512, out_channels, 1))
  
      def forward(self, x):
          feat1 = self.conv5a(x)
          sa_feat = self.sa(feat1)
          sa_conv = self.conv51(sa_feat)
          sa_output = self.conv6(sa_conv)
  
          feat2 = self.conv5c(x)
          sc_feat = self.sc(feat2)
          sc_conv = self.conv52(sc_feat)
          sc_output = self.conv7(sc_conv)
  
          feat_sum = sa_conv+sc_conv
          
          sasc_output = self.conv8(feat_sum)
  
          output = [sasc_output]
          output.append(sa_output)
          output.append(sc_output)
          return tuple(output)
  
  
apis: torch.nn.ReLU torch.nn.Conv2d torch.nn.Dropout2d torch.nn.functional.interpolate