class_docstr: Progressive Shuffle head takes the largest feature map and progressively upsample it to the original image size.
  Upsampling is done by doing [Conv3x3 + BN + Activation + Conv1x1 + PixelShuffle].
  At each stage number of channels is reduced by a factor given by `reduction_factor`.
code: def __init__(
      self,
      input_spec: FeatureMapsSpecification,
      num_classes: int,
      activation: str,
      dropout_rate,
      output_name: Optional[str],
      reduction_factor: int = 2,
      normalization: str = NORM_BATCH,
      normalization_kwargs: Optional[Mapping] = None,
  ):
      super().__init__(input_spec)
  
      self.num_classes = num_classes
      self.feature_map_index = (
          input_spec.get_index_of_largest_feature_map()
      )
      self.output_name = output_name
  
      min_stride = input_spec.strides[self.feature_map_index]
      num_upsample_blocks = int(np.log2(min_stride))
      in_channels = input_spec.channels[self.feature_map_index]
      blocks = []
  
      for _ in range(num_upsample_blocks):
          out_channels = divisible(in_channels / reduction_factor, 8)
          blocks.append(
              ProgressiveShuffleBlock(
                  in_channels,
                  out_channels,
                  activation=activation,
                  normalization=normalization,
                  normalization_kwargs=normalization_kwargs,
              )
          )
          in_channels = out_channels
  
      blocks += [
          nn.Dropout2d(p=dropout_rate),
      ]
  
      self.blocks = nn.Sequential(*blocks)
      self.final = nn.Conv2d(
          in_channels,
          self.num_classes,
          kernel_size=3,
          padding=1,
          bias=True,
      )
  
      self.output_spec = FeatureMapsSpecification(
          channels=(num_classes,), strides=(1,)
      )
  
file_path: pytorch-toolbelt/pytorch_toolbelt/modules/heads/progressive_shuffle.py
imports: from typing import Optional, Callable, Mapping
  import numpy
  from torch import nn
  from pytorch_toolbelt.modules import instantiate_activation_block
  from pytorch_toolbelt.modules.interfaces import AbstractHead, FeatureMapsSpecification
  from pytorch_toolbelt.modules.normalization import NORM_BATCH, instantiate_normalization_block
label_desc: Use image node_id 1 to create a new ProgressiveShuffleHead object from inherited base classes: AbstractHead with example: obj = ProgressiveShuffleHead(input_spec, num_classes, activation, dropout_rate, output_name, reduction_factor, normalization, normalization_kwargs)