├── .gitignore ├── README.md ├── data_utils.py ├── experiment_code ├── agreement_analysis │ ├── .ipynb_checkpoints │ │ └── compare_models-checkpoint.ipynb │ ├── compare_models.ipynb │ ├── description.txt │ └── generate_models.py ├── early_training_analysis │ ├── Hessian.ipynb │ ├── description.txt │ └── recognition.ipynb ├── influence_analysis │ ├── description.txt │ └── influence.ipynb └── replacement_analysis │ ├── .ipynb_checkpoints │ ├── pretrained_visualization-checkpoint.ipynb │ └── training_sensitivity-checkpoint.ipynb │ ├── description.txt │ ├── pretrained_visualization.ipynb │ └── training_sensitivity.ipynb ├── experiment_results └── placeholder.txt ├── model_utils.py ├── networks.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.pth 2 | *.pt 3 | */.ipynb_checkpoints/* 4 | */.ipynb_checkpoints/ 5 | */*/.ipynb_checkpoints/* 6 | __pycache__/ 7 | data/ 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [What is Dataset Distillation Learning?](https://arxiv.org/abs/2406.04284) 2 | 3 | After cloning the repo, download the distilled data and pretrained model from [Google Drive](https://drive.google.com/drive/folders/1kTQnt5WszAgifbyCYVPnaUYQrdqlAkNT?usp=sharing). 4 | Afterwards, create the conda enviroment: 5 | ``` 6 | conda create -n learning python=3.10.12 7 | conda activate learning 8 | pip install -r requirements.txt 9 | ``` 10 | ## Distilled vs. Real Data 11 | To run analyses done in Section 3 of the paper, refer to the two jupyter notebooks in [experiment_code/replacement_analysis](https://github.com/princetonvisualai/What-is-Dataset-Distillation-Learning/tree/main/experiment_code/replacement_analysis) 12 | 13 | ## Information Captured by Distilled Data 14 | ### Predictions of models trained on distilled data is similar to models trained with early-stopping 15 | Generate a pool of subset-trained-models and early-stopped-models by running 16 | ``` 17 | python experiment_code/agreement_analysis/generate_models.py 18 | ``` 19 | Finally, compare and visualize the prediction differences using the [jupyter notebook](https://github.com/princetonvisualai/What-is-Dataset-Distillation-Learning/blob/main/experiment_code/agreement_analysis/compare_models.ipynb). 20 | 21 | ### Recognition on the distilled data is learned early in the training process 22 | Use [jupyter notebook](https://github.com/princetonvisualai/What-is-Dataset-Distillation-Learning/blob/main/experiment_code/early_training_analysis/recognition.ipynb). 23 | 24 | ### Distilled data stores little information beyond what would be learned early in training 25 | Refer to [jupyter notebook](https://github.com/princetonvisualai/What-is-Dataset-Distillation-Learning/blob/main/experiment_code/early_training_analysis/Hessian.ipynb). 26 | 27 | Note: computing Hessian approximation for the whole training data takes a long time (10+ hours on a L40 GPU). Comment out this Hessian computation if there is a lack of compute resources (Hessian calculations on distilled data is notably less resource intensive). 28 | 29 | ## Semantics of Captured Information 30 | Use [jupyter notebook](https://github.com/princetonvisualai/What-is-Dataset-Distillation-Learning/blob/main/experiment_code/influence_analysis/influence.ipynb) to generate the qualitative analysis (Figure 10) of the paper. For quantitative analysis, refer to the [LLaVa repo](https://github.com/haotian-liu/LLaVA). 31 | -------------------------------------------------------------------------------- /data_utils.py: -------------------------------------------------------------------------------- 1 | ### code retrieved from https://github.com/princetonvisualai/RememberThePast-DatasetDistillation 2 | import os 3 | import numpy as np 4 | import torch 5 | import torch.nn as nn 6 | import torch.nn.functional as F 7 | from torch.utils.data import Dataset 8 | from torchvision import datasets, transforms 9 | import copy 10 | 11 | 12 | import pickle 13 | from PIL import Image 14 | import os.path as osp 15 | 16 | THIS_PATH = osp.dirname(__file__) 17 | ROOT_PATH = osp.abspath(osp.join(THIS_PATH, '..')) 18 | 19 | class MiniimagenetDataset(Dataset): 20 | def __init__(self, setname, transform=None): 21 | setname = setname 22 | PICKLE_PATH = osp.join(ROOT_PATH, 'data/miniimagenet/') 23 | pickle_path = osp.join(PICKLE_PATH, 'mini-imagenet-cache-' + setname + '.pkl') 24 | pickle_data = pickle.load(open(pickle_path, "rb" )) 25 | self.data, self.targets, self.classes = self.process_pkl(pickle_data) 26 | self.transform = transform 27 | 28 | def __len__(self): 29 | return self.data.shape[0] 30 | 31 | def process_pkl(self, pickle_data): 32 | data = pickle_data['image_data'] 33 | class_dict = pickle_data['class_dict'] 34 | label = [-1] * data.shape[0] 35 | classnames = [ele for ele in class_dict.keys()] 36 | 37 | lbl = 0 38 | for cls in class_dict: 39 | for idx in class_dict[cls]: 40 | label[idx] = lbl 41 | lbl += 1 42 | return data, label, classnames 43 | 44 | def __getitem__(self, idx): 45 | img = self.data[idx] 46 | target = self.targets[idx] 47 | if self.transform: 48 | img = self.transform(Image.fromarray(img.astype(np.uint8))) 49 | return img, target 50 | 51 | 52 | class CIFAR10Dataset(datasets.CIFAR10): 53 | def __getitem__(self, idx): 54 | return self.data[idx], self.targets[idx] 55 | 56 | 57 | class CIFAR100Dataset(datasets.CIFAR100): 58 | def __getitem__(self, idx): 59 | return self.data[idx], self.targets[idx] 60 | 61 | 62 | class SVHNDataset(datasets.SVHN): 63 | def __getitem__(self, idx): 64 | return self.data[idx], int(self.labels[idx]) 65 | 66 | 67 | def _split_validation(data, targets, validation_ratio): 68 | if isinstance(targets, torch.Tensor): 69 | label_set = set(targets.tolist()) 70 | else: 71 | label_set = set(targets) 72 | ttype = 'tensor' 73 | if isinstance(targets, list): 74 | ttype = 'list' 75 | targets = torch.Tensor(targets) 76 | 77 | train_data_set = [] 78 | train_label_set = [] 79 | val_data_set = [] 80 | val_label_set = [] 81 | for c in label_set: 82 | data_c = data[targets==c] 83 | targets_c = targets[targets==c] 84 | 85 | n_val = int(data_c.shape[0] * validation_ratio) 86 | n_train = data_c.shape[0] - n_val 87 | 88 | indices = torch.randperm(data_c.shape[0]) 89 | train_indices = indices[:n_train] 90 | val_indices = indices[n_train:] 91 | 92 | train_data_c = data_c[train_indices] 93 | val_data_c = data_c[val_indices] 94 | train_label_c = targets_c[train_indices] 95 | val_label_c = targets_c[val_indices] 96 | 97 | train_data_set.append(train_data_c) 98 | train_label_set.extend(train_label_c.long().tolist()) 99 | val_data_set.append(val_data_c) 100 | val_label_set.extend(val_label_c.long().tolist()) 101 | 102 | train_data_set = torch.cat(train_data_set, dim=0) 103 | val_data_set = torch.cat(val_data_set,dim=0) 104 | if ttype == 'tensor': 105 | train_label_set = torch.Tensor(train_label_set).long() 106 | val_label_set = torch.Tensor(val_label_set).long() 107 | return train_data_set, train_label_set, val_data_set, val_label_set 108 | 109 | 110 | def split_validation(dst_train, dst_test, validation_ratio, dataset): 111 | if dataset in ['SVHN']: 112 | data = dst_train.data 113 | targets = dst_train.labels 114 | else: 115 | data = dst_train.data 116 | targets = dst_train.targets 117 | 118 | train_data, train_label, val_data, val_label = _split_validation(data, targets, validation_ratio) 119 | 120 | if dataset in ['SVHN']: 121 | dst_train.data = train_data 122 | dst_train.labels = train_label 123 | dst_test.data = val_data 124 | dst_test.labels = val_label 125 | else: 126 | dst_train.data = train_data 127 | dst_train.targets = train_label 128 | dst_test.data = val_data 129 | dst_test.targets = val_label 130 | 131 | return dst_train, dst_test 132 | 133 | 134 | def organize_dst(dst_train, num_classes, print_info=True, dset_name='none', split='train', im_size=None): 135 | images_all = [] 136 | labels_all = [] 137 | indices_class = [[] for c in range(num_classes)] 138 | 139 | data_loaded = None 140 | if data_loaded is None: 141 | images_all = [torch.unsqueeze(dst_train[i][0], dim=0) for i in range(len(dst_train))] 142 | labels_all = [dst_train[i][1] for i in range(len(dst_train))] 143 | images_all = torch.cat(images_all, dim=0) 144 | else: 145 | images_all = data_loaded['images_all'] 146 | labels_all = data_loaded['labels_all'] 147 | labels_all = labels_all.tolist() 148 | print('Total number:', images_all.shape[0]) 149 | 150 | for i, lab in enumerate(labels_all): 151 | if isinstance(lab, list): 152 | indices_class[lab[-1]].append(i) 153 | else: 154 | indices_class[lab].append(i) 155 | labels_all = torch.tensor(labels_all, dtype=torch.long) 156 | 157 | if print_info: 158 | for c in range(num_classes): 159 | print('class c = %d: %d real images'%(c, len(indices_class[c]))) 160 | 161 | for ch in range(images_all.shape[1]): 162 | print('real images channel %d, mean = %.4f, std = %.4f'%( 163 | ch, torch.mean(images_all[:, ch]), torch.std(images_all[:, ch]))) 164 | 165 | return images_all, labels_all, indices_class 166 | 167 | 168 | def get_images(c, n, images_all, indices_class): # get random n images from class c 169 | idx_shuffle = np.random.permutation(indices_class[c])[:n] 170 | # for debugging 171 | #idx_shuffle = indices_class[c][:n] 172 | return images_all[idx_shuffle] 173 | 174 | 175 | def get_images_labels(c, n, images_all, labels_all, indices_class): # get random n images from class c 176 | idx_shuffle = np.random.permutation(indices_class[c])[:n] 177 | return images_all[idx_shuffle], labels_all[idx_shuffle] 178 | 179 | 180 | def select_k_classes(dst, classes, indent): 181 | data = dst.data 182 | targets = np.array(dst.targets) 183 | new_data = [] 184 | new_targets = [] 185 | for c in classes: 186 | data_c = data[targets==c] 187 | targets_c = targets[targets==c] 188 | new_data.append(data_c) 189 | new_targets.append(targets_c-indent) 190 | new_data = np.vstack(new_data) 191 | new_targets = np.hstack(new_targets).tolist() 192 | return new_data, new_targets 193 | 194 | 195 | def get_dataset_config(dataset): 196 | if dataset == 'MNIST': 197 | channel = 1 198 | im_size = 28 199 | n_class = 10 200 | 201 | elif dataset == 'FashionMNIST': 202 | channel = 1 203 | im_size = 28 204 | n_class = 10 205 | 206 | elif dataset == 'SVHN': 207 | channel = 3 208 | im_size = 32 209 | n_class = 10 210 | 211 | elif dataset == 'CIFAR10': 212 | channel = 3 213 | im_size = 32 214 | n_class = 10 215 | 216 | elif dataset == 'CIFAR100': 217 | channel = 3 218 | im_size = 32 219 | n_class = 100 220 | 221 | elif 'CIFAR100_10' in dataset: 222 | channel = 3 223 | im_size = 32 224 | n_class = 10 225 | 226 | elif 'CIFAR100_5' in dataset: 227 | channel = 3 228 | im_size = 32 229 | n_class = 5 230 | 231 | elif 'CIFAR100_15' in dataset: 232 | channel = 3 233 | im_size = 32 234 | n_class = 15 235 | 236 | elif dataset == 'MiniImagenet': 237 | channel = 3 238 | im_size = 84 239 | n_class = 64 240 | 241 | elif dataset == 'TinyImagenet': 242 | channel = 3 243 | im_size = 64 244 | n_class = 200 245 | 246 | elif dataset == 'TinyImagenetDM': 247 | channel = 3 248 | im_size = 64 249 | n_class = 200 250 | 251 | else: 252 | exit('unknown dataset: %s'%dataset) 253 | 254 | return channel, im_size, n_class 255 | 256 | 257 | def get_dataset(dataset, data_path, zca=False, manual_size=None, use_val=True, validation_ratio=0, test_on_train=False): 258 | if dataset == 'MNIST': 259 | channel = 1 260 | im_size = (28, 28) 261 | train_num_classes = 10 262 | test_num_classes = 10 263 | mean = [0.1307] 264 | std = [0.3081] 265 | transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)]) 266 | dst_train = datasets.MNIST(data_path, train=True, download=True, transform=transform) # no augmentation 267 | dst_test = datasets.MNIST(data_path, train=False, download=True, transform=transform) 268 | class_names = [str(c) for c in range(train_num_classes)] 269 | 270 | elif dataset == 'rotMNIST-task1': 271 | channel = 1 272 | im_size = (28, 28) 273 | train_num_classes = 10 274 | test_num_classes = 10 275 | mean = [0.1307] 276 | std = [0.3081] 277 | #data_loaded = torch.load('data/rmnist_task1.pt') 278 | train_data_loaded = torch.load('data/rmnist_task5_train.pt') 279 | test_data_loaded = torch.load('data/rmnist_task5_test.pt') 280 | 281 | #transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)]) 282 | transform = transforms.Compose([transforms.ToTensor()]) 283 | dst_train = datasets.MNIST(data_path, train=True, download=True, transform=transform) # no augmentation 284 | dst_test = datasets.MNIST(data_path, train=False, download=True, transform=transform) 285 | 286 | dst_train.data, dst_train.targets = train_data_loaded['x_train'].detach().cpu(), train_data_loaded['y_train'].detach().cpu() 287 | dst_test.data, dst_test.targets = test_data_loaded['x_test'].detach().cpu(), test_data_loaded['y_test'].detach().cpu() 288 | 289 | class_names = [str(c) for c in range(train_num_classes)] 290 | 291 | elif dataset == 'FashionMNIST': 292 | channel = 1 293 | im_size = (28, 28) 294 | train_num_classes = 10 295 | test_num_classes = 10 296 | mean = [0.2861] 297 | std = [0.3530] 298 | transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)]) 299 | dst_train = datasets.FashionMNIST(data_path, train=True, download=True, transform=transform) # no augmentation 300 | dst_test = datasets.FashionMNIST(data_path, train=False, download=True, transform=transform) 301 | class_names = dst_train.classes 302 | 303 | elif dataset == 'SVHN': 304 | channel = 3 305 | im_size = (32, 32) 306 | train_num_classes = 10 307 | test_num_classes = 10 308 | mean = [0.4377, 0.4438, 0.4728] 309 | std = [0.1980, 0.2010, 0.1970] 310 | if zca: 311 | print('Using ZCA') 312 | transform = None 313 | dst_train = SVHNDataset(data_path, split='train', download=True, transform=transform) # no augmentation 314 | dst_test = SVHNDataset(data_path, split='test', download=True, transform=transform) 315 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=100, permute=False) 316 | else: 317 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 318 | if manual_size is not None and manual_size > 0: 319 | im_size = (manual_size, manual_size) 320 | transform_seq.append(transforms.Resize(manual_size)) 321 | transform = transforms.Compose(transform_seq) 322 | dst_train = datasets.SVHN(data_path, split='train', download=True, transform=transform) # no augmentation 323 | dst_test = datasets.SVHN(data_path, split='test', download=True, transform=transform) 324 | class_names = [str(c) for c in range(train_num_classes)] 325 | assert train_num_classes == test_num_classes 326 | 327 | elif dataset == 'CIFAR10': 328 | channel = 3 329 | im_size = (32, 32) 330 | train_num_classes = 10 331 | test_num_classes = 10 332 | mean = [0.4914, 0.4822, 0.4465] 333 | std = [0.2023, 0.1994, 0.2010] 334 | if zca: 335 | print('Using ZCA') 336 | transform = None 337 | dst_train = CIFAR10Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 338 | dst_test = CIFAR10Dataset(data_path, train=False, download=True, transform=transform) 339 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 340 | else: 341 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 342 | if manual_size is not None and manual_size > 0: 343 | im_size = (manual_size, manual_size) 344 | transform_seq.append(transforms.Resize(manual_size)) 345 | transform = transforms.Compose(transform_seq) 346 | dst_train = datasets.CIFAR10(data_path, train=True, download=True, transform=transform) # no augmentation 347 | dst_test = datasets.CIFAR10(data_path, train=False, download=True, transform=transform) 348 | class_names = dst_train.classes 349 | 350 | elif dataset == 'CIFAR10Half': 351 | channel = 3 352 | im_size = (32, 32) 353 | train_num_classes = 5 354 | test_num_classes = 5 355 | mean = [0.4914, 0.4822, 0.4465] 356 | std = [0.2023, 0.1994, 0.2010] 357 | if zca: 358 | print('Using ZCA') 359 | transform = None 360 | dst_train = CIFAR10Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 361 | dst_test = CIFAR10Dataset(data_path, train=False, download=True, transform=transform) 362 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 363 | else: 364 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 365 | if manual_size is not None and manual_size > 0: 366 | im_size = (manual_size, manual_size) 367 | transform_seq.append(transforms.Resize(manual_size)) 368 | transform = transforms.Compose(transform_seq) 369 | dst_train = datasets.CIFAR10(data_path, train=True, download=True, transform=transform) # no augmentation 370 | dst_test = datasets.CIFAR10(data_path, train=False, download=True, transform=transform) 371 | task_id = 0 372 | dst_train.data, dst_train.targets = select_k_classes(dst_train, list(range(5*task_id, 5*(task_id+1))), indent=5*task_id) 373 | dst_test.data, dst_test.targets = select_k_classes(dst_test, list(range(5*task_id, 5*(task_id+1))), indent=5*task_id) 374 | class_names = dst_train.classes 375 | 376 | elif dataset == 'CIFAR10FSL': 377 | channel = 3 378 | im_size = (32, 32) 379 | train_num_classes = 5 380 | test_num_classes = 5 381 | mean = [0.4914, 0.4822, 0.4465] 382 | std = [0.2023, 0.1994, 0.2010] 383 | if zca: 384 | print('Using ZCA') 385 | transform = None 386 | dst_train = CIFAR10Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 387 | dst_test = CIFAR10Dataset(data_path, train=False, download=True, transform=transform) 388 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 389 | else: 390 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 391 | if manual_size is not None and manual_size > 0: 392 | im_size = (manual_size, manual_size) 393 | transform_seq.append(transforms.Resize(manual_size)) 394 | transform = transforms.Compose(transform_seq) 395 | dst_train = datasets.CIFAR10(data_path, train=True, download=True, transform=transform) # no augmentation 396 | dst_test = datasets.CIFAR10(data_path, train=False, download=True, transform=transform) 397 | dst_train.data, dst_train.targets = select_k_classes(dst_train, list(range(5)), indent=0) 398 | dst_test.data, dst_test.targets = select_k_classes(dst_test, list(range(5,10)), indent=5) 399 | class_names = dst_train.classes 400 | 401 | elif dataset == 'CIFAR100': 402 | channel = 3 403 | im_size = (32, 32) 404 | train_num_classes = 100 405 | test_num_classes = 100 406 | #num_classes = 5 407 | mean = [0.5071, 0.4867, 0.4408] 408 | std = [0.2675, 0.2565, 0.2761] 409 | if zca: 410 | print('Using ZCA') 411 | transform = None 412 | dst_train = CIFAR100Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 413 | dst_test = CIFAR100Dataset(data_path, train=False, download=True, transform=transform) 414 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 415 | else: 416 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 417 | if manual_size is not None and manual_size > 0: 418 | im_size = (manual_size, manual_size) 419 | transform_seq.append(transforms.Resize(manual_size)) 420 | transform = transforms.Compose(transform_seq) 421 | dst_train = datasets.CIFAR100(data_path, train=True, download=True, transform=transform) # no augmentation 422 | dst_test = datasets.CIFAR100(data_path, train=False, download=True, transform=transform) 423 | 424 | class_names = dst_train.classes 425 | 426 | elif 'CIFAR100_5' in dataset: 427 | channel = 3 428 | im_size = (32, 32) 429 | train_num_classes = 5 430 | test_num_classes = 5 431 | mean = [0.5071, 0.4867, 0.4408] 432 | std = [0.2675, 0.2565, 0.2761] 433 | task_id = int(dataset.split('_')[-1]) 434 | if zca: 435 | print('Using ZCA') 436 | transform = None 437 | dst_train = CIFAR100Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 438 | dst_test = CIFAR100Dataset(data_path, train=False, download=True, transform=transform) 439 | dst_train.data, dst_train.targets = select_k_classes( 440 | dst_train, 441 | list(range(5*task_id, 5*(task_id+1))), 442 | indent=5*task_id 443 | ) 444 | dst_test.data, dst_test.targets = select_k_classes( 445 | dst_test, 446 | list(range(5*task_id, 5*(task_id+1))), 447 | indent=5*task_id 448 | ) 449 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 450 | else: 451 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 452 | if manual_size is not None and manual_size > 0: 453 | im_size = (manual_size, manual_size) 454 | transform_seq.append(transforms.Resize(manual_size)) 455 | transform = transforms.Compose(transform_seq) 456 | dst_train = datasets.CIFAR100(data_path, train=True, download=True, transform=transform) # no augmentation 457 | dst_test = datasets.CIFAR100(data_path, train=False, download=True, transform=transform) 458 | dst_train.data, dst_train.targets = select_k_classes( 459 | dst_train, 460 | list(range(5*task_id, 5*(task_id+1))), 461 | indent=5*task_id 462 | ) 463 | dst_test.data, dst_test.targets = select_k_classes( 464 | dst_test, 465 | list(range(5*task_id, 5*(task_id+1))), 466 | indent=5*task_id 467 | ) 468 | class_names = dst_train.classes 469 | 470 | elif 'CIFAR100_15' in dataset: 471 | channel = 3 472 | im_size = (32, 32) 473 | train_num_classes = 15 474 | test_num_classes = 15 475 | mean = [0.5071, 0.4867, 0.4408] 476 | std = [0.2675, 0.2565, 0.2761] 477 | task_id = int(dataset.split('_')[-1]) 478 | if zca: 479 | print('Using ZCA') 480 | transform = None 481 | dst_train = CIFAR100Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 482 | dst_test = CIFAR100Dataset(data_path, train=False, download=True, transform=transform) 483 | dst_train.data, dst_train.targets = select_k_classes( 484 | dst_train, 485 | list(range(15*task_id, 15*(task_id+1))), 486 | indent=15*task_id 487 | ) 488 | dst_test.data, dst_test.targets = select_k_classes( 489 | dst_test, 490 | list(range(15*task_id, 15*(task_id+1))), 491 | indent=15*task_id 492 | ) 493 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 494 | else: 495 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 496 | if manual_size is not None and manual_size > 0: 497 | im_size = (manual_size, manual_size) 498 | transform_seq.append(transforms.Resize(manual_size)) 499 | transform = transforms.Compose(transform_seq) 500 | dst_train = datasets.CIFAR100(data_path, train=True, download=True, transform=transform) # no augmentation 501 | dst_test = datasets.CIFAR100(data_path, train=False, download=True, transform=transform) 502 | dst_train.data, dst_train.targets = select_k_classes( 503 | dst_train, 504 | list(range(15*task_id, 15*(task_id+1))), 505 | indent=15*task_id 506 | ) 507 | dst_test.data, dst_test.targets = select_k_classes( 508 | dst_test, 509 | list(range(15*task_id, 15*(task_id+1))), 510 | indent=15*task_id 511 | ) 512 | class_names = dst_train.classes 513 | 514 | elif 'CIFAR100_10' in dataset: 515 | channel = 3 516 | im_size = (32, 32) 517 | train_num_classes = 10 518 | test_num_classes = 10 519 | #num_classes = 5 520 | mean = [0.5071, 0.4867, 0.4408] 521 | std = [0.2675, 0.2565, 0.2761] 522 | task_id = int(dataset.split('_')[-1]) 523 | if zca: 524 | print('Using ZCA') 525 | transform = None 526 | dst_train = CIFAR100Dataset(data_path, train=True, download=True, transform=transform) # no augmentation 527 | dst_test = CIFAR100Dataset(data_path, train=False, download=True, transform=transform) 528 | dst_train.data, dst_train.targets = select_k_classes( 529 | dst_train, 530 | list(range(10*task_id, 10*(task_id+1))), 531 | indent=10*task_id 532 | ) 533 | dst_test.data, dst_test.targets = select_k_classes( 534 | dst_test, 535 | list(range(10*task_id, 10*(task_id+1))), 536 | indent=10*task_id 537 | ) 538 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 539 | else: 540 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 541 | if manual_size is not None and manual_size > 0: 542 | im_size = (manual_size, manual_size) 543 | transform_seq.append(transforms.Resize(manual_size)) 544 | transform = transforms.Compose(transform_seq) 545 | dst_train = datasets.CIFAR100(data_path, train=True, download=True, transform=transform) # no augmentation 546 | dst_test = datasets.CIFAR100(data_path, train=False, download=True, transform=transform) 547 | dst_train.data, dst_train.targets = select_k_classes( 548 | dst_train, 549 | list(range(10*task_id, 10*(task_id+1))), 550 | indent=10*task_id 551 | ) 552 | dst_test.data, dst_test.targets = select_k_classes( 553 | dst_test, 554 | list(range(10*task_id, 10*(task_id+1))), 555 | indent=10*task_id 556 | ) 557 | class_names = dst_train.classes 558 | 559 | elif dataset == 'MiniImagenet': 560 | channel = 3 561 | im_size = (84, 84) 562 | mean = [0.485, 0.456, 0.406] 563 | std = [0.229, 0.224, 0.225] 564 | if zca: 565 | print('Using ZCA') 566 | transform = None 567 | dst_train = MiniimagenetDataset(setname='train', transform=transform) 568 | dst_test = MiniimagenetDataset(setname='train', transform=transform) 569 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 570 | else: 571 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 572 | if manual_size is not None and manual_size > 0: 573 | im_size = (manual_size, manual_size) 574 | transform_seq.append(transforms.Resize(manual_size)) 575 | transform = transforms.Compose(transform_seq) 576 | dst_train = MiniimagenetDataset(setname='train', transform=transform) 577 | dst_test = MiniimagenetDataset(setname='train', transform=transform) 578 | class_names = dst_train.classes 579 | train_num_classes = len(dst_train.classes) 580 | test_num_classes = len(dst_test.classes) 581 | 582 | elif dataset == 'MiniImagenetFSL': 583 | channel = 3 584 | im_size = (84, 84) 585 | num_classes = 64 586 | mean = [0.485, 0.456, 0.406] 587 | std = [0.229, 0.224, 0.225] 588 | if zca: 589 | print('Using ZCA') 590 | transform = None 591 | dst_train = MiniimagenetDataset(setname='train', transform=transform) 592 | dst_test = MiniimagenetDataset(setname='validation', transform=transform) 593 | dst_train.data, dst_test.data = preprocess(dst_train.data, dst_test.data, regularization=0.1) 594 | else: 595 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 596 | if manual_size is not None and manual_size > 0: 597 | im_size = (manual_size, manual_size) 598 | transform_seq.append(transforms.Resize(manual_size)) 599 | transform = transforms.Compose(transform_seq) 600 | dst_train = MiniimagenetDataset(setname='train', transform=transform) 601 | dst_test = MiniimagenetDataset(setname='validation', transform=transform) 602 | class_names = dst_train.classes 603 | train_num_classes = len(dst_train.classes) 604 | test_num_classes = len(dst_test.classes) 605 | 606 | elif dataset == 'TinyImagenet': 607 | channel = 3 608 | im_size = (64, 64) 609 | num_classes = 200 610 | mean = [0.485, 0.456, 0.406] 611 | std = [0.229, 0.224, 0.225] 612 | if zca: 613 | raise NotImplementedError 614 | else: 615 | transform_seq = [transforms.ToTensor(), transforms.Normalize(mean=mean, std=std)] 616 | if manual_size is not None and manual_size > 0: 617 | im_size = (manual_size, manual_size) 618 | transform_seq.append(transforms.Resize(manual_size)) 619 | transform = transforms.Compose(transform_seq) 620 | dst_train = datasets.ImageFolder('data/tiny-imagenet-200/train', transform=transform) 621 | if False and use_val: 622 | dst_test = datasets.ImageFolder('data/tiny-imagenet-200/val', transform=transform) 623 | else: 624 | dst_test = datasets.ImageFolder('data/tiny-imagenet-200/test', transform=transform) 625 | class_names = dst_train.classes 626 | train_num_classes = len(dst_train.classes) 627 | test_num_classes = len(dst_test.classes) 628 | 629 | elif dataset == 'TinyImagenetDM': 630 | channel = 3 631 | im_size = (64, 64) 632 | num_classes = 200 633 | mean = [0.485, 0.456, 0.406] 634 | std = [0.229, 0.224, 0.225] 635 | data = torch.load(os.path.join(data_path, 'tinyimagenet.pt'), map_location='cpu') 636 | 637 | class_names = data['classes'] 638 | 639 | images_train = data['images_train'] 640 | labels_train = data['labels_train'] 641 | images_train = images_train.detach().float() / 255.0 642 | labels_train = labels_train.detach() 643 | for c in range(channel): 644 | images_train[:,c] = (images_train[:,c] - mean[c])/std[c] 645 | dst_train = TensorDataset(images_train, labels_train) # no augmentation 646 | 647 | images_val = data['images_val'] 648 | labels_val = data['labels_val'] 649 | images_val = images_val.detach().float() / 255.0 650 | labels_val = labels_val.detach() 651 | 652 | for c in range(channel): 653 | images_val[:, c] = (images_val[:, c] - mean[c]) / std[c] 654 | 655 | dst_test = TensorDataset(images_val, labels_val) # no augmentation 656 | train_num_classes = num_classes 657 | test_num_classes = num_classes 658 | 659 | else: 660 | exit('unknown dataset: %s'%dataset) 661 | 662 | if validation_ratio > 0: 663 | dst_train, dst_test = split_validation(dst_train, dst_test, validation_ratio, dataset) 664 | 665 | if test_on_train: 666 | dst_test = copy.deepcopy(dst_train) 667 | 668 | return channel, im_size, train_num_classes, test_num_classes, dst_train, dst_test 669 | 670 | 671 | class TensorDataset(Dataset): 672 | def __init__(self, images, labels): # images: n x c x h x w tensor 673 | self.images = images.detach().float() 674 | self.labels = labels.detach() 675 | 676 | def __getitem__(self, index): 677 | return self.images[index], self.labels[index] 678 | 679 | def __len__(self): 680 | return self.images.shape[0] 681 | 682 | 683 | def preprocess(train, test, zca_bias=0, regularization=0, permute=True): 684 | origTrainShape = train.shape 685 | origTestShape = test.shape 686 | 687 | train = np.ascontiguousarray(train, dtype=np.float32).reshape(train.shape[0], -1).astype('float64') 688 | test = np.ascontiguousarray(test, dtype=np.float32).reshape(test.shape[0], -1).astype('float64') 689 | 690 | nTrain = train.shape[0] 691 | 692 | # Zero mean every feature 693 | train = train - np.mean(train, axis=1)[:,np.newaxis] 694 | test = test - np.mean(test, axis=1)[:,np.newaxis] 695 | 696 | # Normalize 697 | train_norms = np.linalg.norm(train, axis=1) 698 | test_norms = np.linalg.norm(test, axis=1) 699 | 700 | # Make features unit norm 701 | train = train/train_norms[:,np.newaxis] 702 | test = test/test_norms[:,np.newaxis] 703 | 704 | trainCovMat = 1.0/nTrain * train.T.dot(train) 705 | 706 | (E,V) = np.linalg.eig(trainCovMat) 707 | 708 | E += zca_bias 709 | sqrt_zca_eigs = np.sqrt(E + regularization * np.sum(E) / E.shape[0]) 710 | inv_sqrt_zca_eigs = np.diag(np.power(sqrt_zca_eigs, -1)) 711 | global_ZCA = V.dot(inv_sqrt_zca_eigs).dot(V.T) 712 | 713 | train = (train).dot(global_ZCA) 714 | test = (test).dot(global_ZCA) 715 | 716 | train_tensor = torch.Tensor(train.reshape(origTrainShape).astype('float64')) 717 | test_tensor = torch.Tensor(test.reshape(origTestShape).astype('float64')) 718 | if permute: 719 | train_tensor = train_tensor.permute(0,3,1,2).contiguous() 720 | test_tensor = test_tensor.permute(0,3,1,2).contiguous() 721 | 722 | return train_tensor, test_tensor 723 | 724 | 725 | if __name__ == '__main__': 726 | results = get_dataset('CIFAR10', 'data', zca=True) 727 | -------------------------------------------------------------------------------- /experiment_code/agreement_analysis/.ipynb_checkpoints/compare_models-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 5 6 | } 7 | -------------------------------------------------------------------------------- /experiment_code/agreement_analysis/description.txt: -------------------------------------------------------------------------------- 1 | Analysis code for Section 4.1 of the paper. -------------------------------------------------------------------------------- /experiment_code/agreement_analysis/generate_models.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append(".") 3 | import torch 4 | from random import shuffle 5 | import torch 6 | from tqdm import tqdm 7 | from data_utils import get_dataset 8 | from model_utils import get_network 9 | import numpy as np 10 | import os 11 | 12 | 13 | if __name__ == '__main__': 14 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 15 | if not os.path.exists("./experiment_results/agreement_models/"): 16 | os.mkdir("./experiment_results/agreement_models/") 17 | for model_id in tqdm(range(520)): 18 | channel, im_size, train_n_classes, test_n_classes, dst_train, dst_test = get_dataset( 19 | "CIFAR10", 20 | "../data", 21 | zca=False 22 | ) 23 | assert train_n_classes == test_n_classes 24 | label_indices = [[] for _ in range(train_n_classes)] 25 | for i, (x,y) in enumerate(dst_train): 26 | label_indices[y].append(i) 27 | for list in label_indices: 28 | shuffle(list) 29 | indices = [] 30 | subset = np.random.uniform(0.005, 0.05) # random sample between 0.5% to 5% of training data 31 | for list in label_indices: 32 | indices += list[:int(len(list)*subset)] 33 | dst_train = torch.utils.data.Subset(dst_train, indices) 34 | train_loader = torch.utils.data.DataLoader(dst_train, batch_size=256, shuffle=True, num_workers=8) 35 | test_loader = torch.utils.data.DataLoader(dst_test, batch_size=256, shuffle=False, num_workers=8) 36 | train_model = get_network("ConvNet", channel, train_n_classes, im_size).to(device) 37 | optim = torch.optim.SGD(train_model.parameters(), lr=0.01, momentum=0.9) 38 | criterion = torch.nn.CrossEntropyLoss() 39 | train_model.train() 40 | for _ in range(100): 41 | for x,y in train_loader: 42 | x = x.to(device) 43 | y = y.to(device) 44 | pred = train_model(x)[-1] 45 | loss = criterion(pred, y) 46 | optim.zero_grad() 47 | loss.backward() 48 | optim.step() 49 | predictions = [] 50 | num_correct = 0 51 | num_total = 0 52 | train_model.eval() 53 | for x,y in test_loader: 54 | x = x.to(device) 55 | y = y.to(device) 56 | pred = torch.argmax(train_model(x)[-1], dim=1) 57 | predictions += pred.tolist() 58 | num_correct += torch.sum(pred == y).item() 59 | num_total += len(y) 60 | torch.save({"predictions": predictions, "accuracy": num_correct/num_total}, f"./experiment_results/agreement_models/subset_{model_id}.pt") 61 | 62 | channel, im_size, train_n_classes, test_n_classes, dst_train, dst_test = get_dataset( 63 | "CIFAR10", 64 | "../data", 65 | zca=False 66 | ) 67 | assert train_n_classes == test_n_classes 68 | train_loader = torch.utils.data.DataLoader(dst_train, batch_size=256, shuffle=True, num_workers=8) 69 | test_loader = torch.utils.data.DataLoader(dst_test, batch_size=256, shuffle=False, num_workers=8) 70 | for model_id in tqdm(range(30)): 71 | train_model = get_network("ConvNet", channel, train_n_classes, im_size).to(device) 72 | optim = torch.optim.SGD(train_model.parameters(), lr=0.01, momentum=0.9) 73 | criterion = torch.nn.CrossEntropyLoss() 74 | all_the_predictions = [] # predictions across every iteration 75 | for x,y in train_loader: 76 | train_model.train() 77 | x = x.to(device) 78 | y = y.to(device) 79 | pred = train_model(x)[-1] 80 | loss = criterion(pred, y) 81 | optim.zero_grad() 82 | loss.backward() 83 | optim.step() 84 | 85 | predictions_at_iter = [] # predictions from this iteration 86 | train_model.eval() 87 | for x,y in test_loader: 88 | x = x.to(device) 89 | y = y.to(device) 90 | pred = torch.argmax(train_model(x)[-1], dim=1) 91 | predictions_at_iter += pred.tolist() 92 | num_correct += torch.sum(pred == y).item() 93 | num_total += len(y) 94 | all_the_predictions.append(predictions_at_iter) 95 | torch.save({"predictions": all_the_predictions}, f"./experiment_results/agreement_models/earlystopping_{model_id}.pt") 96 | 97 | -------------------------------------------------------------------------------- /experiment_code/early_training_analysis/description.txt: -------------------------------------------------------------------------------- 1 | Analysis code for Section 4.2 and 4.3 of the paper -------------------------------------------------------------------------------- /experiment_code/early_training_analysis/recognition.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "0aedc4a8-e942-46a6-a820-fe3314841071", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import sys\n", 11 | "sys.path.append(\"../..\")\n", 12 | "import torch\n", 13 | "import numpy as np\n", 14 | "import matplotlib.pyplot as plt\n", 15 | "from data_utils import *\n", 16 | "from model_utils import get_network\n", 17 | "from tqdm import tqdm\n", 18 | "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "id": "861d3847-257a-463e-b3e3-178aa5f9395c", 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "Files already downloaded and verified\n", 32 | "Files already downloaded and verified\n" 33 | ] 34 | } 35 | ], 36 | "source": [ 37 | "# create dataloaders\n", 38 | "channel, im_size, train_n_classes, test_n_classes, dst_train, dst_test = get_dataset(\n", 39 | " \"CIFAR10\",\n", 40 | " \"../../data\",\n", 41 | " zca=False\n", 42 | " )\n", 43 | "assert train_n_classes == test_n_classes\n", 44 | "train_loader = torch.utils.data.DataLoader(dst_train, batch_size=256, shuffle=True, num_workers=8)\n", 45 | "test_loader = torch.utils.data.DataLoader(dst_test, batch_size=256, shuffle=False, num_workers=8)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 3, 51 | "id": "1356669b-c914-4aa7-bf55-6572f601a06a", 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "name": "stderr", 56 | "output_type": "stream", 57 | "text": [ 58 | "100%|██████████████████████████████████████████████████████████████████████████████████████████| 40/40 [00:00<00:00, 42.18it/s]\n" 59 | ] 60 | }, 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "torch.Size([10000, 3, 32, 32])\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# store test data for faster inference (run on RTX 3090 with 24GB of VRAM)\n", 71 | "test_label = []\n", 72 | "test_img = []\n", 73 | "with torch.no_grad():\n", 74 | " for x, y in tqdm(test_loader):\n", 75 | " test_label.append(y)\n", 76 | " test_img.append(x)\n", 77 | "test_label = torch.hstack(test_label).to(device)\n", 78 | "test_img = torch.vstack(test_img).to(device)\n", 79 | "print(test_img.shape)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 4, 85 | "id": "49e643a0-8455-4007-bcc7-7bf40939d8ad", 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "data = torch.load(f\"../../DD_data/0.pt\")\n", 90 | "synthetic_data = data[\"data\"].cuda()\n", 91 | "synthetic_label = data[\"label\"].cuda()\n", 92 | "data = torch.load(f\"../../DD_data/1.pt\")\n", 93 | "synthetic_data2 = data[\"data\"].cuda()\n", 94 | "synthetic_label2 = data[\"label\"].cuda()\n", 95 | "data = torch.load(f\"../../DD_data/2.pt\")\n", 96 | "synthetic_data3 = data[\"data\"].cuda()\n", 97 | "synthetic_label3 = data[\"label\"].cuda()\n", 98 | "data = torch.load(f\"../../DD_data/3.pt\")\n", 99 | "synthetic_data4 = data[\"data\"].cuda()\n", 100 | "synthetic_label4 = data[\"label\"].cuda()" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "id": "f4d168e2-20be-4c4b-89de-ddd54418ac7a", 107 | "metadata": {}, 108 | "outputs": [ 109 | { 110 | "name": "stderr", 111 | "output_type": "stream", 112 | "text": [ 113 | "196it [00:24, 7.87it/s]\n", 114 | "196it [00:24, 7.98it/s]\n" 115 | ] 116 | } 117 | ], 118 | "source": [ 119 | "train_model = get_network(\"ConvNet\", 3, 10, (32,32)).cuda()\n", 120 | "optim = torch.optim.SGD(train_model.parameters(), lr=0.01, momentum=0.9)\n", 121 | "criterion = torch.nn.CrossEntropyLoss()\n", 122 | "\n", 123 | "syn_acc1 = []\n", 124 | "syn_acc2 = []\n", 125 | "syn_acc3 = []\n", 126 | "syn_acc4 = []\n", 127 | "syn_loss1 = []\n", 128 | "syn_loss2 = []\n", 129 | "syn_loss3 = []\n", 130 | "syn_loss4 = []\n", 131 | "test_acc = []\n", 132 | "for _ in range(2):\n", 133 | " for i, (x,y) in tqdm(enumerate(train_loader)):\n", 134 | " train_model.train()\n", 135 | " x = x.cuda()\n", 136 | " y = y.cuda()\n", 137 | " loss = criterion(train_model(x)[-1], y)\n", 138 | " optim.zero_grad()\n", 139 | " loss.backward()\n", 140 | " optim.step()\n", 141 | " with torch.no_grad():\n", 142 | " test_acc.append(torch.sum(torch.argmax(train_model(test_img)[-1], dim=1) == test_label).item()/len(test_label))\n", 143 | " syn_acc1.append(torch.sum(torch.argmax(train_model(synthetic_data)[-1], dim=1) == synthetic_label).item()/len(synthetic_label))\n", 144 | " syn_acc2.append(torch.sum(torch.argmax(train_model(synthetic_data2)[-1], dim=1) == synthetic_label2).item()/len(synthetic_label2))\n", 145 | " syn_acc3.append(torch.sum(torch.argmax(train_model(synthetic_data3)[-1], dim=1) == synthetic_label3).item()/len(synthetic_label3))\n", 146 | " syn_acc4.append(torch.sum(torch.argmax(train_model(synthetic_data4)[-1], dim=1) == synthetic_label4).item()/len(synthetic_label4))\n", 147 | " syn_loss1.append(criterion(train_model(synthetic_data)[-1], synthetic_label).item())\n", 148 | " syn_loss2.append(criterion(train_model(synthetic_data2)[-1], synthetic_label2).item())\n", 149 | " syn_loss3.append(criterion(train_model(synthetic_data3)[-1], synthetic_label3).item())\n", 150 | " syn_loss4.append(criterion(train_model(synthetic_data4)[-1], synthetic_label4).item())" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 6, 156 | "id": "5271ca8b-2fe0-47d7-b97d-d6ca19d3264d", 157 | "metadata": {}, 158 | "outputs": [ 159 | { 160 | "data": { 161 | "text/plain": [ 162 | "Text(0, 0.5, 'Accuracy')" 163 | ] 164 | }, 165 | "execution_count": 6, 166 | "metadata": {}, 167 | "output_type": "execute_result" 168 | }, 169 | { 170 | "data": { 171 | "image/png": "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3FzF9zhhwgSGDx8OwNSpU5kwYQIOh4Px48ezfft2Hn30UZ/2Vioq/yZatWpFv3792Lx5s7Js5syZdOrUiejoaC644AIKCtxxAy4XF198MfHx8URHRzN+/HifwhtNZdu2bQwYMICoqCh69erF+vXrlfPcc889xMbGEh4eTs+ePSkqKuKmm24iMzOTwYMHExoaynfffdfg8T/99FOGDx/OzTffTFhYGL179yY7O5s777yTiIgI+vTpQ05OTqPubfbs2bRq1Yro6GieffZZH822traWu+66i+TkZFJTU3nllVeU/ebOnUu7du0ICwujWbNmfPPNN8f8vE4HmiwoO3fuHPSL+vbbb+nYseNxuaj/GrVOSVCatZLQQ2cFwQXhBRBeRKxDr2x7pmE3v99yFg90KAVAa/Q1vWpM8Xz00Uc+x7/++uv56KOPmDp1Ki6Xi759+9KiRQtuu+02AL788ksOHz5Mq1at+Oijj+jUqRMvvfQSkZGRJ/K2Vf7liKJIdXX1Cf93LPma+/btY+XKlaSnpwOwdu1aJk6cyHfffUd+fj7t27fn9ttvV7a/+OKLycjIICMjg8rKSiZPnnxMz6SyspKRI0dy//33U1RUxJNPPslFF11EXV0dv//+O3/99RcHDx6ktLSU6dOnYzKZmD59Os2bN1e04csuC94qz5s//viD888/n5KSElJTU+nXrx8DBw6kuLiYli1b+nR6qu/e8vPzufLKK5k2bRp5eXnU1dWRne1pvPDggw9SXl7O3r17Wbt2LZ9//jm//PILADfddBMzZsygsrKSdevW0a1b/d2G/gk0ORrjySef5JJLLuHAgQMMHjwYgMWLF/P1118zc+bM436B/wVqHJIPMskcwcGKEtC4GHaWnYWVuwA4oyJa2dZZdYhzY7M5/Ns04BY0esG9XKqzatdE8tVXXwHwyy+/cOutt5KTk8Mtt9yiHOP6668HYPjw4dx44418/PHHREZG8ssvvxAR4duuS0XlWKmpqTnmBO+mUFVVRUhISKO2HTZsmCLAL7roIsUHP2PGDO666y46d+4MwFNPPUVUVBQOhwOdTsdVV3mqXd1///1MmjTpmK71119/pWvXrlx00UUAjB07lueff55Vq1YpVrndu3dzxhln0LNnz2M6B0i5z/I5LrzwQvbt28ell16qnHP69OmA1P2pvnubP38+ffv25bzz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", 172 | "text/plain": [ 173 | "
" 174 | ] 175 | }, 176 | "metadata": {}, 177 | "output_type": "display_data" 178 | } 179 | ], 180 | "source": [ 181 | "plt.figure(figsize=(5,3))\n", 182 | "colours = [\"#000000\", \"#E69F00\", \"#0072B2\", \"#009E73\", \"#CC79A7\"]\n", 183 | "plt.plot(test_acc[:300], label='Real Test Images',c=colours[0])\n", 184 | "plt.plot(syn_acc1[:300], label='BPTT', c=colours[1])\n", 185 | "plt.plot(syn_acc2[:300], label='Distribution Matching', c=colours[2])\n", 186 | "plt.plot(syn_acc3[:300], label='Gradient Matching', c=colours[3])\n", 187 | "plt.plot(syn_acc4[:300], label='Trajectory Matching', c=colours[4])\n", 188 | "plt.legend(fontsize='small')\n", 189 | "plt.xlabel(\"Iteration\")\n", 190 | "plt.ylabel(\"Accuracy\")" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": null, 196 | "id": "f2a6e83a-3827-4dbd-86bc-d875ce7cfc1e", 197 | "metadata": {}, 198 | "outputs": [], 199 | "source": [] 200 | } 201 | ], 202 | "metadata": { 203 | "kernelspec": { 204 | "display_name": "Python 3 (ipykernel)", 205 | "language": "python", 206 | "name": "python3" 207 | }, 208 | "language_info": { 209 | "codemirror_mode": { 210 | "name": "ipython", 211 | "version": 3 212 | }, 213 | "file_extension": ".py", 214 | "mimetype": "text/x-python", 215 | "name": "python", 216 | "nbconvert_exporter": "python", 217 | "pygments_lexer": "ipython3", 218 | "version": "3.10.12" 219 | } 220 | }, 221 | "nbformat": 4, 222 | "nbformat_minor": 5 223 | } 224 | -------------------------------------------------------------------------------- /experiment_code/influence_analysis/description.txt: -------------------------------------------------------------------------------- 1 | Analysis code for Section 5.2 of the paper -------------------------------------------------------------------------------- /experiment_code/replacement_analysis/.ipynb_checkpoints/training_sensitivity-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "9df7e4d7-d4d9-4c86-9c53-549b01dee1f1", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import sys\n", 11 | "sys.path.append(\"../..\")\n", 12 | "import torch\n", 13 | "import numpy as np\n", 14 | "import matplotlib.pyplot as plt\n", 15 | "from data_utils import *\n", 16 | "from model_utils import get_network\n", 17 | "from tqdm import tqdm\n", 18 | "from torchvision import transforms as T\n", 19 | "from matplotlib import cm\n", 20 | "import torchvision\n", 21 | "from random import shuffle, choice, seed\n", 22 | "import seaborn as sns\n", 23 | "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "id": "a76d3633-0e5c-4074-b36d-af4e31ae093e", 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "name": "stdout", 34 | "output_type": "stream", 35 | "text": [ 36 | "Files already downloaded and verified\n", 37 | "Files already downloaded and verified\n" 38 | ] 39 | } 40 | ], 41 | "source": [ 42 | "channel, im_size, train_n_classes, test_n_classes, dst_train, dst_test = get_dataset(\n", 43 | " \"CIFAR10\",\n", 44 | " \"../../data\",\n", 45 | " zca=False\n", 46 | " )\n", 47 | "assert train_n_classes == test_n_classes\n", 48 | "test_loader = torch.utils.data.DataLoader(dst_test, batch_size=256, shuffle=False, num_workers=8)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "id": "baa5dc2c-d716-44e2-afaa-45df92088f2c", 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "name": "stderr", 59 | "output_type": "stream", 60 | "text": [ 61 | "100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 40/40 [00:00<00:00, 46.27it/s]\n" 62 | ] 63 | }, 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "torch.Size([10000, 3, 32, 32])\n", 69 | "torch.Size([10000])\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "test_img = []\n", 75 | "test_label = []\n", 76 | "with torch.no_grad():\n", 77 | " for x, y in tqdm(test_loader):\n", 78 | " test_img.append(x)\n", 79 | " test_label.append(y)\n", 80 | "test_img = torch.vstack(test_img).to(device)\n", 81 | "test_label = torch.hstack(test_label).to(device)\n", 82 | "print(test_img.shape)\n", 83 | "print(test_label.shape)" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "id": "7361c67d-9792-4089-a2e6-e9b88c41b393", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stderr", 94 | "output_type": "stream", 95 | "text": [ 96 | " 0%| | 0/5 [00:00