def forward(self, features: List[torch.Tensor]) -> torch.Tensor:
        """
        Args:
            features (List[torch.Tensor]):
                features with: [1, 1/2, 1/4, 1/8, 1/16, ...] spatial resolutions,
                where the first feature is the highest resolution and the number
                of features is equal to encoder_depth + 1.
        """

        # skip 1/1 and 1/2 resolution features
        features = features[2:]

        # normalize feature maps
        for i, norm in enumerate(self.feature_norms):
            features[i] = norm(features[i])

        # pass lowest resolution feature to PSP module
        psp_out = self.psp(features[-1])

        # skip lowest features for FPN + reverse the order
        # [1/4, 1/8, 1/16, 1/32] -> [1/16, 1/8, 1/4]
        fpn_lateral_features = features[:-1][::-1]
        fpn_features = [psp_out]
        for i, block in enumerate(self.fpn_lateral_blocks):
            # 1. for each encoder (skip) feature we apply 1x1 ConvNormRelu,
            # 2. upsample latest fpn feature to it's resolution
            # 3. sum them together
            lateral_feature = fpn_lateral_features[i]
            state_feature = fpn_features[-1]
            fpn_feature = block(state_feature, lateral_feature)
            fpn_features.append(fpn_feature)

        # Apply FPN conv blocks, but skip PSP module
        for i, conv_block in enumerate(self.fpn_conv_blocks, start=1):
            fpn_features[i] = conv_block(fpn_features[i])

        # Resize all FPN features to 1/4 of the original resolution.
        resized_fpn_features = []
        target_size = fpn_features[-1].shape[2:]  # 1/4 of the original resolution
        for feature in fpn_features:
            resized_feature = F.interpolate(
                feature, size=target_size, mode="bilinear", align_corners=False
            )
            resized_fpn_features.append(resized_feature)

        # reverse and concatenate
        stacked_features = torch.cat(resized_fpn_features[::-1], dim=1)
        output = self.fusion_block(stacked_features)
        return output

        Args:
            features (List[torch.Tensor]):
                features with: [1, 1/2, 1/4, 1/8, 1/16, ...] spatial resolutions,
                where the first feature is the highest resolution and the number
                of features is equal to encoder_depth + 1.
        
segmentation_models_pytorch/decoders/upernet/decoder.py