def compute_all_am_shap(img, model, attr_class, layers, flag1, flag_read_attr=True, iter_num=2**8, labels=None, save_directory=None): """ Using sampling based Shapley method to compute feature attributions Return all attributions and AM not just positive or negative ones """ with tf.Graph().as_default(), tf.Session() as sess, gradient_override_map( {}): # img = tf.image.resize_image_with_crop_or_pad(img, model.image_shape[0], model.image_shape[0]) # imgnp = sess.run(img) # imgnp = imgnp.reshape(224, 224, 3) # plt.imsave("./doghead224.jpeg", imgnp) t_input = tf.placeholder_with_default(img, [None, None, 3]) T = render.import_model(model, t_input, t_input) # grads_cam_T = [T(layer) for layer in layers] # logit = T("softmax2_pre_activation")[0] # score = T("output2")[0, labels.index(attr_class)] logit = T("softmax2_pre_activation")[0] AM_T = list(range(len(layers))) channel_attr_list = list(range(len(layers))) ori_logit = logit.eval() y_label = np.zeros_like(ori_logit) y_label[labels.index(attr_class)] = 1 # index_class_logit = ori_logit[labels.index(attr_class)] # detected_label_index = ori_logit.argmax() # print("detected label index: {}, real label index: {}, label name: {}" # .format(detected_label_index, labels.index(attr_class), attr_class)) for i_wanted_layer in range(len(layers)): layer = layers[i_wanted_layer] acts = T(layer).eval() acts_shape = list(acts.shape) # part_name = "import/{}:0".format(layer) # t_part_input = tf.placeholder(acts.dtype, acts_shape) # T_part = import_part_model(model, t_part_input, part_name) # part_logit = T_part("softmax2_pre_activation")[0] n_features = acts.shape[-1] if not flag_read_attr: result = np.zeros((1, n_features)) run_shape = acts_shape.copy() # run_shape = np.delete(run_shape, -1).tolist() # run_shape.insert(-1, -1) reconstruction_shape = [1, acts_shape[-1]] for r in range(iter_num): p = np.random.permutation(n_features) x = acts.copy().reshape(run_shape) y = None for i in p: if y is None: y = logit.eval({T(layer): x}) # y = model.predict(x.reshape(acts_shape)) x[..., i] = 0 y0 = logit.eval({T(layer): x}) # print("Ori logit score: {}, new logit score: {}" # .format(index_class_logit, y0[labels.index(attr_class)])) # y0 = model.predict(x.reshape(acts_shape)) assert y0.shape == y_label.shape, y0.shape prediction_delta = np.sum((y - y0) * y_label) result[:, i] += prediction_delta y = y0 attr = np.squeeze( (result.copy() / iter_num).reshape(reconstruction_shape).astype( np.float32)) np.savetxt( save_directory + "/{}_{}_{}.txt".format(flag1, layer, attr_class), attr) else: attr = np.loadtxt( save_directory + "/{}_{}_{}.txt".format(flag1, layer, attr_class)).astype( np.float32) acts_squeeze = np.squeeze(acts) attr_temp = np.squeeze(attr).astype(np.float32) channel_attr_list[i_wanted_layer] = attr_temp AM_T[i_wanted_layer] = acts_squeeze AM_list = AM_T logit_list = sess.run([logit])[0] return AM_list, logit_list, channel_attr_list
def compute_igsg(img, model, attr_class, layers, flag1, flag_read_attr=True, iter_num=100, SG_path=False, labels=None, save_directory=None): """ Using Aumann Shapley values as feature attributions """ with tf.Graph().as_default(), tf.Session() as sess, gradient_override_map( {}): # img = tf.image.resize_image_with_crop_or_pad(img, model.image_shape[0], model.image_shape[0]) # imgnp = sess.run(img) # imgnp = imgnp.reshape(224, 224, 3) # plt.imsave("./doghead224.jpeg", imgnp) t_input = tf.placeholder_with_default(img, [None, None, 3]) T = render.import_model(model, t_input, t_input) # grads_cam_T = [T(layer) for layer in layers] # logit = T("softmax2_pre_activation")[0] # logit = T("output2")[0] # score = T("output2")[0, labels.index(attr_class)] logit = T("softmax2_pre_activation")[0] logit4grad = T("softmax2_pre_activation")[0, labels.index(attr_class)] AM_T = list(range(len(layers))) AM_T_reverse = list(range(len(layers))) channel_attr_list = list(range(len(layers))) kept_channel_list = list(range(len(layers))) kept_channel_list_reverse = list(range(len(layers))) for i_wanted_layer in range(len(layers)): layer = layers[i_wanted_layer] acts = T(layer).eval() attr = np.zeros(acts.shape[1:]) t_grad = tf.gradients([logit4grad], [T(layer)])[0] if not flag_read_attr: for n in range(iter_num): acts_ = acts * float(n) / iter_num if SG_path: acts_ *= (np.random.uniform(0, 1, [528]) + np.random.uniform(0, 1, [528])) / 1.5 grad = t_grad.eval({T(layer): acts_}) attr += grad[0] attr = attr * (1.0 / iter_num) * acts[0] attr = np.sum(np.sum(attr, 0), 0) np.savetxt( save_directory + "/{}_{}_{}.txt".format(flag1, layer, attr_class), attr) else: attr = np.loadtxt( save_directory + "/{}_{}_{}.txt".format(flag1, layer, attr_class)).astype( np.float32) # AM_T[i_wanted_layer] = attr * (attr > 0) kept_channel_idx = np.squeeze( np.argwhere( attr > np.nanmean(np.where(attr > 0, attr, np.nan)))) acts_squeeze = np.squeeze(acts) attr_temp = np.squeeze(attr).astype(np.float32) # print(np.count_nonzero(clear_channel_idx)) channel_attr_list[i_wanted_layer] = attr_temp AM_T[i_wanted_layer] = acts_squeeze[..., kept_channel_idx] kept_channel_list[i_wanted_layer] = kept_channel_idx # # alltests_Shap/test0_4 # kept_channel_idx = np.squeeze(np.argwhere(attr < 0)) # # alltests_Shap/test0_6 kept_channel_idx = np.squeeze( np.argwhere( attr < np.nanmean(np.where(attr < 0, attr, np.nan)))) AM_T_reverse[i_wanted_layer] = acts_squeeze[..., kept_channel_idx] kept_channel_list_reverse[i_wanted_layer] = kept_channel_idx AM_list = AM_T logit_list = sess.run([logit])[0] return [AM_list, AM_T_reverse], logit_list, channel_attr_list, \ [kept_channel_list, kept_channel_list_reverse]
def compute_shap(img, model, attr_class, layers, flag1, flag_read_attr=True, iter_num=2**8, labels=None, save_directory=None): """ Using sampling based Shapley method to compute feature attributions """ with tf.Graph().as_default(), tf.Session() as sess, gradient_override_map( {}): # img = tf.image.resize_image_with_crop_or_pad(img, model.image_shape[0], model.image_shape[0]) # imgnp = sess.run(img) # imgnp = imgnp.reshape(224, 224, 3) # plt.imsave("./doghead224.jpeg", imgnp) t_input = tf.placeholder_with_default(img, [None, None, 3]) T = render.import_model(model, t_input, t_input) # grads_cam_T = [T(layer) for layer in layers] # logit = T("softmax2_pre_activation")[0] # score = T("output2")[0, labels.index(attr_class)] logit = T("softmax2_pre_activation")[0] AM_T = list(range(len(layers))) AM_T_reverse = list(range(len(layers))) channel_attr_list = list(range(len(layers))) kept_channel_list = list(range(len(layers))) kept_channel_list_reverse = list(range(len(layers))) ori_logit = logit.eval() y_label = np.zeros_like(ori_logit) y_label[labels.index(attr_class)] = 1 # index_class_logit = ori_logit[labels.index(attr_class)] # detected_label_index = ori_logit.argmax() # print("detected label index: {}, real label index: {}, label name: {}" # .format(detected_label_index, labels.index(attr_class), attr_class)) for i_wanted_layer in range(len(layers)): layer = layers[i_wanted_layer] acts = T(layer).eval() acts_shape = list(acts.shape) # part_name = "import/{}:0".format(layer) # t_part_input = tf.placeholder(acts.dtype, acts_shape) # T_part = import_part_model(model, t_part_input, part_name) # part_logit = T_part("softmax2_pre_activation")[0] n_features = acts.shape[-1] if not flag_read_attr: result = np.zeros((1, n_features)) run_shape = acts_shape.copy() # run_shape = np.delete(run_shape, -1).tolist() # run_shape.insert(-1, -1) reconstruction_shape = [1, acts_shape[-1]] for r in range(iter_num): p = np.random.permutation(n_features) x = acts.copy().reshape(run_shape) y = None for i in p: if y is None: y = logit.eval({T(layer): x}) # y = model.predict(x.reshape(acts_shape)) x[..., i] = 0 y0 = logit.eval({T(layer): x}) # print("Ori logit score: {}, new logit score: {}" # .format(index_class_logit, y0[labels.index(attr_class)])) # y0 = model.predict(x.reshape(acts_shape)) assert y0.shape == y_label.shape, y0.shape prediction_delta = np.sum((y - y0) * y_label) # if i == 139: # print("AM 139: attr is {}".format(prediction_delta)) result[:, i] += prediction_delta y = y0 attr = np.squeeze( (result.copy() / iter_num).reshape(reconstruction_shape).astype( np.float32)) np.savetxt( save_directory + "/{}_{}_{}.txt".format(flag1, layer, attr_class), attr) else: attr = np.loadtxt( save_directory + "/{}_{}_{}.txt".format(flag1, layer, attr_class)).astype( np.float32) # arg_attr = attr.argsort()[::-1][:] # shap_attr_trans = np.transpose(shap_attr, (2, 0, 1)) # acts_squeeze_trans = np.transpose(acts_squeeze, (2, 0, 1)) ''' # # Use it for debug the attribution maps # sort_AMs_idx_b2s = np.argsort(-attr) # sort_AMs_idx_s2b = np.argsort(attr) # for i_sort_AMs in range(20): # if i_sort_AMs < 10: # AM_backup_idx = sort_AMs_idx_b2s[i_sort_AMs] # print("big shap value: {:+.3f} in channel {} of all {}" # .format(attr[AM_backup_idx], AM_backup_idx, acts.shape[-1])) # print(" for class: {}, image No:{}" # .format(attr_class, i_sort_AMs)) # else: # AM_backup_idx = sort_AMs_idx_s2b[i_sort_AMs-10] # print("small shap value: {:+.3f} in channel {} of all {}" # .format(attr[AM_backup_idx], AM_backup_idx, acts.shape[-1])) # print(" for class: {}, image No:{}" # .format(attr_class, i_sort_AMs-10)) # AM_backup = acts[..., AM_backup_idx] # AM_backup = AM_backup.reshape([AM_backup.shape[-1], AM_backup.shape[-1]]) # AM_backup = resize(AM_backup, (model.image_shape[0], model.image_shape[1]), order=1, # mode='constant', anti_aliasing=False) # AM_backup = AM_backup / AM_backup.max() * 255 # resize_show(AM_backup, xi=img) # kept_channel_idx = np.squeeze(np.argwhere(attr > 0)) ''' kept_channel_idx = np.squeeze( np.argwhere( attr > np.nanmean(np.where(attr > 0, attr, np.nan)))) acts_squeeze = np.squeeze(acts) attr_temp = np.squeeze(attr).astype(np.float32) # print(np.count_nonzero(clear_channel_idx)) channel_attr_list[i_wanted_layer] = attr_temp AM_T[i_wanted_layer] = acts_squeeze[..., kept_channel_idx] kept_channel_list[i_wanted_layer] = kept_channel_idx kept_channel_idx = np.squeeze( np.argwhere( attr < np.nanmean(np.where(attr < 0, attr, np.nan)))) AM_T_reverse[i_wanted_layer] = acts_squeeze[..., kept_channel_idx] kept_channel_list_reverse[i_wanted_layer] = kept_channel_idx # test_AM = acts_squeeze * clear_channel_idx * attr_temp # test_AM = np.sum(np.transpose(test_AM, (2, 0, 1)), axis=0) # acts_squeeze_trans = np.transpose(AM_T[i_wanted_layer], (2, 0, 1)) # acts_squeeze_trans_sum = np.sum(acts_squeeze_trans, axis=0) AM_list = AM_T logit_list = sess.run([logit])[0] return [AM_list, AM_T_reverse], logit_list, channel_attr_list, \ [kept_channel_list, kept_channel_list_reverse]
def get_shape(model, node_name): with tf.Graph().as_default(): t_obses = tf.placeholder(dtype=tf.float32, shape=(None, None, None, None)) T = render.import_model(model, t_obses, t_obses) return T(node_name).get_shape().as_list()
def get_var(model, var_name): with tf.Graph().as_default(), tf.Session(): t_obses = tf.placeholder(dtype=tf.float32, shape=(None, None, None, None)) T = render.import_model(model, t_obses, t_obses) return T(var_name).eval()
def _main( objective_f, model, layer, channel_indices, alpha=False, negative=False, decorrelation_matrix=None, n_steps=128, parallel_transforms=16, lr=0.05, override_gradients=True, ): if not isinstance(channel_indices, (tuple, list)): channel_indices = [channel_indices] if isinstance(layer, Layer): layer_name = layer.name elif isinstance(layer, str): layer_name = layer else: raise ValueError("layer argument can be either a Layer object or str") sign = -1 if negative else 1 batch = len(channel_indices) w, h, _ = model.image_shape with tf.Graph().as_default(), tf.Session() as sess: # Transformation Robustness transforms = transform.standard_transforms + [transform.crop_or_pad_to(w, h)] if alpha: transforms += [transform.collapse_alpha_random()] transform_f = render.make_transform_f(transforms) # Parameterization image_t = param.image( w, h, fft=True, decorrelate=True, alpha=alpha, batch=batch ) param_t = transform_f(image_t) # Gradient Overrides if override_gradients: with overrides.relu_overrides(): T = render.import_model(model, param_t, image_t) else: T = render.import_model(model, param_t, image_t) # Objective if decorrelation_matrix is None: objs = [ sign * objective_f(layer_name, i, batch=b) for b, i in enumerate(channel_indices) ] else: raise NotImplementedError reported_obj = tf.stack([o(T) for o in objs]) obj = sum(objs)(T) if alpha: obj *= 1.0 - tf.reduce_mean(image_t[..., -1]) obj -= 0.1 * objectives.blur_alpha_each_step()(T) # Optimization optimization = tf.train.AdamOptimizer(lr).minimize(-obj) tf.global_variables_initializer().run() losses = np.zeros((batch, n_steps)) for step in range(n_steps): _, loss = sess.run([optimization, reported_obj]) losses[:, step] = loss # Evaluation visualization = image_t.eval() if batch == 1: return (visualization, losses) else: return list(zip(visualization, losses))