def main(): args = parseargs() resdir = 'results/%s-%s-%s' % (args.model, args.dataset, args.seg) if args.layer is not None: resdir += '-' + args.layer if args.quantile != 0.005: resdir += ('-%g' % (args.quantile * 1000)) if args.thumbsize != 100: resdir += ('-t%d' % (args.thumbsize)) resfile = pidfile.exclusive_dirfn(resdir) model = load_model(args) layername = instrumented_layername(args) model.retain_layer(layername) dataset = load_dataset(args, model=model.model) upfn = make_upfn(args, dataset, model, layername) sample_size = len(dataset) is_generator = (args.model == 'progan') percent_level = 1.0 - args.quantile iou_threshold = args.miniou image_row_width = 5 torch.set_grad_enabled(False) # Tally rq.np (representation quantile, unconditional). pbar.descnext('rq') def compute_samples(batch, *args): data_batch = batch.cuda() _ = model(data_batch) acts = model.retained_layer(layername) hacts = upfn(acts) return hacts.permute(0, 2, 3, 1).contiguous().view(-1, acts.shape[1]) rq = tally.tally_quantile(compute_samples, dataset, sample_size=sample_size, r=8192, num_workers=100, pin_memory=True, cachefile=resfile('rq.npz')) # Create visualizations - first we need to know the topk pbar.descnext('topk') def compute_image_max(batch, *args): data_batch = batch.cuda() _ = model(data_batch) acts = model.retained_layer(layername) acts = acts.view(acts.shape[0], acts.shape[1], -1) acts = acts.max(2)[0] return acts topk = tally.tally_topk(compute_image_max, dataset, sample_size=sample_size, batch_size=50, num_workers=30, pin_memory=True, cachefile=resfile('topk.npz')) # Visualize top-activating patches of top-activatin images. pbar.descnext('unit_images') image_size, image_source = None, None if is_generator: image_size = model(dataset[0][0].cuda()[None,...]).shape[2:] else: image_source = dataset iv = imgviz.ImageVisualizer((args.thumbsize, args.thumbsize), image_size=image_size, source=dataset, quantiles=rq, level=rq.quantiles(percent_level)) def compute_acts(data_batch, *ignored_class): data_batch = data_batch.cuda() out_batch = model(data_batch) acts_batch = model.retained_layer(layername) if is_generator: return (acts_batch, out_batch) else: return (acts_batch, data_batch) unit_images = iv.masked_images_for_topk( compute_acts, dataset, topk, k=image_row_width, num_workers=30, pin_memory=True, cachefile=resfile('top%dimages.npz' % image_row_width)) pbar.descnext('saving images') imgsave.save_image_set(unit_images, resfile('image/unit%d.jpg'), sourcefile=resfile('top%dimages.npz' % image_row_width)) # Compute IoU agreement between segmentation labels and every unit # Grab the 99th percentile, and tally conditional means at that level. level_at_99 = rq.quantiles(percent_level).cuda()[None,:,None,None] segmodel, seglabels, segcatlabels = setting.load_segmenter(args.seg) renorm = renormalize.renormalizer(dataset, target='zc') def compute_conditional_indicator(batch, *args): data_batch = batch.cuda() out_batch = model(data_batch) image_batch = out_batch if is_generator else renorm(data_batch) seg = segmodel.segment_batch(image_batch, downsample=4) acts = model.retained_layer(layername) hacts = upfn(acts) iacts = (hacts > level_at_99).float() # indicator return tally.conditional_samples(iacts, seg) pbar.descnext('condi99') condi99 = tally.tally_conditional_mean(compute_conditional_indicator, dataset, sample_size=sample_size, num_workers=3, pin_memory=True, cachefile=resfile('condi99.npz')) # Now summarize the iou stats and graph the units iou_99 = tally.iou_from_conditional_indicator_mean(condi99) unit_label_99 = [ (concept.item(), seglabels[concept], segcatlabels[concept], bestiou.item()) for (bestiou, concept) in zip(*iou_99.max(0))] labelcat_list = [labelcat for concept, label, labelcat, iou in unit_label_99 if iou > iou_threshold] save_conceptcat_graph(resfile('concepts_99.svg'), labelcat_list) dump_json_file(resfile('report.json'), dict( header=dict( name='%s %s %s' % (args.model, args.dataset, args.seg), image='concepts_99.svg'), units=[ dict(image='image/unit%d.jpg' % u, unit=u, iou=iou, label=label, cat=labelcat[1]) for u, (concept, label, labelcat, iou) in enumerate(unit_label_99)]) ) copy_static_file('report.html', resfile('+report.html')) resfile.done();
upfn = upsample.upsampler( (56, 56), # The target output shape (7, 7), source=dataset, ) renorm = renormalize.renormalizer(dataset, mode='zc') def compute_samples(batch, *args): image_batch = batch.cuda() _ = model(image_batch) acts = model.retained_layer(layername) hacts = upfn(acts) return hacts.permute(0, 2, 3, 1).contiguous().view(-1, acts.shape[1]) pbar.descnext('rq') rq = tally.tally_quantile(compute_samples, dataset, sample_size=sample_size, r=8192, cachefile=resfile('rq.npz')) if False: def compute_conditional_samples(batch, *args): image_batch = batch.cuda() _ = model(image_batch) acts = model.retained_layer(layername) seg = segmodel.segment_batch(renorm(image_batch), downsample=4) hacts = upfn(acts) return tally.conditional_samples(hacts, seg) pbar.descnext('condq') condq = tally.tally_conditional_quantile(compute_conditional_samples, dataset, sample_size=sample_size, cachefile=resfile('condq.npz'))
def main(): CHOSEN_UNITS_DIR = os.path.join("/", "home", "dwijaya", "dissect", "experiment", "ucf101", "datas", "chosen_units.csv") report_dir = os.path.join( "/", "home", "dwijaya", "dissect", "experiment", "results/vgg16-ucf101-netpqc-conv5_3-10/report.json") result_test = load_json(report_dir)['units'] # getUnitLabel(result_test) # groupUnitByLabel(result_test) chosen_units_df = pd.read_csv(CHOSEN_UNITS_DIR) args = parseargs() model = setting.load_ucf101_classifier(args.model) model = nethook.InstrumentedModel(model).cuda().eval() layername = args.layer model.retain_layer(layername) dataset = setting.load_ucf101_dataset(crop_size=224, in_dataloader=False, is_all_frames=True) train_dataset = setting.load_ucf101_dataset(crop_size=224, in_dataloader=False, is_all_frames=True, is_train=True) num_units = len(chosen_units_df) classlabels = dataset.classes def zeroingTopK(k=14): directory = os.path.join(os.getcwd(), 'results/shared', 'pra-vgg16-ucf101/per_class') save_dir = os.path.join(directory, 'topK_target.csv') if (os.path.exists(save_dir)): df = pd.read_csv(save_dir) print(df) else: # topK_all_class = [] # for idx, cl in enumerate(classlabels): # cachefile = sharedfile('pra-%s-%s/%s/%s.npz' % (args.model, args.dataset, args.experiments, cl)) # df = pd.read_csv(save_dir) # df2 = pd.read_csv(os.path.join(directory, '%s.csv' % cl)) # to_save = [] # for idx, (unit, concept) in enumerate(zip(df2['Unit'].loc[14:], df2['Concept'].loc[14:])): # to_save.append((unit, concept)) # topK_all_class.append(to_save) # df = df.rename(columns={'Unnamed: 0': 'Class', '0': 'Acc_dropped'}) # df['Unit/Concept'] = topK_all_class # df['Class'] = classlabels # df.to_csv(save_dir) topK_all_class = [] acc_per_class_list, target_acc_class = [], [] for idx, cl in enumerate(classlabels): cachefile = sharedfile( 'pra-%s-%s/%s/%s.npz' % (args.model, args.dataset, args.experiments, cl)) df = pd.read_csv(os.path.join(directory, '%s.csv' % cl)) units_to_remove = df['Unit'].loc[:k - 1].to_list() accuracy, acc_per_class = my_test_perclass( model, dataset, layername=layername, ablated_units=units_to_remove, cachefile=cachefile) target_acc_class.append(acc_per_class[idx]) acc_per_class_list.append(acc_per_class) to_save = [] for idx, (unit, concept) in enumerate( zip(df['Unit'].loc[:k - 1], df['Concept'].loc[:k - 1])): to_save.append((unit, concept)) topK_all_class.append(to_save) result_df = pd.DataFrame(target_acc_class, columns=['Acc_dropped']) # result_df = result_df.rename(columns={'Unnamed: 0': 'Class', '0': 'Acc_dropped'}) result_df['Unit/Concept'] = topK_all_class result_df['Class'] = classlabels result_df.to_csv(os.path.join(directory, "topK_target.csv")) pd.DataFrame(acc_per_class_list).to_csv( os.path.join('topK_per_class.csv')) def zeroingBottomK(k=498): #previously is 498, so it is wrong. directory = os.path.join(os.getcwd(), 'results/shared', 'pra-vgg16-ucf101/per_class') topK_all_class = [] acc_per_class_list, target_acc_class = [], [] for idx, cl in enumerate(classlabels): cachefile = sharedfile( 'pra-%s-%s/%s/%s.npz' % (args.model, args.dataset, args.experiments, cl)) df = pd.read_csv(os.path.join(directory, '%s.csv' % cl)) units_to_remove = df['Unit'].loc[k:].to_list() accuracy, acc_per_class = my_test_perclass( model, dataset, layername=layername, ablated_units=units_to_remove, cachefile=cachefile) target_acc_class.append(acc_per_class[idx]) acc_per_class_list.append(acc_per_class) to_save = [] for idx, (unit, concept) in enumerate( zip(df['Unit'].loc[k:], df['Concept'].loc[k:])): to_save.append((unit, concept)) topK_all_class.append(to_save) result_df = pd.DataFrame(target_acc_class, columns=['Acc_dropped']) result_df['Unit/Concept'] = topK_all_class result_df['Class'] = classlabels result_df.to_csv(os.path.join(directory, "bottomK_target_new.csv")) # pd.DataFrame(target_acc_class).to_csv(os.path.join(directory, "bottomK_target_new.csv")) pd.DataFrame(acc_per_class_list).to_csv( os.path.join(directory, 'bottomK_per_class_new.csv')) def zeroKWithConcepts(): directory = os.path.join(os.getcwd(), 'results/shared', 'pra-vgg16-ucf101/per_class') save_dir = os.path.join(directory, 'bottomK_target.csv') topK_all_class = [] for idx, cl in enumerate(classlabels): cachefile = sharedfile( 'pra-%s-%s/%s/%s.npz' % (args.model, args.dataset, args.experiments, cl)) df = pd.read_csv(save_dir) df2 = pd.read_csv(os.path.join(directory, '%s.csv' % cl)) to_save = [] for idx, (unit, concept) in enumerate( zip(df2['Unit'].loc[14:], df2['Concept'].loc[14:])): to_save.append((unit, concept)) topK_all_class.append(to_save) df = df.rename(columns={'Unnamed: 0': 'Class', '0': 'Acc_dropped'}) df['Unit/Concept'] = topK_all_class df['Class'] = classlabels df.to_csv(save_dir) print("HELLO") # df = df.rename(columns={"Unnamed: 0": "Concept"}) # df.to_csv(os.path.join(directory, '%s.csv' % cl)) # coba() # sortAcc() #Getting the baseline accuracy. baseline_acc_dir = os.path.join( os.getcwd(), 'results/shared', 'pra-%s-%s/baseline_acc.npz' % (args.model, args.dataset)) if (os.path.exists(baseline_acc_dir)): baseline_ = np.load(baseline_acc_dir) baseline_acc, baseline_acc_per_class = baseline_['acc'], baseline_[ 'acc_per_class'] else: pbar.descnext('baseline_pra') baseline_acc, baseline_acc_per_class = my_test_perclass( model, dataset, ablated_units=None, cachefile=sharedfile('pra-%s-%s/%s_acc.npz' % (args.model, args.dataset, args.experiments))) cachefile = sharedfile('pra-%s-%s/%s_acc.npz' % (args.model, args.dataset, args.experiments)) np.savez(cachefile, acc=baseline_acc, acc_per_class=baseline_acc_per_class) baseline_acc_per_class = np.expand_dims(baseline_acc_per_class, axis=0) pd.DataFrame(baseline_acc_per_class, index=['Baseline'], columns=classlabels).to_csv("base_line.csv") #Now erase each unit, one at a time, and retest accuracy. cached_results_dir = os.path.join( os.getcwd(), 'results/shared', 'pra-%s-%s/%s_acc.npz' % (args.model, args.dataset, args.experiments)) cachefile = sharedfile('pra-%s-%s/%s_acc.npz' % (args.model, args.dataset, args.experiments)) all_units = [] if (args.experiments == "topK"): zeroingTopK() elif (args.experiments == "bottomK"): zeroingBottomK() if (args.extract_data): baseline_ = { 'acc': baseline_acc, 'acc_per_class': baseline_acc_per_class } # npzToCSV(args.experiments, columns=classlabels, baseline_=baseline_, export_csv=False) # sortUnitByClass(baseline_, args.experiments, classlabels) else: if (args.experiments == 'exp1'): df = pd.read_csv(os.path.join(datas_dir, 'Sensible units.csv')) if (os.path.exists(cached_results_dir)): # IF THE RESULT ALREADY EXISTS acc_per_class_list = np.load( cached_results_dir)['acc_per_class'] acc_list = np.load(cached_results_dir)['acc'] else: #Remove unit one at a time. units_to_remove, concepts = df['Unit'], df['Concepts'] for idx, (units, concept) in enumerate(zip(units_to_remove, concepts)): units = units.split(',') units = [(int(u), concept) for u in units] all_units.extend(units) acc_per_class_list = np.zeros( [len(all_units), len(classlabels)]) acc_list = np.zeros(len(classlabels)) for idx, (unit, c) in enumerate(all_units): accuracy, acc_per_class = my_test_perclass( model, dataset, layername=layername, ablated_units=[unit], cachefile=cachefile) acc_list[idx] = accuracy acc_per_class_list[idx] = acc_per_class np.savez(cachefile, acc=acc_list, acc_per_class=acc_per_class_list) elif (args.experiments == 'exp2'): df = pd.read_csv(os.path.join(datas_dir, 'Sensible units.csv')) if (os.path.exists(cached_results_dir)): #IF THE RESULT ALREADY EXISTS acc_per_class_list = np.load( cached_results_dir)['acc_per_class'] acc_list = np.load(cached_results_dir)['acc'] else: #Remove multiple units at a time units_to_remove, concepts = df['Unit'], df['Concepts'] acc_per_class_list = np.zeros([num_units, len(classlabels)]) acc_list = np.zeros(len(classlabels)) for idx, (units, concept) in enumerate(zip(units_to_remove, concepts)): units = units.split(',') units = [int(u) for u in units] accuracy, acc_per_class = my_test_perclass( model, dataset, layername=layername, ablated_units=units, cachefile=cachefile) acc_list[idx] = accuracy acc_per_class_list[idx] = acc_per_class # in a list np.savez(cachefile, acc=acc_list, acc_per_class=acc_per_class_list) elif (args.experiments == 'exp3'): df = pd.read_csv(os.path.join(datas_dir, 'units_label.csv')) if (os.path.exists(cached_results_dir)): acc_per_class_list = np.load( cached_results_dir)['acc_per_class'] acc_list = np.load(cached_results_dir)['acc'] else: # Remove multiple units at a time concepts = df['Concepts'] # acc_per_class_list = np.zeros([len(concepts), len(classlabels)]) # acc_list = np.zeros(len(concepts)) # acc_per_class = np.zeros(len(classlabels)) # acc_per_class = np.zeros(len(classlabels)) process_complete = tqdm.tqdm(total=len(concepts), desc='Units Complete', position=0) for idx, (concept) in enumerate(concepts): cachefile = sharedfile( 'pra-%s-%s/%s/%s.npz' % (args.model, args.dataset, args.experiments, "unit" + str(idx))) if (not os.path.exists(cachefile)): unit = idx # units = [int(u) for u in units] accuracy, acc_per_class = my_test_perclass( model, dataset, layername=layername, ablated_units=[unit], cachefile=cachefile) # acc_list[idx] = accuracy # acc_per_class_list[idx] = acc_per_class # in a list np.savez(cachefile, acc=accuracy, acc_per_class=acc_per_class, concept=concept) else: print("Unit %s is done" % (str(idx))) process_complete.update(1) elif (args.experiments == 'exp4'): with open(os.path.join(datas_dir, 'units_by_labels.json'), 'r') as file: df = json.load(file) acc_per_class_list = np.zeros([len(df), len(classlabels)]) acc_list = np.zeros(len(df)) process_complete = tqdm.tqdm(total=len(df), desc='Concepts Complete', position=0) for idx, (concept, units) in enumerate(df.items()): cachefile = sharedfile( 'pra-%s-%s/%s/%s.npz' % (args.model, args.dataset, args.experiments, concept)) if (not os.path.exists(cachefile)): #i.e (concept, units) = ('arm', [42,260,462,464]) accuracy, acc_per_class = my_test_perclass( model, dataset, layername=layername, ablated_units=units, cachefile=cachefile) acc_list[idx] = accuracy acc_per_class_list[idx] = acc_per_class np.savez(cachefile, acc=acc_list, acc_per_class=acc_per_class_list) else: print("Concept : %s is done" % (concept)) process_complete.update(1)
def main(): args = parseargs() resdir = 'results/%s-%s-%s-%s-%s' % (args.model, args.dataset, args.seg, args.layer, int(args.quantile * 1000)) def resfile(f): return os.path.join(resdir, f) model = load_model(args) layername = instrumented_layername(args) model.retain_layer(layername) dataset = load_dataset(args, model=model.model) upfn = make_upfn(args, dataset, model, layername) sample_size = len(dataset) is_generator = (args.model == 'progan') percent_level = 1.0 - args.quantile # Tally rq.np (representation quantile, unconditional). torch.set_grad_enabled(False) pbar.descnext('rq') def compute_samples(batch, *args): data_batch = batch.cuda() _ = model(data_batch) acts = model.retained_layer(layername) hacts = upfn(acts) return hacts.permute(0, 2, 3, 1).contiguous().view(-1, acts.shape[1]) rq = tally.tally_quantile(compute_samples, dataset, sample_size=sample_size, r=8192, num_workers=100, pin_memory=True, cachefile=resfile('rq.npz')) # Grab the 99th percentile, and tally conditional means at that level. level_at_99 = rq.quantiles(percent_level).cuda()[None, :, None, None] segmodel, seglabels, segcatlabels = setting.load_segmenter(args.seg) renorm = renormalize.renormalizer(dataset, target='zc') def compute_conditional_indicator(batch, *args): data_batch = batch.cuda() out_batch = model(data_batch) image_batch = out_batch if is_generator else renorm(data_batch) seg = segmodel.segment_batch(image_batch, downsample=4) acts = model.retained_layer(layername) hacts = upfn(acts) iacts = (hacts > level_at_99).float() # indicator return tally.conditional_samples(iacts, seg) pbar.descnext('condi99') condi99 = tally.tally_conditional_mean(compute_conditional_indicator, dataset, sample_size=sample_size, num_workers=3, pin_memory=True, cachefile=resfile('condi99.npz')) # Now summarize the iou stats and graph the units iou_99 = tally.iou_from_conditional_indicator_mean(condi99) unit_label_99 = [(concept.item(), seglabels[concept], segcatlabels[concept], bestiou.item()) for (bestiou, concept) in zip(*iou_99.max(0))] def measure_segclasses_with_zeroed_units(zeroed_units, sample_size=100): model.remove_edits() def zero_some_units(x, *args): x[:, zeroed_units] = 0 return x model.edit_layer(layername, rule=zero_some_units) num_seglabels = len(segmodel.get_label_and_category_names()[0]) def compute_mean_seg_in_images(batch_z, *args): img = model(batch_z.cuda()) seg = segmodel.segment_batch(img, downsample=4) seg_area = seg.shape[2] * seg.shape[3] seg_counts = torch.bincount( (seg + (num_seglabels * torch.arange( seg.shape[0], dtype=seg.dtype, device=seg.device)[:, None, None, None])).view(-1), minlength=num_seglabels * seg.shape[0]).view(seg.shape[0], -1) seg_fracs = seg_counts.float() / seg_area return seg_fracs result = tally.tally_mean(compute_mean_seg_in_images, dataset, batch_size=30, sample_size=sample_size, pin_memory=True) model.remove_edits() return result # Intervention experiment here: # segs_baseline = measure_segclasses_with_zeroed_units([]) # segs_without_treeunits = measure_segclasses_with_zeroed_units(tree_units) num_units = len(unit_label_99) baseline_segmean = test_generator_segclass_stats( model, dataset, segmodel, layername=layername, cachefile=resfile('segstats/baseline.npz')).mean() pbar.descnext('unit ablation') unit_ablation_segmean = torch.zeros(num_units, len(baseline_segmean)) for unit in pbar(random.sample(range(num_units), num_units)): stats = test_generator_segclass_stats( model, dataset, segmodel, layername=layername, zeroed_units=[unit], cachefile=resfile('segstats/ablated_unit_%d.npz' % unit)) unit_ablation_segmean[unit] = stats.mean() ablate_segclass_name = 'tree' ablate_segclass = seglabels.index(ablate_segclass_name) best_iou_units = iou_99[ablate_segclass, :].sort(0)[1].flip(0) byiou_unit_ablation_seg = torch.zeros(30) for unitcount in pbar(random.sample(range(0, 30), 30)): zero_units = best_iou_units[:unitcount].tolist() stats = test_generator_segclass_delta_stats( model, dataset, segmodel, layername=layername, zeroed_units=zero_units, cachefile=resfile('deltasegstats/ablated_best_%d_iou_%s.npz' % (unitcount, ablate_segclass_name))) byiou_unit_ablation_seg[unitcount] = stats.mean()[ablate_segclass] # Generator context experiment. num_segclass = len(seglabels) door_segclass = seglabels.index('door') door_units = iou_99[door_segclass].sort(0)[1].flip(0)[:20] door_high_values = rq.quantiles(0.995)[door_units].cuda() def compute_seg_impact(zbatch, *args): zbatch = zbatch.cuda() model.remove_edits() orig_img = model(zbatch) orig_seg = segmodel.segment_batch(orig_img, downsample=4) orig_segcount = tally.batch_bincount(orig_seg, num_segclass) rep = model.retained_layer(layername).clone() ysize = orig_seg.shape[2] // rep.shape[2] xsize = orig_seg.shape[3] // rep.shape[3] def gen_conditions(): for y in range(rep.shape[2]): for x in range(rep.shape[3]): # Take as the context location the segmentation # labels at the center of the square. selsegs = orig_seg[:, :, y * ysize + ysize // 2, x * xsize + xsize // 2] changed_rep = rep.clone() changed_rep[:, door_units, y, x] = (door_high_values[None, :]) model.edit_layer(layername, ablation=1.0, replacement=changed_rep) changed_img = model(zbatch) changed_seg = segmodel.segment_batch(changed_img, downsample=4) changed_segcount = tally.batch_bincount( changed_seg, num_segclass) delta_segcount = (changed_segcount - orig_segcount).float() for sel, delta in zip(selsegs, delta_segcount): for cond in torch.bincount(sel).nonzero()[:, 0]: if cond == 0: continue yield (cond.item(), delta) return gen_conditions() cond_changes = tally.tally_conditional_mean( compute_seg_impact, dataset, sample_size=10000, batch_size=20, cachefile=resfile('big_door_cond_changes.npz'))
def main(): args = parseargs() model = setting.load_classifier(args.model) model = nethook.InstrumentedModel(model).cuda().eval() layername = args.layer model.retain_layer(layername) dataset = setting.load_dataset(args.dataset, crop_size=224) train_dataset = setting.load_dataset(args.dataset, crop_size=224, split='train') sample_size = len(dataset) # Probe layer to get sizes model(dataset[0][0][None].cuda()) num_units = model.retained_layer(layername).shape[1] classlabels = dataset.classes # Measure baseline classification accuracy on val set, and cache. pbar.descnext('baseline_pra') baseline_precision, baseline_recall, baseline_accuracy, baseline_ba = ( test_perclass_pra(model, dataset, cachefile=sharedfile('pra-%s-%s/pra_baseline.npz' % (args.model, args.dataset)))) pbar.print('baseline acc', baseline_ba.mean().item()) # Now erase each unit, one at a time, and retest accuracy. unit_list = random.sample(list(range(num_units)), num_units) val_single_unit_ablation_ba = torch.zeros(num_units, len(classlabels)) for unit in pbar(unit_list): pbar.descnext('test unit %d' % unit) # Get binary accuracy if the model after ablating the unit. _, _, _, ablation_ba = test_perclass_pra( model, dataset, layername=layername, ablated_units=[unit], cachefile=sharedfile('pra-%s-%s/pra_ablate_unit_%d.npz' % (args.model, args.dataset, unit))) val_single_unit_ablation_ba[unit] = ablation_ba # For the purpose of ranking units by importance to a class, we # measure using the training set (to avoid training unit ordering # on the test set). sample_size = None # Measure baseline classification accuracy, and cache. pbar.descnext('train_baseline_pra') baseline_precision, baseline_recall, baseline_accuracy, baseline_ba = ( test_perclass_pra( model, train_dataset, sample_size=sample_size, cachefile=sharedfile('ttv-pra-%s-%s/pra_train_baseline.npz' % (args.model, args.dataset)))) pbar.print('baseline acc', baseline_ba.mean().item()) # Measure accuracy on the val set. pbar.descnext('val_baseline_pra') _, _, _, val_baseline_ba = (test_perclass_pra( model, dataset, cachefile=sharedfile('ttv-pra-%s-%s/pra_val_baseline.npz' % (args.model, args.dataset)))) pbar.print('val baseline acc', val_baseline_ba.mean().item()) # Do in shuffled order to allow multiprocessing. single_unit_ablation_ba = torch.zeros(num_units, len(classlabels)) for unit in pbar(unit_list): pbar.descnext('test unit %d' % unit) _, _, _, ablation_ba = test_perclass_pra( model, train_dataset, layername=layername, ablated_units=[unit], sample_size=sample_size, cachefile=sharedfile('ttv-pra-%s-%s/pra_train_ablate_unit_%d.npz' % (args.model, args.dataset, unit))) single_unit_ablation_ba[unit] = ablation_ba # Now for every class, remove a set of the N most-important # and N least-important units for that class, and measure accuracy. for classnum in pbar( random.sample(range(len(classlabels)), len(classlabels))): # For a few classes, let's chart the whole range of ablations. if classnum in [100, 169, 351, 304]: num_best_list = range(1, num_units) else: num_best_list = [1, 2, 3, 4, 5, 20, 64, 128, 256] pbar.descnext('numbest') for num_best in pbar(random.sample(num_best_list, len(num_best_list))): num_worst = num_units - num_best unitlist = single_unit_ablation_ba[:, classnum].sort(0)[1][:num_best] _, _, _, testba = test_perclass_pra( model, dataset, layername=layername, ablated_units=unitlist, cachefile=sharedfile( 'ttv-pra-%s-%s/pra_val_ablate_classunits_%s_ba_%d.npz' % (args.model, args.dataset, classlabels[classnum], len(unitlist)))) unitlist = ( single_unit_ablation_ba[:, classnum].sort(0)[1][-num_worst:]) _, _, _, testba2 = test_perclass_pra( model, dataset, layername=layername, ablated_units=unitlist, cachefile=sharedfile( 'ttv-pra-%s-%s/pra_val_ablate_classunits_%s_worstba_%d.npz' % (args.model, args.dataset, classlabels[classnum], len(unitlist)))) pbar.print('%s: best %d %.3f vs worst N %.3f' % (classlabels[classnum], num_best, testba[classnum] - val_baseline_ba[classnum], testba2[classnum] - val_baseline_ba[classnum]))