def fit(self) -> None:
        """Fit the KNN model by stacking features and computing normalization stats.

        Stacks the collected feature vectors group-wise and computes the normalization
        statistics. After fitting, the feature collection is deleted to free up memory.

        Example:
            >>> estimator = GroupedKNNEstimator(n_neighbors=5)
            >>> features = torch.randn(32, 512)  # (N, D)
            >>> estimator.update(features, group="video_1")
            >>> estimator.fit()
        """
        # stack the collected features group-wise
        feature_collection = {key: torch.vstack(value) for key, value in self.feature_collection.items()}
        # assign memory bank, group index and group names
        self.memory_bank = torch.vstack(list(feature_collection.values()))
        self.group_index = torch.repeat_interleave(
            Tensor([features.shape[0] for features in feature_collection.values()]).int(),
        )
        self.group_names = list(feature_collection.keys())
        self._compute_normalization_statistics(feature_collection)
        # delete the feature collection to free up memory
        del self.feature_collection
Fit the KNN model by stacking features and computing normalization stats.

        Stacks the collected feature vectors group-wise and computes the normalization
        statistics. After fitting, the feature collection is deleted to free up memory.

        Example:
            >>> estimator = GroupedKNNEstimator(n_neighbors=5)
            >>> features = torch.randn(32, 512)  # (N, D)
            >>> estimator.update(features, group="video_1")
            >>> estimator.fit()
        
src/anomalib/models/video/ai_vad/density.py