def test_multiple_inputs_error(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X1, X2, out = simple_multi_inputs_model(self.session) xi = [np.array([[-10, -5]]), np.array([[3, 1]])] with self.assertRaises(RuntimeError) as cm: de.explain('occlusion', out, [X1, X2], xi) self.assertIn('not yet supported', str(cm.exception))
def calculateAttributions(self, xs, method, mode, model_path, pos=None): with DeepExplain(session=K.get_session()) as de: model = load_model(model_path) flat = Reshape(target_shape=(256 * 256, ))(model.layers[-1].output) flat_model = Model(model.layers[0].input, flat) input_tensor = flat_model.layers[0].input target_tensor = flat_model(input_tensor) xs = xs[np.newaxis, ..., np.newaxis] if mode == 'Select Pixel' and pos != None: x, y = int(pos.x()), int(pos.y()) idx = x * 256 + y ys = np.zeros(256**2) ys[idx] = 1 elif mode == 'Black Mask': ys = 1 - self._mask.flatten() elif mode == 'White Mask': ys = self._mask.flatten() elif mode == 'Full Image': ys = np.ones(256**2) ys = ys[np.newaxis, ...] attributions = de.explain(method, target_tensor, input_tensor, xs, ys) K.clear_session() return attributions
def test_invalid_method(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: with self.assertRaises(RuntimeError) as cm: de.explain('invalid', None, None, None) self.assertIn('Method must be in', str(cm.exception) )
def test_window_shape(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model(self.session) xi = np.array([[-10, -5], [3, 1]]) attributions = de.explain('occlusion', out, X, xi, window_shape=(2,)) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions, [[0.0, 0.0], [0.5, 0.5]], 10)
def _run_deepexplain_single_cv(self, cv_dir, gene_name): ckpt = tf.train.get_checkpoint_state(checkpoint_dir=cv_dir) placeholders = { 'support': [tf.placeholder(tf.float32, shape=self.support[i].shape) for i in range(len(self.support))], 'features': tf.placeholder(tf.float32, shape=self.features.shape), 'labels': tf.placeholder(tf.float32, shape=(None, self.y_train.shape[1])), 'labels_mask': tf.placeholder(tf.int32, shape=self.train_mask.shape), 'dropout': tf.placeholder_with_default(0., shape=()), 'num_features_nonzero': tf.placeholder(tf.int32, shape=()) } with tf.Session() as sess: with DeepExplain(session=sess) as de: model = EMOGI(placeholders=placeholders, input_dim=self.features.shape[1], learning_rate=self.params['lr'], weight_decay=self.params['decay'], num_hidden_layers=len(self.params['hidden_dims']), hidden_dims=self.params['hidden_dims'], pos_loss_multiplier=self.params['loss_mul'], logging=False, sparse_network=False, name='emogi' # 'mygcn' for compatibility with older models ) model.load(ckpt.model_checkpoint_path, sess) idx_gene = self.node_names.index(gene_name) mask_gene = np.zeros((self.features.shape[0], 1)) mask_gene[idx_gene] = 1 attributions = de.explain(method="elrp", T=tf.nn.sigmoid(model.outputs), X=[placeholders['features'], *placeholders["support"]], xs=[self.features, *self.support], ys=mask_gene) tf.reset_default_graph() return attributions
def test_elrp_zero_epsilon(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model(self.session) xi = np.array([[-10, -5], [3, 1]]) with self.assertRaises(AssertionError): de.explain('elrp', out, X, xi, epsilon=0)
def run_de(self, dataset): ''' Runs method from deepexplain library ''' self.de_methods = { "Gradient_Inputs": "grad*input", "Saliency": "saliency", "Integrated_Gradients": "intgrad", # "DeepLIFT": "deeplift", "e-LRP": "elrp", "Occlusion": "occlusion" } de_results = dict() with DeepExplain(session=K.get_session()) as de: # Model should be loaded under the de scope model = get_model(self.model_path, rec = True, max_value=self.max_loss_value) input_tensor = model.layers[0].input de_model = Model(inputs=input_tensor, outputs = model.layers[self.de_output_layer].output) target_tensor = de_model(input_tensor) for method_name, method_tag in self.de_methods.items(): if self.debug: print(method_name) try: attributions = de.explain(method_tag, target_tensor, input_tensor, dataset, ys=dataset, batch_size = self.batch_size) # np.expand_dims(y_test, axis = -1)) except Exception as e: print("%s failed"%(method_name)) if self.debug: print("ERROR: %s"%(e)) continue de_results[method_name] = attributions return de_results
def create_explanations(model, x_data, y_data): with DeepExplain(session=backend.get_session()) as de: input_tensor = model.layers[0].input fModel = Model(inputs=input_tensor, outputs=model.layers[-2].output) target_tensor = fModel(input_tensor) attributions = dict() explanation_keys = [('Sensitivity', 'saliency'), ('Gradient*Input', 'grad*input'), ('epsilon-LRP', 'elrp'), ('Occlusion', 'occlusion'), ('IntegratedGradients', 'intgrad')] for key1, key2 in explanation_keys: if key1 == 'Occlusion': attributions[key1] = de.explain(key2, target_tensor, input_tensor, xs=x_data, ys=y_data, window_shape=(3, 300)) else: attributions[key1] = de.explain(key2, target_tensor, input_tensor, xs=x_data, ys=y_data) attributions_summed = dict() for key in attributions.keys(): attributions_summed[key] = np.sum(attributions[key], axis=2) return attributions, attributions_summed
def test_override_as_default(self): """ In DeepExplain context, nonlinearities behave as default, including training time """ with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: r = train_xor(self.session) self.assertTrue(r)
def explain_image(self, model, data, labels): with DeepExplain(session=K.get_session()) as de: model_wo_sm = iutils.keras.graph.model_wo_softmax(model) input_tensor = model_wo_sm.layers[0].input output_tensor = model_wo_sm.layers[-1].output fModel = keras.models.Model(inputs=input_tensor, outputs=output_tensor) target_tensor = fModel(input_tensor) attributions = de.explain('occlusion', target_tensor * labels, input_tensor, data, window_shape=self.window_shape, step=self.step) attributions = np.nan_to_num(attributions) analysis = attributions analysis = iutils.postprocess_images(analysis, color_coding='BGRtoRGB', channels_first=False) analysis = ivis.gamma(analysis, minamp=0, gamma=0.95) analysis = ivis.heatmap(analysis) return analysis[0]
def test_dummy_zero(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simple_model(tf.nn.sigmoid, self.session) xi = np.array([[10, -10]]) attributions = de.explain('zero', out, X, xi) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions[0], [0.0, 0.0], 10)
def test_deeplift_baseline(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model(self.session) xi = np.array([[3, 1]]) attributions = de.explain('deeplift', out, X, xi, baseline=xi[0]) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions, [[0.0, 0.0]], 5)
def test_elrp_epsilon(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model( self.session) xi = np.array([[-10, -5], [3, 1]]) attributions = de.explain('elrp', out, X, xi, epsilon=1e-9) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions, [[0.0, 0.0], [3.0, -1.0]], 7)
def test_int_grad(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model( self.session) xi = np.array([[-10, -5], [3, 1]]) attributions = de.explain('intgrad', out, X, xi) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions, [[0.0, 0.0], [1.5, -0.5]], 1)
def test_saliency_method(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model(self.session) xi = np.array([[-10, -5], [3, 1]]) attributions = de.explain('grad*input', out, X, xi) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions, [[0.0, 0.0], [3.0, -1.0]], 10)
def test_gradient_restored(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simple_model(tf.nn.sigmoid, self.session) xi = np.array([[10, -10]]) de.explain('zero', out, X, xi) r = train_xor(self.session) self.assertTrue(r)
def test_shapley_targeting_equivalence(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simple_model(tf.identity, self.session) xi = np.array([[5, 3]]) self.assertEqual(out.shape[1], 2) np.random.seed(10) a1 = de.explain('shapley_sampling', out * np.array([[1, 0]]), X, xi, samples=10) np.random.seed(10) b1 = de.explain('shapley_sampling', out * np.array([[0, 1]]), X, xi, samples=10) np.random.seed(10) a2 = de.explain('shapley_sampling', out, X, xi, ys=np.array([[1, 0]]), samples=10) np.random.seed(10) b2 = de.explain('shapley_sampling', out, X, xi, ys=np.array([[0, 1]]), samples=10) np.testing.assert_almost_equal(a1, a2, 3) np.testing.assert_almost_equal(b1, b2, 3)
def make_figure(name, name_seq, name_ss, min_range, max_range): ohe_name = prepare_ohe( np.vstack([[i for i in name_seq[min_range:max_range]], [i for i in name_ss[min_range:max_range]]])) with DeepExplain(session=K.get_session()) as de: input_tensor = ADPred.layers[0].input fModel = Model(inputs=input_tensor, outputs=ADPred.layers[-2].output) target_tensor = fModel(input_tensor) xs = ohe_name.reshape(1, 30, 23, 1) ys = np.array([1]).reshape(1, 1) #attributions_dl = de.explain('grad*input', target_tensor, input_tensor, xs, ys=ys) #attributions_dl = de.explain('shapley_sampling', target_tensor, input_tensor, xs, ys=ys) #attributions_dl = de.explain('deeplift', target_tensor, input_tensor, xs, ys=ys) attributions_dl = de.explain('intgrad', target_tensor, input_tensor, xs, ys=ys) #for name, j in zip(['_grad_int_','_shapley_vals_','_saliency_'],[attributions_gi, attributions_sv,attributions_s]): for i in range(len(attributions_dl)): ALL_SCORES1, aSS1 = ohe_2_aa_analog(attributions_dl[i]) fig = draw_logo2(ALL_SCORES1, name + '_AA.png', 'Verdana', COLOR_SCHEME=COLOR_SCHEME_AA) #draw_logo2(aSS1, name+'gcn4_SS.png', 'Verdana', COLOR_SCHEME=COLOR_SCHEME_SS) return fig
def test_all_in_X_are_tensor(self): X = tf.placeholder("float", [None, 3]) Y = tf.nn.relu(X) with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: with self.assertRaises(RuntimeError) as cm: de.explain('grad*input', Y, [X, np.eye(3)], [[0, 0, 0]]) self.assertIn('Tensorflow Tensor object', str(cm.exception))
def test_multiple_inputs_different_sizes(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X1, X2, out = simple_multi_inputs_model2(self.session) xi = [np.array([[-10, -5]]), np.array([[3]])] attributions = de.explain('deeplift', out, [X1, X2], xi) self.assertEqual(len(attributions), len(xi)) np.testing.assert_almost_equal(attributions[0], [[0.0, 0.0]], 10) np.testing.assert_almost_equal(attributions[1], [[12]], 10)
def test_multiple_inputs(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X1, X2, out = simple_multi_inputs_model(self.session) xi = [np.array([[-10, -5]]), np.array([[3, 1]])] attributions = de.explain('elrp', out, [X1, X2], xi, epsilon=1e-9) self.assertEqual(len(attributions), len(xi)) np.testing.assert_almost_equal(attributions[0], [[0.0, 0.0]], 7) np.testing.assert_almost_equal(attributions[1], [[6.0, 2.0]], 7)
def test_gradient_was_not_overridden(self): X = tf.placeholder("float", [None, 3]) Y = tf.nn.relu(X) with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") de.explain('grad*input', Y, X, [[0, 0, 0]]) assert any(["DeepExplain detected you are trying" in str(wi.message) for wi in w])
def get_attribution_score(input_text, label, model_): ''' computes attribution score for provided text given the prediction model param input_text: user provided text type input_text: str param label: predicted label type label: list of prediction label for e.g., [1 0 1 1 1 1 1 0] param model_: prediction deep learning model type model_: keras Model class returns: feature (word) and its corresponding importance for prediction label rtype: list, list ''' current_session = K.get_session() # DeepExplain context with DeepExplain(session=current_session) as de: input_tensor = model_.layers[1].input # embedding layer output vector embedding = model_.layers[1].output # preprocessing: removal of stop words and punctuations sequences = tokenizer.texts_to_sequences( [stem_sentences(remove_stop_word_punctuation(input_text))]) # pad the sequence to a max_seq_length x_interpret = pad_sequences(sequences, maxlen=model_.MAX_SEQ_LENGTH, padding='pre', truncating='pre') # perform lookup get_embedding_output = K.function([input_tensor], [embedding]) embedding_out = get_embedding_output([x_interpret])[0] # attribution using integrated gradient attributions = de.explain('intgrad', model_.layers[-2].output * label, embedding, embedding_out) values = np.array((np.sum(attributions, -1))) words = [] values_set = [] index_word = {v: k for k, v in tokenizer.word_index.items()} # map back for k in range(len(x_interpret[0])): word = index_word.get(x_interpret[0][k]) words.append(word) values_set.append(values[0][k]) return words, values_set
def test_X_has_compatible_batch_dim(self): X = tf.placeholder("float", [10, 3]) Y = tf.nn.relu(X) with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: with self.assertRaises(RuntimeError) as cm: de.explain('grad*input', Y, X, [[0, 0, 0]], batch_size=2) self.assertIn('the first dimension of the input tensor', str(cm.exception))
def test_explain_not_in_context(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: pass with self.assertRaises(RuntimeError) as cm: de.explain('grad*input', None, None, None) self.assertEqual( 'Explain can be called only within a DeepExplain context.', str(cm.exception))
def test_occlusion_batches(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model(self.session) xi = np.array([[-10, -5], [3, 1]]).repeat(10, 0) attributions = de.explain('occlusion', out, X, xi, batch_size=5) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal( attributions, np.repeat([[0.0, 0.0], [1.0, -1.0]], 10, 0), 10)
def test_T_is_tensor(self): X = tf.placeholder("float", [None, 3]) Y = tf.nn.relu(X) with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: with self.assertRaises(RuntimeError) as cm: de.explain('grad*input', [Y], X, [[0, 0, 0]]) self.assertIn('T must be a Tensorflow Tensor object', str(cm.exception))
def test_warning_unsupported_activations(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X = tf.placeholder("float", [None, 3]) Y = tf.nn.relu6(X) # < an unsupported activation xi = [[-1, 0, 1]] de.explain('elrp', Y, X, xi) assert any(["unsupported activation" in str(wi.message) for wi in w])
def test_multiple_inputs_explainer_api(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X1, X2, out = simple_multi_inputs_model(self.session) xi = [np.array([[-10, -5]]), np.array([[3, 1]])] explainer = de.get_explainer('saliency', out, [X1, X2]) attributions = explainer.run(xi) self.assertEqual(len(attributions), len(xi)) np.testing.assert_almost_equal(attributions[0], [[0.0, 0.0]], 10) np.testing.assert_almost_equal(attributions[1], [[2.0, 2.0]], 10)
def test_occlusion_explainer_api(self): with DeepExplain(graph=tf.get_default_graph(), session=self.session) as de: X, out = simpler_model(self.session) xi = np.array([[-10, -5], [3, 1]]) explainer = de.get_explainer('occlusion', out, X) attributions = explainer.run(xi) self.assertEqual(attributions.shape, xi.shape) np.testing.assert_almost_equal(attributions, [[0.0, 0.0], [1.0, -1.0]], 10)