def compute_anomaly_map(self, latent_variables: list[Tensor]) -> Tensor:
        """Generate likelihood-based anomaly map from latent variables.

        The method:
        1. Computes per-scale likelihoods from latent variables
        2. Upscales each likelihood map to input image size
        3. Combines scale likelihoods via averaging

        Args:
            latent_variables (list[Tensor]): List of latent tensors from U-Flow model,
                each with shape ``(batch_size, channels, height, width)``

        Returns:
            Tensor: Anomaly heatmap of shape ``(batch_size, 1, height, width)``
        """
        likelihoods = []
        for z in latent_variables:
            # Mean prob by scale. Likelihood is actually with sum instead of mean. Using mean to avoid numerical issues.
            # Also, this way all scales have the same weight, and it does not depend on the number of channels
            log_prob_i = -torch.mean(z**2, dim=1, keepdim=True) * 0.5
            prob_i = torch.exp(log_prob_i)
            likelihoods.append(
                F.interpolate(
                    prob_i,
                    size=self.input_size,
                    mode="bilinear",
                    align_corners=False,
                ),
            )
        return 1 - torch.mean(torch.stack(likelihoods, dim=-1), dim=-1)
Generate likelihood-based anomaly map from latent variables.

        The method:
        1. Computes per-scale likelihoods from latent variables
        2. Upscales each likelihood map to input image size
        3. Combines scale likelihoods via averaging

        Args:
            latent_variables (list[Tensor]): List of latent tensors from U-Flow model,
                each with shape ``(batch_size, channels, height, width)``

        Returns:
            Tensor: Anomaly heatmap of shape ``(batch_size, 1, height, width)``
        
src/anomalib/models/image/uflow/anomaly_map.py