import torch.nn as nn import time import os from pathlib import Path from torch.utils.data import DataLoader import Util class Strategy: """Abstract base class for unlearning algorithms with automated, strategy-specific logging.""" def __init__(self, target_class_index): # Dynamically set file name based on the class name (e.g., 'NormalizingLinearFiltration.txt') self.strategy_name = self.__class__.__name__ self.target_class_index = target_class_index self.log_file = Path(f"reports/{self.strategy_name}/metrics.txt") Util._initialize_log_file(log_file= self.log_file) def apply(self, model: nn.Module, forget_loader: DataLoader, retain_loader: DataLoader) -> nn.Module: """ Wraps the unlearning execution with automated timing and strategy-specific logging. DO NOT override this method in subclasses. Override _run instead. """ start_time = time.perf_counter() # Execute core unlearning logic processed_model = self._run(model, forget_loader, retain_loader) end_time = time.perf_counter() execution_time = end_time - start_time # Log to the strategy's specific file Util.log_metric( log_file=self.log_file, execution_time=execution_time ) print(f"[{self.strategy_name}] Completed in {execution_time:.6f} seconds. Saved to {self.log_file}") return processed_model def _run(self, model: nn.Module, forget_loader: DataLoader, retain_loader: DataLoader) -> nn.Module: """Subclasses implement their core unlearning logic here.""" raise NotImplementedError