strategies tested

This commit is contained in:
2026-06-14 11:53:31 +02:00
parent e5bddd5ed2
commit 5f09017456
22 changed files with 1228 additions and 367 deletions

View File

@@ -8,8 +8,11 @@ import numpy as np
from sklearn.metrics import classification_report
from pathlib import Path
from unlearning.Strategy import Strategy
import copy
from torch.optim.lr_scheduler import CosineAnnealingLR
class Model(ABC):
# need to add a weight decay here
def __init__(self, device, size):
self.device = device
self.size = size
@@ -21,8 +24,10 @@ class Model(ABC):
def train(self, epochs, loader, rate):
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(filter(lambda p: p.requires_grad, self.model.parameters()), lr=rate)
optimizer = optim.Adam(filter(lambda p: p.requires_grad, self.model.parameters()), lr=rate, weight_decay=0.1)
scheduler = CosineAnnealingLR(optimizer, T_max=epochs, eta_min=1e-6)
print(f"Starting training on {self.device}...")
start_time = time.time()
self.model.train()
@@ -37,41 +42,21 @@ class Model(ABC):
loss.backward()
optimizer.step()
total_loss += loss.item()
scheduler.step()
print(f"Epoch {epoch+1}/{epochs} | Loss: {total_loss / len(loader):.4f}")
if self.device.type == 'cuda': torch.cuda.synchronize()
print(f"Training completed in: {time.time() - start_time:.2f}s")
def evaluate(self, loader):
self.model.eval()
all_preds, all_labels = [], []
print("\nEvaluating...")
with torch.no_grad():
for inputs, labels in loader:
inputs, labels = inputs.to(self.device), labels.to(self.device)
outputs = self.model(inputs)
_, predicted = torch.max(outputs, 1)
all_preds.extend(predicted.cpu().numpy())
all_labels.extend(labels.cpu().numpy())
classes = sorted(list(set(all_labels)))
accuracy = 100 * (np.array(all_preds) == np.array(all_labels)).sum() / len(classes)
print(f"Test Accuracy: {accuracy:.2f}%")
print(classification_report(all_labels, all_preds, labels=classes, zero_division=0))
def save(self, filename=None):
save_dir = Path("trained_models")
save_dir.mkdir(parents=True, exist_ok=True)
# Determine filename (Default to class name if not provided)
# Filename (Default to class name if not provided)
if filename is None:
filename = f"{self.__class__.__name__.lower()}.pth"
@@ -150,65 +135,7 @@ class Model(ABC):
# 3. Delegate file tracking to isolated helper method
#self._log_to_csv(mode, accuracy,report_dict)
return mode, accuracy, report_dict
def _log_to_csv(self, mode, accuracy, report_dict):
"""Handles directory structures, file setups, and distinct CSV column formatting."""
arch_name = self.__class__.__name__.lower()
save_dir = Path("reports")
save_dir.mkdir(parents=True, exist_ok=True)
csv_path = save_dir / f"{arch_name}-{mode}.csv"
file_exists = csv_path.exists()
'''
# Structure payload and headers based on evaluation slice type
if mode == "forget":
headers = ["accuracy", "precision", "recall", "f1-score"]
target_cls_str = str(classes[0])
metrics = report_dict[target_cls_str]
row = [
f"{accuracy / 100.0:.4f}",
f"{metrics['precision']:.4f}",
f"{metrics['recall']:.4f}",
f"{metrics['f1-score']:.4f}"
]
else:
headers = [
"accuracy",
"macro_precision", "macro_recall", "macro_f1",
"weighted_precision", "weighted_recall", "weighted_f1"
]
row = [
f"{accuracy / 100.0:.4f}",
f"{report_dict['macro avg']['precision']:.4f}",
f"{report_dict['macro avg']['recall']:.4f}",
f"{report_dict['macro avg']['f1-score']:.4f}",
f"{report_dict['weighted avg']['precision']:.4f}",
f"{report_dict['weighted avg']['recall']:.4f}",
f"{report_dict['weighted avg']['f1-score']:.4f}"
]'''
headers = [
"accuracy",
"macro_precision", "macro_recall", "macro_f1",
"weighted_precision", "weighted_recall", "weighted_f1"
]
row = [
f"{accuracy / 100.0:.4f}",
f"{report_dict['macro avg']['precision']:.4f}",
f"{report_dict['macro avg']['recall']:.4f}",
f"{report_dict['macro avg']['f1-score']:.4f}",
f"{report_dict['weighted avg']['precision']:.4f}",
f"{report_dict['weighted avg']['recall']:.4f}",
f"{report_dict['weighted avg']['f1-score']:.4f}"
]
with open(csv_path, "a") as f:
if not file_exists:
f.write(",".join(headers) + "\n")
f.write(",".join(row) + "\n")
print(f">> Direct CSV metrics appended to {csv_path}")
return accuracy, report_dict