import time from pathlib import Path import torch import torch.nn as nn from torch.utils.data import DataLoader from unlearning.Strategy import Strategy from architectures.Model import Model, Architecture class Retrain(Strategy): """ Implements the Exact Unlearning Baseline by re-instantiating a fresh, pre-trained instance of the specific architecture and training it from scratch on the retain set using the Model's internal train function. """ def __init__(self, target_class_index: int, arch: Architecture, size: int, lr: float = 0.001, epochs: int = 5): super().__init__(target_class_index) self.arch = arch self.size = size self.lr = lr self.epochs = epochs def _run(self, model: nn.Module, forget_loader: DataLoader, retain_loader: DataLoader) -> nn.Module: # 1. Determine the active execution device from the running sandbox device = next(model.parameters()).device print(f">> Triggering Exact Unlearning Baseline (Retraining {self.arch.name} from pristine state)...") # a new model with default params is created fresh_meat = Model.create(self.arch, device, self.size) # we train it with retain set fresh_meat.train( epochs=self.epochs, loader=retain_loader, rate=self.lr, mode="retrain" ) # 4. Extract the trained nn.Module parameter state dict # In-place copy onto the existing sandbox model structure to seamlessly retain downstream evaluations model.load_state_dict(fresh_meat.model.state_dict()) print(">> Retraining pipeline finished. Pristine baseline weights successfully established.") return model def _split_data(self, dataset): from sets.Data import get_unlearning_loaders return get_unlearning_loaders( dataset=dataset, forget_class_idx=self.target_class_index, batch_size=32 )