text: import torch
  from torch import nn
  from torch.nn import functional as F
  from typing import List
  
  from ._utils import _SimpleSegmentationModel
  
  
  __all__ = ["DeepLabV3"]
  
  
  class DeepLabV3(_SimpleSegmentationModel):
      """
      Implements DeepLabV3 model from
      `"Rethinking Atrous Convolution for Semantic Image Segmentation"
      <https://arxiv.org/abs/1706.05587>`_.
  
      Args:
          backbone (nn.Module): the network used to compute the features for the model.
              The backbone should return an OrderedDict[Tensor], with the key being
              "out" for the last feature map used, and "aux" if an auxiliary classifier
              is used.
          classifier (nn.Module): module that takes the "out" element returned from
              the backbone and returns a dense prediction.
          aux_classifier (nn.Module, optional): auxiliary classifier used during training
      """
      pass
  
  
  class DeepLabHead(nn.Sequential):
      def __init__(self, in_channels: int, num_classes: int, **kwargs) -> None:
          super(DeepLabHead, self).__init__(
              ASPP(in_channels, [12, 24, 36]),
              nn.Conv2d(256, 256, 3, padding=1, bias=False),
              nn.BatchNorm2d(256),
              nn.ReLU(),
              nn.Conv2d(256, num_classes, 1)
          )
  
  
  class ASPPConv(nn.Sequential):
      def __init__(self, in_channels: int, out_channels: int, dilation: int) -> None:
          modules = [
              nn.Conv2d(in_channels, out_channels, 3, padding=dilation, dilation=dilation, bias=False),
              nn.BatchNorm2d(out_channels),
              nn.ReLU()
          ]
          super(ASPPConv, self).__init__(*modules)
  
  
  class ASPPPooling(nn.Sequential):
      def __init__(self, in_channels: int, out_channels: int) -> None:
          super(ASPPPooling, self).__init__(
              nn.AdaptiveAvgPool2d(1),
              nn.Conv2d(in_channels, out_channels, 1, bias=False),
              nn.BatchNorm2d(out_channels),
              nn.ReLU())
  
      def forward(self, x: torch.Tensor) -> torch.Tensor:
          size = x.shape[-2:]
          for mod in self:
              x = mod(x)
          return F.interpolate(x, size=size, mode='bilinear', align_corners=False)
  
  
  class ASPP(nn.Module):
      def __init__(self, in_channels: int, atrous_rates: List[int], out_channels: int = 256) -> None:
          super(ASPP, self).__init__()
          modules = []
          modules.append(nn.Sequential(
              nn.Conv2d(in_channels, out_channels, 1, bias=False),
              nn.BatchNorm2d(out_channels),
              nn.ReLU()))
  
          rates = tuple(atrous_rates)
          for rate in rates:
              modules.append(ASPPConv(in_channels, out_channels, rate))
  
          modules.append(ASPPPooling(in_channels, out_channels))
  
          self.convs = nn.ModuleList(modules)
  
          self.project = nn.Sequential(
              nn.Conv2d(len(self.convs) * out_channels, out_channels, 1, bias=False),
              nn.BatchNorm2d(out_channels),
              nn.ReLU(),
              nn.Dropout(0.5))
  
      def forward(self, x: torch.Tensor) -> torch.Tensor:
          _res = []
          for conv in self.convs:
              _res.append(conv(x))
          res = torch.cat(_res, dim=1)
          return self.project(res)
  