class_docstr: Density estimator for AI-VAD.
  
  Combines density estimators for the different feature types included in the model.
  
  Args:
      use_velocity_features (bool): Flag indicating if velocity features should be used.
      use_pose_features (bool): Flag indicating if pose features should be used.
      use_deep_features (bool): Flag indicating if deep features should be used.
      n_components_velocity (int): Number of components used by GMM density estimation for velocity features.
      n_neighbors_pose (int): Number of neighbors used in KNN density estimation for pose features.
      n_neighbors_deep (int): Number of neighbors used in KNN density estimation for deep features.
docstr: Predict the region- and image-level anomaly scores for an image based on a set of features.
  
  Args:
      features (dict[Tensor]): Dictionary containing extracted features for a single frame.
  
  Returns:
      Tensor: Region-level anomaly scores for all regions withing the frame.
      Tensor: Frame-level anomaly score for the frame.
code: def predict(
      self, features: dict[FeatureType, Tensor]
  ) -> tuple[Tensor, Tensor]:
      """Predict the region- and image-level anomaly scores for an image based on a set of features.
  
      Args:
          features (dict[Tensor]): Dictionary containing extracted features for a single frame.
  
      Returns:
          Tensor: Region-level anomaly scores for all regions withing the frame.
          Tensor: Frame-level anomaly score for the frame.
      """
      n_regions = list(features.values())[0].shape[0]
      device = list(features.values())[0].device
      region_scores = torch.zeros(n_regions).to(device)
      image_score = 0
      if self.use_velocity_features:
          velocity_scores = self.velocity_estimator.predict(
              features[FeatureType.VELOCITY]
          )
          region_scores += velocity_scores
          image_score += velocity_scores.max()
      if self.use_deep_features:
          deep_scores = self.appearance_estimator.predict(
              features[FeatureType.DEEP]
          )
          region_scores += deep_scores
          image_score += deep_scores.max()
      if self.use_pose_features:
          pose_scores = self.pose_estimator.predict(
              features[FeatureType.POSE]
          )
          region_scores += pose_scores
          image_score += pose_scores.max()
      return region_scores, image_score
  
imports: from __future__ import annotations
  from abc import ABC, abstractmethod
  from typing import Any
  import torch
  from sklearn.mixture import GaussianMixture
  from torch import Tensor, nn
  from anomalib.models.ai_vad.features import FeatureType
  from anomalib.utils.metrics.min_max import MinMax
label_desc: Use image node_id 4 for calling the CombinedDensityEstimator obj's underlying member method code with example usage: obj.predict(features) and returns: region_scores,  image_score