def test_integrated_gradients_binary_classification_single_output_multi_inputs( ffn_model_multi_inputs, method, baselines): model = ffn_model_multi_inputs ig = IntegratedGradients(model, n_steps=50, method=method) explanations = ig.explain(X_test_multi_inputs, baselines=baselines, target=test_labels) assert isinstance(explanations, Explanation) assert max([len(x) for x in X_test_multi_inputs ]) == min([len(x) for x in X_test_multi_inputs]) assert (max([len(x) for x in explanations['data']['attributions']]) == min( [len(x) for x in explanations['data']['attributions']])) assert len(explanations['data']['attributions'][0]) == N_TEST assert len(X_test_multi_inputs[0]) == N_TEST attrs = explanations['data']['attributions'] for i in range(len(attrs)): assert attrs[i].shape == X_test_multi_inputs[i].shape assert 'deltas' in explanations['data'].keys() assert explanations['data']['deltas'].shape[0] == N_TEST assert 'predictions' in explanations['data'].keys() assert explanations['data']['predictions'].shape[0] == N_TEST
def integrated_gradients(self, on="test"): data_select = { "test": self.netdata.test, "train": self.netdata.train, "valid": self.netdata.valid } dataset = data_select.get(on) explainer = IntegratedGradients(self.model, layer=None, method="gausslegendre", n_steps=50, internal_batch_size=10000) explanation = explainer.explain(dataset.data["features"]) attributions = explanation.attributions loc = pd.DataFrame( attributions, columns=dataset.columns["features"], index=dataset.index) # We need to take absolute value so that features that have both positive # and negative impact do not seem unimportant glob = pd.DataFrame(loc.abs().mean(), columns=[self.__repr__()]).transpose() return loc, glob
def fit(self, x, y): self.dim = x.shape[1] x = min_max_normalize(x) # x = z_score_normalize(x) y_oh = to_categorical(y, 2) clf = self.nn_model() clf.fit(x, y_oh, batch_size=self.clf_batch_size, epochs=self.clf_epochs, verbose=1) y_pred = clf(x).numpy().argmax(axis=1) print("Clf model accuracy: [{:.4f}]".format( sklearn.metrics.accuracy_score(y, y_pred))) # Initialize IntegratedGradients instance ig = IntegratedGradients(clf, n_steps=self.n_steps, method=self.method) # Calculate attributions for the first 10 images in the test set self.ano_idx = np.where(y == 1)[0] x_ano = x[self.ano_idx] # predictions = clf(x_ano).numpy().argmax(axis=1) predictions = np.ones(len(self.ano_idx), dtype=int) self.nor_idx = np.where(y == 0)[0] x_nor = x[self.nor_idx] x_nor_avg = np.average(x_nor, axis=0) baselines = np.array([x_nor_avg] * len(self.ano_idx)) explanation = ig.explain(x_ano, baselines=baselines, target=predictions) fea_weight_lst = explanation.data['attributions'] return fea_weight_lst
def test_integrated_gradients_binary_classification_multi_layer_subclassed( ffn_model_subclass, method, baselines): model = ffn_model_subclass layer = [model.layers[0], model.layers[1]] ig = IntegratedGradients(model, layer=layer, n_steps=50, method=method) explanations = ig.explain(X_test, baselines=baselines, target=test_labels) assert isinstance(explanations, Explanation)
def test_integrated_gradients_regression(ffn_model, method, baselines): model = ffn_model ig = IntegratedGradients(model, n_steps=50, method=method) explanations = ig.explain(X_test, baselines=baselines, target=None) assert isinstance(explanations, Explanation) assert explanations['data']['attributions'][0].shape == X_test.shape assert 'deltas' in explanations['data'].keys() assert explanations['data']['deltas'].shape[0] == X_test.shape[0] assert 'predictions' in explanations['data'].keys() assert explanations['data']['predictions'].shape[0] == X_test.shape[0]
def test_integrated_gradients_binary_classification_single_output_squash_output( ffn_model, method, baselines): model = ffn_model ig = IntegratedGradients(model, n_steps=50, method=method) explanations = ig.explain(X_test, baselines=baselines, target=test_labels) assert isinstance(explanations, Explanation) assert explanations['data']['attributions'][0].shape == X_test.shape assert 'deltas' in explanations['data'].keys() assert explanations['data']['deltas'].shape[0] == X_test.shape[0] assert 'predictions' in explanations['data'].keys() assert explanations['data']['predictions'].shape[0] == X_test.shape[0]
def test_integrated_gradients_binary_classification_layer( ffn_model, method, layer_nb, baselines): model = ffn_model if layer_nb is not None: layer = model.layers[layer_nb] else: layer = None ig = IntegratedGradients(model, layer=layer, n_steps=50, method=method) explanations = ig.explain(X_test, baselines=baselines, target=test_labels) assert isinstance(explanations, Explanation) if layer is not None: layer_out = layer(X_test).numpy() assert explanations['data']['attributions'][0].shape == layer_out.shape else: assert explanations['data']['attributions'][0].shape == X_test.shape assert 'deltas' in explanations['data'].keys() assert explanations['data']['deltas'].shape[0] == X_test.shape[0] assert 'predictions' in explanations['data'].keys() assert explanations['data']['predictions'].shape[0] == X_test.shape[0]
def showIntegratedGradients(model, img, origimg): n_steps = 50 i = 0 method = "gausslegendre" internal_batch_size = 50 ig = IntegratedGradients(model, n_steps=n_steps, method=method, internal_batch_size=internal_batch_size) #st.write(img.shape) data = img data = (data / 255).astype('float32') predictions = model(data).numpy().argmax(axis=1) explanation = ig.explain(img, baselines=None, target=predictions) # Get attributions values from the explanation object attrs = explanation.attributions st.header("Integrated Gradient Interpretation") st.subheader("Black image baseline") fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(10, 5)) visualize_image_attr(attr=None, original_image=origimg, method='original_image', title='Original Image', plt_fig_axis=(fig, ax[0]), use_pyplot=False) visualize_image_attr(attr=attrs[i], original_image=data[i], method='blended_heat_map', sign='all', show_colorbar=True, title='Attributions', plt_fig_axis=(fig, ax[1]), use_pyplot=True) visualize_image_attr(attr=attrs[0], original_image=img[0], method='blended_heat_map', sign='all', show_colorbar=True, title='Overlaid Attributions', plt_fig_axis=(fig, ax[2]), use_pyplot=True) st.pyplot() st.subheader("Random baselines") baselines = np.random.random_sample(data.shape) explanation = ig.explain(data, baselines=baselines, target=predictions) attrs = explanation.attributions fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(10, 5)) visualize_image_attr(attr=None, original_image=origimg, method='original_image', title='Original Image', plt_fig_axis=(fig, ax[0]), use_pyplot=False) visualize_image_attr(attr=attrs[i], original_image=data[i], method='blended_heat_map', sign='all', show_colorbar=True, title='Attributions', plt_fig_axis=(fig, ax[1]), use_pyplot=True) visualize_image_attr(attr=attrs[i], original_image=origimg, method='blended_heat_map', sign='all', show_colorbar=True, title='Overlaid Attributions', plt_fig_axis=(fig, ax[2]), use_pyplot=True) st.pyplot()