class DeepLiftExplainer: def __init__(self, model, activation=torch.nn.Softmax(-1)): self.device = 'cuda' if torch.cuda.is_available() else 'cpu' self.base_model = model.to(self.device) self.explainer = DeepLift(self.base_model) self.activation = activation def attribute(self, x, y, retrospective=False): self.base_model.zero_grad() if retrospective: score = self.explainer.attribute(x, target=y.long(), baselines=(x * 0)) score = abs(score.detach().cpu().numpy()) else: score = np.zeros(x.shape) for t in range(1, x.shape[-1]): x_in = x[:, :, :t + 1] pred = self.activation(self.base_model(x_in)) if type(self.activation).__name__ == type( torch.nn.Softmax(-1)).__name__: target = torch.argmax(pred, -1) imp = self.explainer.attribute(x_in, target=target.long(), baselines=(x[:, :, :t + 1] * 0)) score[:, :, t] = abs(imp.detach().cpu().numpy()[:, :, -1]) else: #this works for multilabel and single prediction aka spike n_labels = pred.shape[1] if n_labels > 1: imp = torch.zeros(list(x_in.shape) + [n_labels]) for l in range(n_labels): target = (pred[:, l] > 0.5).float() #[:,0] imp[:, :, :, l] = self.explainer.attribute( x_in, target=target.long(), baselines=(x_in * 0)) score[:, :, t] = (imp.detach().cpu().numpy()).max(3)[:, :, -1] else: #this is for spike with just one label. and we will explain one cla target = (pred > 0.5).float()[:, 0] imp = self.explainer.attribute( x_in, target=target.long(), baselines=(x[:, :, :t + 1] * 0)) score[:, :, t] = abs(imp.detach().cpu().numpy()[:, :, -1]) return score
class Explainer(): def __init__(self, model): self.model = model self.explain = DeepLift(model) def get_attribution_map(self, img, target=None): if target is None: target = torch.argmax(self.model(img), 1) baseline_dist = torch.randn_like(img) * 0.001 attributions, delta = self.explain.attribute( img, baseline_dist, target=target, return_convergence_delta=True) return attributions
def PT_DeepLIFT(model, x, y_onthot, baseline=None, device='cuda:0', **kwargs): input = torch.tensor(x, requires_grad=True).to(device) model = model.to(device) model.eval() saliency = DeepLift(model) target = torch.tensor(np.argmax(y_onthot, -1)).to(device) if baseline is not None: baseline = torch.tensor(baseline).to(device) attribution_map = saliency.attribute(input, target=target, baselines=baseline) return attribution_map.detach().cpu().numpy()
def test_classification_infidelity_convnet_multi_targets(self) -> None: model = BasicModel_ConvNet_One_Conv() dl = DeepLift(model) input = torch.stack([torch.arange(1, 17).float()] * 20, dim=0).view(20, 1, 4, 4) self.infidelity_assert( model, dl.attribute(input, target=torch.tensor([1] * 20)) / input, input, torch.zeros(20), target=torch.tensor([1] * 20), multi_input=False, n_perturb_samples=500, max_batch_size=120, )
def feature_importance(net, graphs, model_name, n_graphs=50, n_steps=2, save=False): n_graphs = min(n_graphs, len(graphs)) input_d = dgl.batch([graphs[i] for i in range(n_graphs)]) # ig = IntegratedGradients(net) # ig_attr_test = ig.attribute(input_d.ndata[Constants.NODE_FEATURES_NAME], # additional_forward_args=(dgl.batch([input_d] * n_steps)), # target=1, n_steps=n_steps) # # ig_attr_test_sum = ig_attr_test.detach().numpy().sum(0) # ig_attr_test_norm_sum = ig_attr_test_sum / np.linalg.norm(ig_attr_test_sum, ord=1) dl = DeepLift(net) dl_attr_test = dl.attribute(input_d.ndata[Constants.NODE_FEATURES_NAME], additional_forward_args=(dgl.batch([input_d] * 2)), target=1) dl_attr_test_sum = dl_attr_test.detach().numpy().sum(0) dl_attr_test_norm_sum = dl_attr_test_sum / np.linalg.norm(dl_attr_test_sum, ord=1) index_array = np.argsort(-np.absolute(dl_attr_test_norm_sum)) n = 25 names = np.array(Constants.FEATURE_NAMES)[index_array] attrs = dl_attr_test_norm_sum[index_array] for i in range(int(np.ceil(len(Constants.FEATURE_NAMES) / n))): maxi = min((i + 1) * n, len(Constants.FEATURE_NAMES)) plt.figure() plt.barh(names[maxi:i * n:-1], attrs[maxi:i * n:-1]) plt.title('Feature importance') plt.tight_layout() if save: plt.savefig( os.path.join(Constants.MODELS_PATH, model_name, f'feature_importance_DL_{i}.png')) else: plt.show()
def find_genes_DeepLift(drug, ens, meta, test_tcga_expr): from captum.attr import DeepLift dl = DeepLift(ens) x = torch.FloatTensor(test_tcga_expr.values) attr = pd.DataFrame(dl.attribute(x).detach().numpy(), index=test_tcga_expr.index, columns=dataset.hgnc) genes = get_ranked_list(attr) out = pd.DataFrame(columns=['borda', 'mean']) attr_mean = list(np.abs(attr).mean(axis=0).nlargest(200).index) out['borda'] = genes out['mean'] = attr_mean out.to_csv(res_dir + drug + '/genes.csv', index=False) fig, ax = plt.subplots(figsize=(15, 5)) for i in attr.index(): ax.plt(range(len(dataset.hgnc)), attr.loc[i], alpha=0.2) plt.show()
def main(args): train_loader, test_loader = data_generator(args.data_dir,1) for m in range(len(models)): model_name = "model_{}_NumFeatures_{}".format(models[m],args.NumFeatures) model_filename = args.model_dir + 'm_' + model_name + '.pt' pretrained_model = torch.load(open(model_filename, "rb"),map_location=device) pretrained_model.to(device) if(args.GradFlag): Grad = Saliency(pretrained_model) if(args.IGFlag): IG = IntegratedGradients(pretrained_model) if(args.DLFlag): DL = DeepLift(pretrained_model) if(args.GSFlag): GS = GradientShap(pretrained_model) if(args.DLSFlag): DLS = DeepLiftShap(pretrained_model) if(args.SGFlag): Grad_ = Saliency(pretrained_model) SG = NoiseTunnel(Grad_) if(args.ShapleySamplingFlag): SS = ShapleyValueSampling(pretrained_model) if(args.GSFlag): FP = FeaturePermutation(pretrained_model) if(args.FeatureAblationFlag): FA = FeatureAblation(pretrained_model) if(args.OcclusionFlag): OS = Occlusion(pretrained_model) timeMask=np.zeros((args.NumTimeSteps, args.NumFeatures),dtype=int) featureMask=np.zeros((args.NumTimeSteps, args.NumFeatures),dtype=int) for i in range (args.NumTimeSteps): timeMask[i,:]=i for i in range (args.NumTimeSteps): featureMask[:,i]=i indexes = [[] for i in range(5,10)] for i ,(data, target) in enumerate(test_loader): if(target==5 or target==6 or target==7 or target==8 or target==9): index=target-5 if(len(indexes[index])<1): indexes[index].append(i) for j, index in enumerate(indexes): print(index) # indexes = [[21],[17],[84],[9]] for j, index in enumerate(indexes): print("Getting Saliency for number", j+1) for i, (data, target) in enumerate(test_loader): if(i in index): labels = target.to(device) input = data.reshape(-1, args.NumTimeSteps, args.NumFeatures).to(device) input = Variable(input, volatile=False, requires_grad=True) baseline_single=torch.Tensor(np.random.random(input.shape)).to(device) baseline_multiple=torch.Tensor(np.random.random((input.shape[0]*5,input.shape[1],input.shape[2]))).to(device) inputMask= np.zeros((input.shape)) inputMask[:,:,:]=timeMask inputMask =torch.Tensor(inputMask).to(device) mask_single= torch.Tensor(timeMask).to(device) mask_single=mask_single.reshape(1,args.NumTimeSteps, args.NumFeatures).to(device) Data=data.reshape(args.NumTimeSteps, args.NumFeatures).data.cpu().numpy() target_=int(target.data.cpu().numpy()[0]) plotExampleBox(Data,args.Graph_dir+'Sample_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.GradFlag): attributions = Grad.attribute(input, \ target=labels) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_Grad_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(Grad,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=None) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_Grad_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.IGFlag): attributions = IG.attribute(input, \ baselines=baseline_single, \ target=labels) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_IG_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(IG,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=baseline_single) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_IG_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.DLFlag): attributions = DL.attribute(input, \ baselines=baseline_single, \ target=labels) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_DL_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(DL,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=baseline_single) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_DL_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.GSFlag): attributions = GS.attribute(input, \ baselines=baseline_multiple, \ stdevs=0.09,\ target=labels) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_GS_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(GS,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=baseline_multiple) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_GS_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.DLSFlag): attributions = DLS.attribute(input, \ baselines=baseline_multiple, \ target=labels) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_DLS_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(DLS,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=baseline_multiple) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_DLS_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.SGFlag): attributions = SG.attribute(input, \ target=labels) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_SG_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(SG,input, args.NumFeatures,args.NumTimeSteps, labels) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_SG_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.ShapleySamplingFlag): attributions = SS.attribute(input, \ baselines=baseline_single, \ target=labels,\ feature_mask=inputMask) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_SVS_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(SS,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=baseline_single,hasFeatureMask=inputMask) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_SVS_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) # if(args.FeaturePermutationFlag): # attributions = FP.attribute(input, \ # target=labels), # # perturbations_per_eval= 1,\ # # feature_mask=mask_single) # saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) # plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_FP',greyScale=True) if(args.FeatureAblationFlag): attributions = FA.attribute(input, \ target=labels) # perturbations_per_eval= input.shape[0],\ # feature_mask=mask_single) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_FA_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(FA,input, args.NumFeatures,args.NumTimeSteps, labels) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_FA_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.OcclusionFlag): attributions = OS.attribute(input, \ sliding_window_shapes=(1,int(args.NumFeatures/10)), target=labels, baselines=baseline_single) saliency_=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,attributions) plotExampleBox(saliency_[0],args.Graph_dir+models[m]+'_FO_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True) if(args.TSRFlag): TSR_attributions = getTwoStepRescaling(OS,input, args.NumFeatures,args.NumTimeSteps, labels,hasBaseline=baseline_single,hasSliding_window_shapes= (1,int(args.NumFeatures/10))) TSR_saliency=Helper.givenAttGetRescaledSaliency(args.NumTimeSteps, args.NumFeatures,TSR_attributions,isTensor=False) plotExampleBox(TSR_saliency,args.Graph_dir+models[m]+'_TSR_FO_MNIST_'+str(target_)+'_index_'+str(i+1),greyScale=True)
def extract_DL(self, X_test): dl = DeepLift(self.net) start = time.time() dl_attr_test = dl.attribute(X_test.to(self.device)) print("temps train", time.time() - start) return dl_attr_test.detach().cpu().numpy()
def DeepLIFT(classifier_model, config, dataset_features, GNNgraph_list, current_fold, cuda=0): ''' :param classifier_model: trained classifier model :param config: parsed configuration file of config.yml :param dataset_features: a dictionary of dataset features obtained from load_data.py :param GNNgraph_list: a list of GNNgraphs obtained from the dataset :param cuda: whether to use GPU to perform conversion to tensor ''' # Initialise settings config = config interpretability_config = config["interpretability_methods"]["DeepLIFT"] dataset_features = dataset_features # Perform deeplift on the classifier model dl = DeepLift(classifier_model) output_for_metrics_calculation = [] output_for_generating_saliency_map = {} # Obtain attribution score for use in qualitative metrics tmp_timing_list = [] for GNNgraph in GNNgraph_list: output = {'graph': GNNgraph} for _, label in dataset_features["label_dict"].items(): # Relabel all just in case, may only relabel those that need relabelling # if performance is poor original_label = GNNgraph.label GNNgraph.label = label node_feat, n2n, subg = graph_to_tensor( [GNNgraph], dataset_features["feat_dim"], dataset_features["edge_feat_dim"], cuda) start_generation = perf_counter() attribution = dl.attribute(node_feat, additional_forward_args=(n2n, subg, [GNNgraph]), target=label) tmp_timing_list.append(perf_counter() - start_generation) attribution_score = torch.sum(attribution, dim=1).tolist() attribution_score = standardize_scores(attribution_score) GNNgraph.label = original_label output[label] = attribution_score output_for_metrics_calculation.append(output) execution_time = sum(tmp_timing_list)/(len(tmp_timing_list)) # Obtain attribution score for use in generating saliency map for comparison with zero tensors if interpretability_config["compare_with_zero_tensor"] is True: if interpretability_config["sample_ids"] is not None: if ',' in str(interpretability_config["sample_ids"]): sample_graph_id_list = list(map(int, interpretability_config["sample_ids"].split(','))) else: sample_graph_id_list = [int(interpretability_config["sample_ids"])] output_for_generating_saliency_map.update({"layergradcam_%s_%s" % (str(assign_type), str(label)): [] for _, label in dataset_features["label_dict"].items()}) for index in range(len(output_for_metrics_calculation)): tmp_output = output_for_metrics_calculation[index] tmp_label = tmp_output['graph'].label if tmp_output['graph'].graph_id in sample_graph_id_list: element_name = "layergradcam_%s_%s" % (str(assign_type), str(tmp_label)) output_for_generating_saliency_map[element_name].append( (tmp_output['graph'], tmp_output[tmp_label])) elif interpretability_config["number_of_zero_tensor_samples"] > 0: # Randomly sample from existing list: graph_idxes = list(range(len(output_for_metrics_calculation))) random.shuffle(graph_idxes) output_for_generating_saliency_map.update({"deeplift_zero_tensor_class_%s" % str(label): [] for _, label in dataset_features["label_dict"].items()}) # Begin appending found samples for index in graph_idxes: tmp_label = output_for_metrics_calculation[index]['graph'].label element_name = "deeplift_zero_tensor_class_%s" % str(tmp_label) if len(output_for_generating_saliency_map[element_name]) < interpretability_config["number_of_zero_tensor_samples"]: output_for_generating_saliency_map[element_name].append( (output_for_metrics_calculation[index]['graph'], output_for_metrics_calculation[index][tmp_label])) # Obtain attribution score for use in generating saliency map for comparison with isomers if interpretability_config["compare_with_isomorphic_samples"] is True: if dataset_features["num_class"] != 2: print("DeepLIFT.py: Comparing with isomorphic samples is only possible in binary classification tasks.") else: # Get all isomorphic pairs class_0_graphs, class_1_graphs = get_isomorphic_pairs( dataset_features["name"], GNNgraph_list, config["run"]["k_fold"], current_fold, interpretability_config["number_of_isomorphic_sample_pairs"]) # Generate attribution scores for the isomorphic pairs if class_0_graphs == None: pass elif len(class_0_graphs) == 0 or len(class_1_graphs) == 0: print("DeepLIFT: No isomorphic pairs found for test dataset") else: output_for_generating_saliency_map["deeplift_isomorphic_class_0"] = [] output_for_generating_saliency_map["deeplift_isomorphic_class_1"] = [] for graph_0, graph_1 in zip(class_0_graphs, class_1_graphs): node_feat_0, n2n, subg = graph_to_tensor( [graph_0], dataset_features["feat_dim"], dataset_features["edge_feat_dim"], cuda) node_feat_1, _, _ = graph_to_tensor( [graph_1], dataset_features["feat_dim"], dataset_features["edge_feat_dim"], cuda) attribution_0 = dl.attribute(node_feat_0, additional_forward_args=(n2n, subg, [graph_0]), baselines=node_feat_1, target=graph_0.label) attribution_1 = dl.attribute(node_feat_1, additional_forward_args=(n2n, subg, [graph_1]), baselines=node_feat_0, target=graph_1.label) attribution_score_0 = torch.sum(attribution_0, dim=1).tolist() attribution_score_1 = torch.sum(attribution_1, dim=1).tolist() attribution_score_0 = standardize_scores(attribution_score_0) attribution_score_1 = standardize_scores(attribution_score_1) output_for_generating_saliency_map["deeplift_isomorphic_class_0"].append( (graph_0, attribution_score_0)) output_for_generating_saliency_map["deeplift_isomorphic_class_1"].append( (graph_1, attribution_score_1)) return output_for_metrics_calculation, output_for_generating_saliency_map, execution_time
def run_saliency_methods(saliency_methods, pretrained_model, test_shape, train_loader, test_loader, device, model_type, model_name, saliency_dir, tsr_graph_dir=None, tsr_inputs_to_graph=()): _, num_timesteps, num_features = test_shape run_grad = "Grad" in saliency_methods run_grad_tsr = "Grad_TSR" in saliency_methods run_ig = "IG" in saliency_methods run_ig_tsr = "IG_TSR" in saliency_methods run_dl = "DL" in saliency_methods run_gs = "GS" in saliency_methods run_dls = "DLS" in saliency_methods run_dls_tsr = "DLS_TSR" in saliency_methods run_sg = "SG" in saliency_methods run_shapley_sampling = "ShapleySampling" in saliency_methods run_feature_permutation = "FeaturePermutation" in saliency_methods run_feature_ablation = "FeatureAblation" in saliency_methods run_occlusion = "Occlusion" in saliency_methods run_fit = "FIT" in saliency_methods run_ifit = "IFIT" in saliency_methods run_wfit = "WFIT" in saliency_methods run_iwfit = "IWFIT" in saliency_methods if run_grad or run_grad_tsr: Grad = Saliency(pretrained_model) if run_grad: rescaledGrad = np.zeros(test_shape) if run_grad_tsr: rescaledGrad_TSR = np.zeros(test_shape) if run_ig or run_ig_tsr: IG = IntegratedGradients(pretrained_model) if run_ig: rescaledIG = np.zeros(test_shape) if run_ig_tsr: rescaledIG_TSR = np.zeros(test_shape) if run_dl: rescaledDL = np.zeros(test_shape) DL = DeepLift(pretrained_model) if run_gs: rescaledGS = np.zeros(test_shape) GS = GradientShap(pretrained_model) if run_dls or run_dls_tsr: DLS = DeepLiftShap(pretrained_model) if run_dls: rescaledDLS = np.zeros(test_shape) if run_dls_tsr: rescaledDLS_TSR = np.zeros(test_shape) if run_sg: rescaledSG = np.zeros(test_shape) Grad_ = Saliency(pretrained_model) SG = NoiseTunnel(Grad_) if run_shapley_sampling: rescaledShapleySampling = np.zeros(test_shape) SS = ShapleyValueSampling(pretrained_model) if run_gs: rescaledFeaturePermutation = np.zeros(test_shape) FP = FeaturePermutation(pretrained_model) if run_feature_ablation: rescaledFeatureAblation = np.zeros(test_shape) FA = FeatureAblation(pretrained_model) if run_occlusion: rescaledOcclusion = np.zeros(test_shape) OS = Occlusion(pretrained_model) if run_fit: rescaledFIT = np.zeros(test_shape) FIT = FITExplainer(pretrained_model, ft_dim_last=True) generator = JointFeatureGenerator(num_features, data='none') # TODO: Increase epochs FIT.fit_generator(generator, train_loader, test_loader, n_epochs=300) if run_ifit: rescaledIFIT = np.zeros(test_shape) if run_wfit: rescaledWFIT = np.zeros(test_shape) if run_iwfit: rescaledIWFIT = np.zeros(test_shape) idx = 0 mask = np.zeros((num_timesteps, num_features), dtype=int) for i in range(num_timesteps): mask[i, :] = i for i, (samples, labels) in enumerate(test_loader): input = samples.reshape(-1, num_timesteps, num_features).to(device) input = Variable(input, volatile=False, requires_grad=True) batch_size = input.shape[0] baseline_single = torch.from_numpy(np.random.random( input.shape)).to(device) baseline_multiple = torch.from_numpy( np.random.random((input.shape[0] * 5, input.shape[1], input.shape[2]))).to(device) inputMask = np.zeros((input.shape)) inputMask[:, :, :] = mask inputMask = torch.from_numpy(inputMask).to(device) mask_single = torch.from_numpy(mask).to(device) mask_single = mask_single.reshape(1, num_timesteps, num_features).to(device) labels = torch.tensor(labels.int().tolist()).to(device) if run_grad: attributions = Grad.attribute(input, target=labels) rescaledGrad[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_grad_tsr: rescaledGrad_TSR[idx:idx + batch_size, :, :] = get_tsr_saliency( Grad, input, labels, graph_dir=tsr_graph_dir, graph_name=f'{model_name}_{model_type}_Grad_TSR', inputs_to_graph=tsr_inputs_to_graph, cur_batch=i) if run_ig: attributions = IG.attribute(input, baselines=baseline_single, target=labels) rescaledIG[idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_ig_tsr: rescaledIG_TSR[idx:idx + batch_size, :, :] = get_tsr_saliency( IG, input, labels, baseline=baseline_single, graph_dir=tsr_graph_dir, graph_name=f'{model_name}_{model_type}_IG_TSR', inputs_to_graph=tsr_inputs_to_graph, cur_batch=i) if run_dl: attributions = DL.attribute(input, baselines=baseline_single, target=labels) rescaledDL[idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_gs: attributions = GS.attribute(input, baselines=baseline_multiple, stdevs=0.09, target=labels) rescaledGS[idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_dls: attributions = DLS.attribute(input, baselines=baseline_multiple, target=labels) rescaledDLS[idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_dls_tsr: rescaledDLS_TSR[idx:idx + batch_size, :, :] = get_tsr_saliency( DLS, input, labels, baseline=baseline_multiple, graph_dir=tsr_graph_dir, graph_name=f'{model_name}_{model_type}_DLS_TSR', inputs_to_graph=tsr_inputs_to_graph, cur_batch=i) if run_sg: attributions = SG.attribute(input, target=labels) rescaledSG[idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_shapley_sampling: attributions = SS.attribute(input, baselines=baseline_single, target=labels, feature_mask=inputMask) rescaledShapleySampling[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_feature_permutation: attributions = FP.attribute(input, target=labels, perturbations_per_eval=input.shape[0], feature_mask=mask_single) rescaledFeaturePermutation[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_feature_ablation: attributions = FA.attribute(input, target=labels) # perturbations_per_eval= input.shape[0],\ # feature_mask=mask_single) rescaledFeatureAblation[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_occlusion: attributions = OS.attribute(input, sliding_window_shapes=(1, num_features), target=labels, baselines=baseline_single) rescaledOcclusion[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_fit: attributions = torch.from_numpy(FIT.attribute(input, labels)) rescaledFIT[idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( num_timesteps, num_features, attributions) if run_ifit: attributions = torch.from_numpy( inverse_fit_attribute(input, pretrained_model, ft_dim_last=True)) rescaledIFIT[idx:idx + batch_size, :, :] = attributions if run_wfit: attributions = torch.from_numpy( wfit_attribute(input, pretrained_model, N=test_shape[1], ft_dim_last=True, single_label=True)) rescaledWFIT[idx:idx + batch_size, :, :] = attributions if run_iwfit: attributions = torch.from_numpy( wfit_attribute(input, pretrained_model, N=test_shape[1], ft_dim_last=True, single_label=True, inverse=True)) rescaledIWFIT[idx:idx + batch_size, :, :] = attributions idx += batch_size if run_grad: print("Saving Grad", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_Grad_rescaled", rescaledGrad) if run_grad_tsr: print("Saving Grad_TSR", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_Grad_TSR_rescaled", rescaledGrad_TSR) if run_ig: print("Saving IG", model_name + "_" + model_type) np.save(saliency_dir + model_name + "_" + model_type + "_IG_rescaled", rescaledIG) if run_ig_tsr: print("Saving IG_TSR", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_IG_TSR_rescaled", rescaledIG_TSR) if run_dl: print("Saving DL", model_name + "_" + model_type) np.save(saliency_dir + model_name + "_" + model_type + "_DL_rescaled", rescaledDL) if run_gs: print("Saving GS", model_name + "_" + model_type) np.save(saliency_dir + model_name + "_" + model_type + "_GS_rescaled", rescaledGS) if run_dls: print("Saving DLS", model_name + "_" + model_type) np.save(saliency_dir + model_name + "_" + model_type + "_DLS_rescaled", rescaledDLS) if run_dls_tsr: print("Saving DLS_TSR", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_DLS_TSR_rescaled", rescaledDLS_TSR) if run_sg: print("Saving SG", model_name + "_" + model_type) np.save(saliency_dir + model_name + "_" + model_type + "_SG_rescaled", rescaledSG) if run_shapley_sampling: print("Saving ShapleySampling", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_ShapleySampling_rescaled", rescaledShapleySampling) if run_feature_permutation: print("Saving FeaturePermutation", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_FeaturePermutation_rescaled", rescaledFeaturePermutation) if run_feature_ablation: print("Saving FeatureAblation", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_FeatureAblation_rescaled", rescaledFeatureAblation) if run_occlusion: print("Saving Occlusion", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_Occlusion_rescaled", rescaledOcclusion) if run_fit: print("Saving FIT", model_name + "_" + model_type) np.save(saliency_dir + model_name + "_" + model_type + "_FIT_rescaled", rescaledFIT) if run_ifit: print("Saving IFIT", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_IFIT_rescaled", rescaledIFIT) if run_wfit: print("Saving WFIT", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_WFIT_rescaled", rescaledWFIT) if run_iwfit: print("Saving IWFIT", model_name + "_" + model_type) np.save( saliency_dir + model_name + "_" + model_type + "_IWFIT_rescaled", rescaledIWFIT)
def main(args, DatasetsTypes, DataGenerationTypes, models, device): for m in range(len(models)): for x in range(len(DatasetsTypes)): for y in range(len(DataGenerationTypes)): if (DataGenerationTypes[y] == None): args.DataName = DatasetsTypes[x] + "_Box" else: args.DataName = DatasetsTypes[ x] + "_" + DataGenerationTypes[y] Training = np.load(args.data_dir + "SimulatedTrainingData_" + args.DataName + "_F_" + str(args.NumFeatures) + "_TS_" + str(args.NumTimeSteps) + ".npy") TrainingMetaDataset = np.load(args.data_dir + "SimulatedTrainingMetaData_" + args.DataName + "_F_" + str(args.NumFeatures) + "_TS_" + str(args.NumTimeSteps) + ".npy") TrainingLabel = TrainingMetaDataset[:, 0] Testing = np.load(args.data_dir + "SimulatedTestingData_" + args.DataName + "_F_" + str(args.NumFeatures) + "_TS_" + str(args.NumTimeSteps) + ".npy") TestingDataset_MetaData = np.load(args.data_dir + "SimulatedTestingMetaData_" + args.DataName + "_F_" + str(args.NumFeatures) + "_TS_" + str(args.NumTimeSteps) + ".npy") TestingLabel = TestingDataset_MetaData[:, 0] Training = Training.reshape( Training.shape[0], Training.shape[1] * Training.shape[2]) Testing = Testing.reshape(Testing.shape[0], Testing.shape[1] * Testing.shape[2]) scaler = MinMaxScaler() scaler.fit(Training) Training = scaler.transform(Training) Testing = scaler.transform(Testing) TrainingRNN = Training.reshape(Training.shape[0], args.NumTimeSteps, args.NumFeatures) TestingRNN = Testing.reshape(Testing.shape[0], args.NumTimeSteps, args.NumFeatures) train_dataRNN = data_utils.TensorDataset( torch.from_numpy(TrainingRNN), torch.from_numpy(TrainingLabel)) train_loaderRNN = data_utils.DataLoader( train_dataRNN, batch_size=args.batch_size, shuffle=True) test_dataRNN = data_utils.TensorDataset( torch.from_numpy(TestingRNN), torch.from_numpy(TestingLabel)) test_loaderRNN = data_utils.DataLoader( test_dataRNN, batch_size=args.batch_size, shuffle=False) modelName = "Simulated" modelName += args.DataName saveModelName = "../Models/" + models[m] + "/" + modelName saveModelBestName = saveModelName + "_BEST.pkl" pretrained_model = torch.load(saveModelBestName, map_location=device) Test_Acc = checkAccuracy(test_loaderRNN, pretrained_model, args) print('{} {} model BestAcc {:.4f}'.format( args.DataName, models[m], Test_Acc)) if (Test_Acc >= 90): if (args.GradFlag): rescaledGrad = np.zeros((TestingRNN.shape)) Grad = Saliency(pretrained_model) if (args.IGFlag): rescaledIG = np.zeros((TestingRNN.shape)) IG = IntegratedGradients(pretrained_model) if (args.DLFlag): rescaledDL = np.zeros((TestingRNN.shape)) DL = DeepLift(pretrained_model) if (args.GSFlag): rescaledGS = np.zeros((TestingRNN.shape)) GS = GradientShap(pretrained_model) if (args.DLSFlag): rescaledDLS = np.zeros((TestingRNN.shape)) DLS = DeepLiftShap(pretrained_model) if (args.SGFlag): rescaledSG = np.zeros((TestingRNN.shape)) Grad_ = Saliency(pretrained_model) SG = NoiseTunnel(Grad_) if (args.ShapleySamplingFlag): rescaledShapleySampling = np.zeros((TestingRNN.shape)) SS = ShapleyValueSampling(pretrained_model) if (args.GSFlag): rescaledFeaturePermutation = np.zeros( (TestingRNN.shape)) FP = FeaturePermutation(pretrained_model) if (args.FeatureAblationFlag): rescaledFeatureAblation = np.zeros((TestingRNN.shape)) FA = FeatureAblation(pretrained_model) if (args.OcclusionFlag): rescaledOcclusion = np.zeros((TestingRNN.shape)) OS = Occlusion(pretrained_model) idx = 0 mask = np.zeros((args.NumTimeSteps, args.NumFeatures), dtype=int) for i in range(args.NumTimeSteps): mask[i, :] = i for i, (samples, labels) in enumerate(test_loaderRNN): print('[{}/{}] {} {} model accuracy {:.2f}'\ .format(i,len(test_loaderRNN), models[m], args.DataName, Test_Acc)) input = samples.reshape(-1, args.NumTimeSteps, args.NumFeatures).to(device) input = Variable(input, volatile=False, requires_grad=True) batch_size = input.shape[0] baseline_single = torch.from_numpy( np.random.random(input.shape)).to(device) baseline_multiple = torch.from_numpy( np.random.random( (input.shape[0] * 5, input.shape[1], input.shape[2]))).to(device) inputMask = np.zeros((input.shape)) inputMask[:, :, :] = mask inputMask = torch.from_numpy(inputMask).to(device) mask_single = torch.from_numpy(mask).to(device) mask_single = mask_single.reshape( 1, args.NumTimeSteps, args.NumFeatures).to(device) labels = torch.tensor(labels.int().tolist()).to(device) if (args.GradFlag): attributions = Grad.attribute(input, \ target=labels) rescaledGrad[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.IGFlag): attributions = IG.attribute(input, \ baselines=baseline_single, \ target=labels) rescaledIG[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.DLFlag): attributions = DL.attribute(input, \ baselines=baseline_single, \ target=labels) rescaledDL[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.GSFlag): attributions = GS.attribute(input, \ baselines=baseline_multiple, \ stdevs=0.09,\ target=labels) rescaledGS[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.DLSFlag): attributions = DLS.attribute(input, \ baselines=baseline_multiple, \ target=labels) rescaledDLS[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.SGFlag): attributions = SG.attribute(input, \ target=labels) rescaledSG[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.ShapleySamplingFlag): attributions = SS.attribute(input, \ baselines=baseline_single, \ target=labels,\ feature_mask=inputMask) rescaledShapleySampling[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.FeaturePermutationFlag): attributions = FP.attribute(input, \ target=labels, perturbations_per_eval= input.shape[0],\ feature_mask=mask_single) rescaledFeaturePermutation[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.FeatureAblationFlag): attributions = FA.attribute(input, \ target=labels) # perturbations_per_eval= input.shape[0],\ # feature_mask=mask_single) rescaledFeatureAblation[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) if (args.OcclusionFlag): attributions = OS.attribute(input, \ sliding_window_shapes=(1,args.NumFeatures), target=labels, baselines=baseline_single) rescaledOcclusion[ idx:idx + batch_size, :, :] = Helper.givenAttGetRescaledSaliency( args, attributions) idx += batch_size if (args.plot): index = random.randint(0, TestingRNN.shape[0] - 1) plotExampleBox(TestingRNN[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_sample', flip=True) print("Plotting sample", index) if (args.GradFlag): plotExampleBox(rescaledGrad[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_Grad', greyScale=True, flip=True) if (args.IGFlag): plotExampleBox(rescaledIG[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_IG', greyScale=True, flip=True) if (args.DLFlag): plotExampleBox(rescaledDL[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_DL', greyScale=True, flip=True) if (args.GSFlag): plotExampleBox(rescaledGS[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_GS', greyScale=True, flip=True) if (args.DLSFlag): plotExampleBox(rescaledDLS[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_DLS', greyScale=True, flip=True) if (args.SGFlag): plotExampleBox(rescaledSG[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_SG', greyScale=True, flip=True) if (args.ShapleySamplingFlag): plotExampleBox( rescaledShapleySampling[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_ShapleySampling', greyScale=True, flip=True) if (args.FeaturePermutationFlag): plotExampleBox( rescaledFeaturePermutation[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_FeaturePermutation', greyScale=True, flip=True) if (args.FeatureAblationFlag): plotExampleBox( rescaledFeatureAblation[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_FeatureAblation', greyScale=True, flip=True) if (args.OcclusionFlag): plotExampleBox(rescaledOcclusion[index, :, :], args.Saliency_Maps_graphs_dir + args.DataName + "_" + models[m] + '_Occlusion', greyScale=True, flip=True) if (args.save): if (args.GradFlag): print("Saving Grad", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_Grad_rescaled", rescaledGrad) if (args.IGFlag): print("Saving IG", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_IG_rescaled", rescaledIG) if (args.DLFlag): print("Saving DL", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_DL_rescaled", rescaledDL) if (args.GSFlag): print("Saving GS", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_GS_rescaled", rescaledGS) if (args.DLSFlag): print("Saving DLS", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_DLS_rescaled", rescaledDLS) if (args.SGFlag): print("Saving SG", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_SG_rescaled", rescaledSG) if (args.ShapleySamplingFlag): print("Saving ShapleySampling", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_ShapleySampling_rescaled", rescaledShapleySampling) if (args.FeaturePermutationFlag): print("Saving FeaturePermutation", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_FeaturePermutation_rescaled", rescaledFeaturePermutation) if (args.FeatureAblationFlag): print("Saving FeatureAblation", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_FeatureAblation_rescaled", rescaledFeatureAblation) if (args.OcclusionFlag): print("Saving Occlusion", modelName + "_" + models[m]) np.save( args.Saliency_dir + modelName + "_" + models[m] + "_Occlusion_rescaled", rescaledOcclusion) else: logging.basicConfig(filename=args.log_file, level=logging.DEBUG) logging.debug('{} {} model BestAcc {:.4f}'.format( args.DataName, models[m], Test_Acc)) if not os.path.exists(args.ignore_list): with open(args.ignore_list, 'w') as fp: fp.write(args.DataName + '_' + models[m] + '\n') else: with open(args.ignore_list, "a") as fp: fp.write(args.DataName + '_' + models[m] + '\n')
model.to(torch.device("cpu")) deeplift = DeepLift(model) deeplift_shap = DeepLiftShap(model) deeplift_baseline = deeplift_baseline.resize(1, deeplift_baseline.shape[0]) attribution_brca = 0 attribution_ucec = 0 attribution_kirc = 0 attribution_luad = 0 attribution_skcm = 0 total = 0 for i, inputs in enumerate(dl_loader, 0): attribution_brca = torch.abs( deeplift.attribute(inputs, target=0, baselines=deeplift_baseline)) attribution_ucec = torch.abs( deeplift.attribute(inputs, target=1, baselines=deeplift_baseline)) attribution_kirc = torch.abs( deeplift.attribute(inputs, target=2, baselines=deeplift_baseline)) attribution_luad = torch.abs( deeplift.attribute(inputs, target=3, baselines=deeplift_baseline)) attribution_skcm = torch.abs( deeplift.attribute(inputs, target=4, baselines=deeplift_baseline)) total = (attribution_brca + attribution_ucec + attribution_kirc + attribution_luad + attribution_skcm) mean_df = pd.DataFrame(columns=['GENE', 'SCORE']) mean_df.GENE = gene_ids mean_df.SCORE = torch.mean(total, 0).detach().numpy()
def get_grad_imp(model, X, y=None, mode='grad', return_y=False, clip=False, baselines=None): X.requires_grad_(True) # X = X.cuda() if mode in ['grad']: logits = model(X) if y is None: y = logits.argmax(dim=1) attributions = torch.autograd.grad( logits[torch.arange(len(logits)), y].sum(), X)[0].detach() else: if y is None: with torch.no_grad(): logits = model(X) y = logits.argmax(dim=1) if mode == 'deeplift': dl = DeepLift(model) attributions = dl.attribute(inputs=X, baselines=0., target=y) attributions = attributions.detach() # attributions = (attributions.detach() ** 2).sum(dim=1, keepdim=True) # elif mode in ['deepliftshap', 'deepliftshap_mean']: elif mode in ['deepliftshap']: dl = DeepLiftShap(model) attributions = [] for idx in range(0, len(X), 2): the_x, the_y = X[idx:(idx + 2)], y[idx:(idx + 2)] attribution = dl.attribute(inputs=the_x, baselines=baselines, target=the_y) attributions.append(attribution.detach()) attributions = torch.cat(attributions, dim=0) # attributions = dl.attribute(inputs=X, baselines=baselines, target=y).detach() # if mode == 'deepliftshap': # attributions = (attributions ** 2).sum(dim=1, keepdim=True) # else: # attributions = (attributions).mean(dim=1, keepdim=True) elif mode in ['gradcam']: orig_lgc = LayerGradCam(model, model.body[0]) attributions = orig_lgc.attribute(X, target=y) attributions = F.interpolate(attributions, size=X.shape[-2:], mode='bilinear') else: raise NotImplementedError(f'${mode} is not specified.') # Do clipping! if clip: attributions = myclip(attributions) X.requires_grad_(False) if not return_y: return attributions return attributions, y
number_references = 10 # imp scores are averaged over 10 reference sequences hypo_A_scores = [] hypo_C_scores = [] hypo_G_scores = [] hypo_T_scores = [] importance_scores = [] for ref in range(number_references): seq_ref = seq[:, :, torch.randperm(seq.size()[2])] # obtaining attribution scores dl = DeepLift(model, multiply_by_inputs=False) attributions, delta = dl.attribute(seq, seq_ref, target=JUND_index, return_convergence_delta=True) attribution_imp = ( seq - seq_ref) * attributions # obtaining importance scores imp_score = torch.sum(attribution_imp, axis=1) # summing across all 4 bases importance_scores.append(imp_score) # obtaining hypothetical importance scores for A,C,G,T attributions_hypo_A = (hypo_A - seq_ref) * attributions attributions_A = torch.sum(attributions_hypo_A, axis=1) hypo_A_scores.append(attributions_A)
def get_attribution(real_img, fake_img, real_class, fake_class, net_module, checkpoint_path, input_shape, channels, methods=["ig", "grads", "gc", "ggc", "dl", "ingrad", "random", "residual"], output_classes=6, downsample_factors=[(2,2), (2,2), (2,2), (2,2)]): imgs = [image_to_tensor(normalize_image(real_img).astype(np.float32)), image_to_tensor(normalize_image(fake_img).astype(np.float32))] classes = [real_class, fake_class] net = init_network(checkpoint_path, input_shape, net_module, channels, output_classes=output_classes,eval_net=True, require_grad=False, downsample_factors=downsample_factors) attrs = [] attrs_names = [] if "residual" in methods: res = np.abs(real_img - fake_img) res = res - np.min(res) attrs.append(torch.tensor(res/np.max(res))) attrs_names.append("residual") if "random" in methods: rand = np.abs(np.random.randn(*np.shape(real_img))) rand = np.abs(scipy.ndimage.filters.gaussian_filter(rand, 4)) rand = rand - np.min(rand) rand = rand/np.max(np.abs(rand)) attrs.append(torch.tensor(rand)) attrs_names.append("random") if "gc" in methods: net.zero_grad() last_conv_layer = [(name,module) for name, module in net.named_modules() if type(module) == torch.nn.Conv2d][-1] layer_name = last_conv_layer[0] layer = last_conv_layer[1] layer_gc = LayerGradCam(net, layer) gc_real = layer_gc.attribute(imgs[0], target=classes[0]) gc_fake = layer_gc.attribute(imgs[1], target=classes[1]) gc_real = project_layer_activations_to_input_rescale(gc_real.cpu().detach().numpy(), (input_shape[0], input_shape[1])) gc_fake = project_layer_activations_to_input_rescale(gc_fake.cpu().detach().numpy(), (input_shape[0], input_shape[1])) attrs.append(torch.tensor(gc_real[0,0,:,:])) attrs_names.append("gc_real") attrs.append(torch.tensor(gc_fake[0,0,:,:])) attrs_names.append("gc_fake") # SCAM gc_diff_0, gc_diff_1 = get_sgc(real_img, fake_img, real_class, fake_class, net_module, checkpoint_path, input_shape, channels, None, output_classes=output_classes, downsample_factors=downsample_factors) attrs.append(gc_diff_0) attrs_names.append("gc_diff_0") attrs.append(gc_diff_1) attrs_names.append("gc_diff_1") if "ggc" in methods: net.zero_grad() last_conv = [module for module in net.modules() if type(module) == torch.nn.Conv2d][-1] guided_gc = GuidedGradCam(net, last_conv) ggc_real = guided_gc.attribute(imgs[0], target=classes[0]) ggc_fake = guided_gc.attribute(imgs[1], target=classes[1]) attrs.append(ggc_real[0,0,:,:]) attrs_names.append("ggc_real") attrs.append(ggc_fake[0,0,:,:]) attrs_names.append("ggc_fake") net.zero_grad() gbp = GuidedBackprop(net) gbp_real = gbp.attribute(imgs[0], target=classes[0]) gbp_fake = gbp.attribute(imgs[1], target=classes[1]) attrs.append(gbp_real[0,0,:,:]) attrs_names.append("gbp_real") attrs.append(gbp_fake[0,0,:,:]) attrs_names.append("gbp_fake") ggc_diff_0 = gbp_real[0,0,:,:] * gc_diff_0 ggc_diff_1 = gbp_fake[0,0,:,:] * gc_diff_1 attrs.append(ggc_diff_0) attrs_names.append("ggc_diff_0") attrs.append(ggc_diff_1) attrs_names.append("ggc_diff_1") # IG if "ig" in methods: baseline = image_to_tensor(np.zeros(input_shape, dtype=np.float32)) net.zero_grad() ig = IntegratedGradients(net) ig_real, delta_real = ig.attribute(imgs[0], baseline, target=classes[0], return_convergence_delta=True) ig_fake, delta_fake = ig.attribute(imgs[1], baseline, target=classes[1], return_convergence_delta=True) ig_diff_0, delta_diff = ig.attribute(imgs[0], imgs[1], target=classes[0], return_convergence_delta=True) ig_diff_1, delta_diff = ig.attribute(imgs[1], imgs[0], target=classes[1], return_convergence_delta=True) attrs.append(ig_real[0,0,:,:]) attrs_names.append("ig_real") attrs.append(ig_fake[0,0,:,:]) attrs_names.append("ig_fake") attrs.append(ig_diff_0[0,0,:,:]) attrs_names.append("ig_diff_0") attrs.append(ig_diff_1[0,0,:,:]) attrs_names.append("ig_diff_1") # DL if "dl" in methods: net.zero_grad() dl = DeepLift(net) dl_real = dl.attribute(imgs[0], target=classes[0]) dl_fake = dl.attribute(imgs[1], target=classes[1]) dl_diff_0 = dl.attribute(imgs[0], baselines=imgs[1], target=classes[0]) dl_diff_1 = dl.attribute(imgs[1], baselines=imgs[0], target=classes[1]) attrs.append(dl_real[0,0,:,:]) attrs_names.append("dl_real") attrs.append(dl_fake[0,0,:,:]) attrs_names.append("dl_fake") attrs.append(dl_diff_0[0,0,:,:]) attrs_names.append("dl_diff_0") attrs.append(dl_diff_1[0,0,:,:]) attrs_names.append("dl_diff_1") # INGRAD if "ingrad" in methods: net.zero_grad() saliency = Saliency(net) grads_real = saliency.attribute(imgs[0], target=classes[0]) grads_fake = saliency.attribute(imgs[1], target=classes[1]) attrs.append(grads_real[0,0,:,:]) attrs_names.append("grads_real") attrs.append(grads_fake[0,0,:,:]) attrs_names.append("grads_fake") net.zero_grad() input_x_gradient = InputXGradient(net) ingrad_real = input_x_gradient.attribute(imgs[0], target=classes[0]) ingrad_fake = input_x_gradient.attribute(imgs[1], target=classes[1]) ingrad_diff_0 = grads_fake * (imgs[0] - imgs[1]) ingrad_diff_1 = grads_real * (imgs[1] - imgs[0]) attrs.append(torch.abs(ingrad_real[0,0,:,:])) attrs_names.append("ingrad_real") attrs.append(torch.abs(ingrad_fake[0,0,:,:])) attrs_names.append("ingrad_fake") attrs.append(torch.abs(ingrad_diff_0[0,0,:,:])) attrs_names.append("ingrad_diff_0") attrs.append(torch.abs(ingrad_diff_1[0,0,:,:])) attrs_names.append("ingrad_diff_1") attrs = [a.detach().cpu().numpy() for a in attrs] attrs_norm = [a/np.max(np.abs(a)) for a in attrs] return attrs_norm, attrs_names
def main(args): warnings.filterwarnings("ignore") device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') print('Executing on device:', device) # --- Get Threshold --- model = './model/base' + str(args.model_index) + '.pkl' threshold, _ = get_threshold(model_dir=model, use_cached=args.use_cached, search_space=np.linspace( 0, 1, args.search_num)) # --- Load Model --- model = torch.load(model, map_location=device).to(device) model = model.eval() # --- Fix Seed --- torch.manual_seed(123) np.random.seed(123) # --- Label --- label_dir = '../CheXpert-v1.0-small/valid.csv' label = pd.read_csv(label_dir) target_label = np.array(list(label.keys())[5:]) target_obsrv = np.array([8, 2, 6, 5, 10]) label = label.values label_gd = label[:, 5:] # --- Image --- img_index = args.image_index img_dir = '../' transform = transforms.Compose([ transforms.Resize(224), transforms.CenterCrop(224), transforms.ToTensor(), ]) print('Patient:', label[img_index][0]) img = Image.open(os.path.join(img_dir, label[img_index][0])).convert('RGB') img = transform(img) img_transformed = img / 255 img_transformed = img_transformed.unsqueeze(0).to(device) # --- Predict --- pred = model(img_transformed) print() print('[Prediction]') print('{:17s}|{:4s}|{:4s}|{:4s}|{:3s}'.format('Pathology', 'Prob', 'Thrs', 'Pred', 'Ans')) for lbl, prd, thrsh, gd in zip(target_label[target_obsrv], pred[0][target_obsrv], threshold[target_obsrv], label_gd[img_index][target_obsrv]): print('{:17s}:{:4.2f} {:4.2f} {:4d} {:3d}'.format( lbl, prd.item(), thrsh, int(prd.item() > thrsh), int(gd))) print() del pred torch.cuda.empty_cache() gc.collect() model = model.to(torch.device('cpu')) img_transformed = img_transformed.to(torch.device('cpu')) # --- Visualization --- pathology_input = input( 'Please enter which pathology to visualize:\n[0]Atelectasis\n[1]Cardiomegaly\n[2]Consolidation\n[3]Edema\n[4]Pleural Effusion\n[5]Exit\n' ) if pathology_input == '0': pathology = 8 print('Diagnosis on Atelectasis') elif pathology_input == '1': pathology = 2 print('Diagnosis on Cardiomegaly') elif pathology_input == '2': pathology = 6 print('Diagnosis on Consolidation') elif pathology_input == '3': pathology = 5 print('Diagnosis on Edema') elif pathology_input == '4': pathology = 10 print('Diagnosis on Pleural Effusion') elif pathology_input == '5': print('Exiting...') return else: raise NotImplementedError('Only 0-5 are valid input values') default_cmap = LinearSegmentedColormap.from_list('custom blue', [(0, '#ffffff'), (0.25, '#000000'), (1, '#000000')], N=256) print() method_input = input( 'Please enter which method to visualize:\n[0]GradientShap\n[1]DeepLift\n[2]Exit\n' ) if method_input == '0': print('Using GradientShap') # --- Gradient Shap --- gradient_shap = GradientShap(model) # === baseline distribution === rand_img_dist = torch.cat([img_transformed * 0, img_transformed * 1]) attributions_gs = gradient_shap.attribute(img_transformed, n_samples=50, stdevs=0.0001, baselines=rand_img_dist, target=pathology) _ = viz.visualize_image_attr_multiple( np.transpose(attributions_gs.squeeze().cpu().detach().numpy(), (1, 2, 0)), np.transpose(img.squeeze().cpu().detach().numpy(), (1, 2, 0)), ["original_image", "heat_map"], ["all", "absolute_value"], cmap=default_cmap, show_colorbar=True) del attributions_gs elif method_input == '1': print('Using DeepLIFT') # --- Deep Lift --- model = model_transform(model) dl = DeepLift(model) attr_dl = dl.attribute(img_transformed, target=pathology, baselines=img_transformed * 0) _ = viz.visualize_image_attr_multiple( np.transpose(attr_dl.squeeze().cpu().detach().numpy(), (1, 2, 0)), np.transpose(img.squeeze().cpu().detach().numpy(), (1, 2, 0)), ["original_image", "heat_map"], ["all", "positive"], cmap=default_cmap, show_colorbar=True) del attr_dl elif method_input == '2': print('Exiting...') return else: raise NotImplementedError('Only 0-2 are valid input values') """ elif method_input == '2': print('Using Integrated Gradients') # --- Integrated Gradients --- integrated_gradients = IntegratedGradients(model) attributions_ig = integrated_gradients.attribute(img_transformed, target=pathology, n_steps=200) _ = viz.visualize_image_attr_multiple(np.transpose(attributions_ig.squeeze().cpu().detach().numpy(), (1,2,0)), np.transpose(img.squeeze().cpu().detach().numpy(), (1,2,0)), method=["original_image", "heat_map"], cmap=default_cmap, show_colorbar=True, sign=["all", "positive"]) del attributions_ig elif method_input == '3': print('Using Noise Tunnel') # --- Noise Tunnel --- integrated_gradients = IntegratedGradients(model) noise_tunnel = NoiseTunnel(integrated_gradients) attributions_ig_nt = noise_tunnel.attribute(img_transformed, n_samples=10, nt_type='smoothgrad_sq', target=pathology) _ = viz.visualize_image_attr_multiple(np.transpose(attributions_ig_nt.squeeze().cpu().detach().numpy(), (1,2,0)), np.transpose(img.squeeze().cpu().detach().numpy(), (1,2,0)), ["original_image", "heat_map"], ["all", "positive"], cmap=default_cmap, show_colorbar=True) del attributions_ig_nt """ gc.collect() return
def generate_saliency(model_path, saliency_path, saliency, aggregation): checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage) model_args = Namespace(**checkpoint['args']) if args.model == 'lstm': model = LSTM_MODEL(tokenizer, model_args, n_labels=checkpoint['args']['labels']).to(device) model.load_state_dict(checkpoint['model']) elif args.model == 'trans': transformer_config = BertConfig.from_pretrained( 'bert-base-uncased', num_labels=model_args.labels) model_cp = BertForSequenceClassification.from_pretrained( 'bert-base-uncased', config=transformer_config).to(device) checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage) model_cp.load_state_dict(checkpoint['model']) model = BertModelWrapper(model_cp) else: model = CNN_MODEL(tokenizer, model_args, n_labels=checkpoint['args']['labels']).to(device) model.load_state_dict(checkpoint['model']) model.train() pad_to_max = False if saliency == 'deeplift': ablator = DeepLift(model) elif saliency == 'guided': ablator = GuidedBackprop(model) elif saliency == 'sal': ablator = Saliency(model) elif saliency == 'inputx': ablator = InputXGradient(model) elif saliency == 'occlusion': ablator = Occlusion(model) coll_call = get_collate_fn(dataset=args.dataset, model=args.model) return_attention_masks = args.model == 'trans' collate_fn = partial(coll_call, tokenizer=tokenizer, device=device, return_attention_masks=return_attention_masks, pad_to_max_length=pad_to_max) test = get_dataset(path=args.dataset_dir, mode=args.split, dataset=args.dataset) batch_size = args.batch_size if args.batch_size != None else \ model_args.batch_size test_dl = DataLoader(batch_size=batch_size, dataset=test, shuffle=False, collate_fn=collate_fn) # PREDICTIONS predictions_path = model_path + '.predictions' if not os.path.exists(predictions_path): predictions = defaultdict(lambda: []) for batch in tqdm(test_dl, desc='Running test prediction... '): if args.model == 'trans': logits = model(batch[0], attention_mask=batch[1], labels=batch[2].long()) else: logits = model(batch[0]) logits = logits.detach().cpu().numpy().tolist() predicted = np.argmax(np.array(logits), axis=-1) predictions['class'] += predicted.tolist() predictions['logits'] += logits with open(predictions_path, 'w') as out: json.dump(predictions, out) # COMPUTE SALIENCY if saliency != 'occlusion': embedding_layer_name = 'model.bert.embeddings' if args.model == \ 'trans' else \ 'embedding' interpretable_embedding = configure_interpretable_embedding_layer( model, embedding_layer_name) class_attr_list = defaultdict(lambda: []) token_ids = [] saliency_flops = [] for batch in tqdm(test_dl, desc='Running Saliency Generation...'): if args.model == 'cnn': additional = None elif args.model == 'trans': additional = (batch[1], batch[2]) else: additional = batch[-1] token_ids += batch[0].detach().cpu().numpy().tolist() if saliency != 'occlusion': input_embeddings = interpretable_embedding.indices_to_embeddings( batch[0]) if not args.no_time: high.start_counters([ events.PAPI_FP_OPS, ]) for cls_ in range(checkpoint['args']['labels']): if saliency == 'occlusion': attributions = ablator.attribute( batch[0], sliding_window_shapes=(args.sw, ), target=cls_, additional_forward_args=additional) else: attributions = ablator.attribute( input_embeddings, target=cls_, additional_forward_args=additional) attributions = summarize_attributions( attributions, type=aggregation, model=model, tokens=batch[0]).detach().cpu().numpy().tolist() class_attr_list[cls_] += [[_li for _li in _l] for _l in attributions] if not args.no_time: saliency_flops.append( sum(high.stop_counters()) / batch[0].shape[0]) if saliency != 'occlusion': remove_interpretable_embedding_layer(model, interpretable_embedding) # SERIALIZE print('Serializing...', flush=True) with open(saliency_path, 'w') as out: for instance_i, _ in enumerate(test): saliencies = [] for token_i, token_id in enumerate(token_ids[instance_i]): token_sal = {'token': tokenizer.ids_to_tokens[token_id]} for cls_ in range(checkpoint['args']['labels']): token_sal[int( cls_)] = class_attr_list[cls_][instance_i][token_i] saliencies.append(token_sal) out.write(json.dumps({'tokens': saliencies}) + '\n') out.flush() return saliency_flops
# Occlusion occlusion = Occlusion(model) grads = occlusion.attribute(x, strides = (1, int(FS / 100)), target=labels[idx].item(), sliding_window_shapes=(1, int(FS / 10)), baselines=0) grads_occ.append(grads.squeeze().cpu().detach().numpy()) # Integrated Gradients integrated_gradients = IntegratedGradients(model) grads = integrated_gradients.attribute(x, target=labels[idx].item(), n_steps=1000) grads_igrad.append(grads.squeeze().cpu().detach().numpy()) # Gradient SHAP gshap = GradientShap(model) baseline_dist = torch.cat([x*0, x*1]) grads = gshap.attribute(x, n_samples=10, stdevs=0.1, baselines=baseline_dist, target=labels[idx].item()) grads_gshap.append(grads.squeeze().cpu().detach().numpy()) # DeepLIFT dlift = DeepLift(model) grads = dlift.attribute(x, x*0, target=labels[idx].item()) grads_dlift.append(grads.squeeze().cpu().detach().numpy()) signal.append(x.squeeze().cpu().detach().numpy()) with open(os.path.join('results', 'interp_' + os.path.basename(MODEL) + '.pk'), 'wb') as hf: pk.dump({'x': signal, 'sal': grads_sal, 'occ': grads_occ, 'igrad': grads_igrad, 'gshap': grads_gshap, 'dlift': grads_dlift}, hf)
def test(cnn, valid_data, valid_loader, learning_file): cnn.to("cpu") cnn.eval() #correct = 0 #prediction_positive = 0 ''' my_array = np.array(valid_data.data.values).astype(float) print(type(my_array)) my_tensor = torch.tensor(my_array) valid_x = torch.unsqueeze(my_tensor, dim = 1).type(torch.FloatTensor) valid_y = valid_data.labels.numpy() y_pre = cnn(valid_x) _,pre_index = torch.max(y_pre, 1) pre_index = pre_index.view(-1) prediction = pre_index.numpy() tp,fp,tn,fn, p,recall,F1,acc = Evaluate(prediction,valid_y) logger.info( "TP:{:d},FP:{:d},TN:{:d},FN:{:d}".format(tp,fp,tn,fn)) logger.info( "precision:{:.2f},recall:{:.2f},F1:{:.2f},accuracy:{:.2f}".format(p,recall,F1,acc)) ''' precite = np.array([]) expected = np.array([]) attr_score = np.empty([40, 4], dtype=np.float64) #ig = IntegratedGradients(cnn) dl = DeepLift(cnn) #t1 = time() for i, data in enumerate(valid_loader): # forward inputs, labels = data inputs = torch.unsqueeze(inputs, dim=1).type(torch.FloatTensor) inputs = inputs #.to(device) labels = labels #.to(device) # for IntegratedGradients #baseline = torch.zeros(inputs.shape)#.to(device) baseline_np = np.array([[[0.3, 0.2, 0.2, 0.3]] * 40] * inputs.shape[0]) baseline = torch.from_numpy(baseline_np) baseline = torch.unsqueeze(baseline, dim=1).type(torch.FloatTensor) attributions, delta = dl.attribute( inputs, baseline, target=0, return_convergence_delta=True) #.to(device) #logger.info('IG Attributions:' + str(attributions)) #logger.info('Convergence Delta:' + str(delta)) outputs = cnn(inputs) attr_score += genScore(attributions) #print('echo test:',i,time()-t1) _, pre_index = torch.max(outputs.data, 1) pre_index = pre_index.view(-1) prediction = pre_index.numpy() labels = labels.numpy() precite = np.concatenate((precite, prediction)) expected = np.concatenate((expected, labels)) #prediction_positive += np.sum(prediction) #correct += np.sum(prediction == labels) attr_score_sum = np.sum(attr_score, axis=1) attr_score = avgScore(attr_score, attr_score_sum) np.save( ATTR_PATH + 'attributions_Rep1_' + learning_file.split('_')[0][:-4] + '.npy', attr_score) cnn.to("cpu") tp, fp, tn, fn, p, recall, F1, acc, mcc = Evaluate(precite, expected) ''' logger.info( "TP:{:d},FP:{:d},TN:{:d},FN:{:d}".format(tp,fp,tn,fn)) logger.info( "precision:{:.2f},recall:{:.2f},F1:{:.2f},accuracy:{:.2f}".format(p,recall,F1,acc)) logger.info( "MCC:{:.2f}".format(mcc) ) ''' logger.info("TP:" + str(tp)) logger.info("FP:" + str(fp)) logger.info("TN:" + str(tn)) logger.info("FN:" + str(fn)) logger.info("Precision:{:.4f}".format(p)) logger.info("Recall:{:.4f}".format(recall)) logger.info("F1:{:.4f}".format(F1)) logger.info("Accuracy:{:.4f}".format(acc)) logger.info("MCC:{:.4f}".format(mcc)) #test_accuracy = correct / len(valid_data) #print("Test accuracy: ", test_accuracy ) #logger.info( "Predicted positive: " + str( prediction_positive ) ) #logger.info( "Test accuracy: " + str( test_accuracy ) ) return tp, fp, tn, fn