def forward(self, features: list[torch.Tensor] | dict[str, torch.Tensor]) -> torch.Tensor:
        """Forward pass through the descriptor network.

        Args:
            features (list[torch.Tensor] | dict[str, torch.Tensor]): Features
                from the backbone network.

        Returns:
            torch.Tensor: Target-oriented features.

        Example:
            >>> descriptor = Descriptor(gamma_d=1, backbone="resnet18")
            >>> features = [torch.randn(32, 64, 64, 64)]
            >>> target_features = descriptor(features)
        """
        if isinstance(features, dict):
            features = list(features.values())

        patch_features: torch.Tensor | None = None
        for feature in features:
            pooled_features = (
                F.avg_pool2d(feature, 3, 1, 1) / feature.size(1)
                if self.backbone == "efficientnet_b5"
                else F.avg_pool2d(feature, 3, 1, 1)
            )
            patch_features = (
                pooled_features
                if patch_features is None
                else torch.cat((patch_features, F.interpolate(feature, patch_features.size(2), mode="bilinear")), dim=1)
            )

        return self.layer(patch_features)
Forward pass through the descriptor network.

        Args:
            features (list[torch.Tensor] | dict[str, torch.Tensor]): Features
                from the backbone network.

        Returns:
            torch.Tensor: Target-oriented features.

        Example:
            >>> descriptor = Descriptor(gamma_d=1, backbone="resnet18")
            >>> features = [torch.randn(32, 64, 64, 64)]
            >>> target_features = descriptor(features)
        
src/anomalib/models/image/cfa/torch_model.py