def forward(encoder_features: list[torch.Tensor], decoder_features: list[torch.Tensor]) -> torch.Tensor:
        """Compute cosine similarity loss between encoder and decoder features.

        Args:
            encoder_features (list[torch.Tensor]): List of feature tensors from the
                encoder network. Each tensor has shape ``(B, C, H, W)`` where B is
                batch size, C is channels, H and W are spatial dimensions.
            decoder_features (list[torch.Tensor]): List of feature tensors from the
                decoder network. Must match encoder features in length and shapes.

        Returns:
            torch.Tensor: Scalar loss value computed as mean of (1 - cosine
                similarity) across all feature pairs.
        """
        cos_loss = torch.nn.CosineSimilarity()
        loss_sum = 0
        for encoder_feature, decoder_feature in zip(encoder_features, decoder_features, strict=True):
            loss_sum += torch.mean(
                1
                - cos_loss(
                    encoder_feature.view(encoder_feature.shape[0], -1),
                    decoder_feature.view(decoder_feature.shape[0], -1),
                ),
            )
        return loss_sum
Compute cosine similarity loss between encoder and decoder features.

        Args:
            encoder_features (list[torch.Tensor]): List of feature tensors from the
                encoder network. Each tensor has shape ``(B, C, H, W)`` where B is
                batch size, C is channels, H and W are spatial dimensions.
            decoder_features (list[torch.Tensor]): List of feature tensors from the
                decoder network. Must match encoder features in length and shapes.

        Returns:
            torch.Tensor: Scalar loss value computed as mean of (1 - cosine
                similarity) across all feature pairs.
        
src/anomalib/models/image/reverse_distillation/loss.py