# Finetuning a selected model # on a selected dataset # using selected parameters from torch.utils.data import DataLoader from sklearn.metrics import classification_report import SetUp from Data import * #from datasets.Casia import * from IdentitySubset import IdentitySubset #from datasets.UniversalIdentitySubset import UniversalIdentitySubset as IdentitySubset # models from architectures.Model import Model, Architecture from unlearning.LinearFiltration import LinearFiltration import Util # WeightFiltration, CertifiedRemoval # numbre of classes CLASS_SIZE = 20 # batch BATCH_SIZE = 32 # size of images per class trainset + testset # 30 works best, more than that and we dont have enough data SAMPLE_SIZE = 30 # this is then (full_sample - test_sample) TRAINING_SMPLE = 27 # learning rate LR_RATE = 0.0001 EPOCHS = 20 # depends on model architecture # ResNet, DenseNet = 224 # Inception = 299 RESOLUTION = 224 # model architecture options are # - RESNET18 # - RESNET50 # - DENSENET121 # - INCEPTION # - GOOGLENET # - EFFICIENTNET # - SHUFFLENET arch = Architecture.RESNET50 # DATA PREPARATION # load data set and prepare dataset = get_set() # select identities for experiment #selected_identities = select_ids( # dataset = dataset, # sample_size = SAMPLE_SIZE, # class_size = CLASS_SIZE # ) # this selects the top 50 based on sample size # that way repeated calls return the same classes selected_identities = select_top_ids( dataset=dataset, class_size= CLASS_SIZE, ) print(f'> Selected {CLASS_SIZE} random identity classes from CelebA dataset.') print(f'> A class has {TRAINING_SMPLE} train and {SAMPLE_SIZE-TRAINING_SMPLE} test samples') # split class images to train/test indices train_indices, test_indices = get_indices( dataset = dataset, identities = selected_identities, split_at = TRAINING_SMPLE ) # helps map class id to index id_map = {old_id: new_id for new_id, old_id in enumerate(selected_identities)} # we remap identities because crossEntropyLoss requires in indices 0 -> (n-1) # where n = class size. tr_transform = train_transform(res = RESOLUTION) train_data = IdentitySubset( dataset=dataset, indices=train_indices, id_mapping=id_map, transform=tr_transform) train_loader = DataLoader( train_data, batch_size = BATCH_SIZE, shuffle = True) print(f"> Total training images: {len(train_data)}") print(f'> Constants : Classes = {CLASS_SIZE}, Batch = {BATCH_SIZE}, epochs = {EPOCHS}') # MODEL PREPARATION # cuda if exists (it does here) device = SetUp.get_device() for i in range(0,CLASS_SIZE): # Create model using Factory model = Model.create( arch = arch, device = device, size = CLASS_SIZE) # we may need to load existing model or finetune model.train( epochs = EPOCHS, loader = train_loader, rate = LR_RATE) # save. model.save(filename=arch.name.lower()) # done tuning # EVALUATE te_transform = test_transform(RESOLUTION) # Testing test_data = IdentitySubset( dataset = dataset, indices=test_indices, id_mapping=id_map, transform=te_transform) test_loader = DataLoader( test_data, batch_size=BATCH_SIZE, shuffle=False) print(f"Total test images for these {CLASS_SIZE} classes: {len(test_data)}") # Evaluate mode, accuracy, report_dict = model.evaluate( loader = test_loader, mode="finetunned" ) Util._log_to_csv(model=reloaded, mode = "finetuned", accuracy=accuracy, report_dict=report_dict, strategy="base") # test again reloaded = Model.create( arch=arch, device = device, size = CLASS_SIZE ) reloaded.load(arch = arch) print("fine tunned model loaded") # reloaded.evaluate( # loader = test_loader #) # Unlearning FORGET_CLASS_IDX = i forget_test_loader, retain_test_loader = get_forget_retain_loaders( dataset=test_data, forget_class_idx=FORGET_CLASS_IDX, batch_size=BATCH_SIZE ) #retain_test_loader = DataLoader(retain_test_loader.dataset, batch_size=BATCH_SIZE, shuffle=False) # 3. Instantiate and apply the Linear Filtration rule filtration = LinearFiltration(target_class_idx=FORGET_CLASS_IDX) filtration.apply(reloaded.model) # 4. Final Performance Analysis print("\n--- Performance on Retained Classes") mode, accuracy, report_dict = reloaded.evaluate(loader=retain_test_loader, mode="retain") Util._log_to_csv(model=reloaded, mode = "retain", accuracy=accuracy, report_dict=report_dict, strategy="linearFiltration") print("\n--- Performance on Forgotten Class") mode, accuracy, report_dict = reloaded.evaluate(loader=forget_test_loader,mode="forget") Util._log_to_csv(model=reloaded, mode = "forgotten", accuracy=accuracy, report_dict=report_dict, strategy="linearFiltration")