def leave_one_out(args): dataset, model = args.dataset, args.model st = time.time() print('Making explanations...') if model.maxlen: positions = 1 - to_categorical(range(model.maxlen), num_classes=model.maxlen) if model.type == 'word': if args.train_score: pred_train = model.predict(dataset.x_train) else: pred_val = model.predict(dataset.x_val) elif model.type == 'char': if args.train_score: pred_train = model.predict( encode_data(dataset.x_train, model.charlen, model.vocab, model.vocab_size, model.vocab_check)) else: pred_val = model.predict( encode_data(dataset.x_val, model.charlen, model.vocab, model.vocab_size, model.vocab_check)) classes = np.argmax(pred_train, axis=1) if args.train_score else np.argmax( pred_val, axis=1) if args.train_score: scores = getScore(model, dataset.x_train, pred_train, positions, classes) else: scores = getScore(model, dataset.x_val, pred_val, positions, classes) print('Time spent is {}'.format(time.time() - st)) return scores, [time.time() - st]
def data_generator(x, select, vocab, vocab_size, vocab_check, maxlen, batch_size=128): for i in xrange(0, len(x), batch_size): x_sample = x[i:i + batch_size] select_sample = select[i:i + batch_size] input_data = encode_data(x_sample, maxlen, vocab, vocab_size, vocab_check) yield [input_data, select_sample]
def getScore(model, data_sample, pred_sample, positions, classes): scores = [] for i, sample in enumerate(data_sample): print('explaining the {}th sample...'.format(i)) if model.type == 'word': probs = model.predict(np.expand_dims(sample, 0) * positions) # [d, 2] elif model.type == 'char': words = encode_data([sample], model.charlen, model.vocab, model.vocab_size, model.vocab_check) d = words.shape[1] positions = np.expand_dims(1 - to_categorical(range(d), num_classes=d), axis=-1) # (d, d) probs = model.predict(words * positions) score = pred_sample[i, classes[i]] - probs[:, classes[i]] scores.append(score) return scores
def batch_generator(x, select, y, vocab, vocab_size, vocab_check, maxlen, epoch, batch_size=128): for j in xrange(0, len(x) * epoch, batch_size): i = j % len(x) x_sample = x[i:i + batch_size] select_sample = select[i:i + batch_size] y_sample = y[i:i + batch_size] input_data = encode_data(x_sample, maxlen, vocab, vocab_size, vocab_check) yield ([input_data, select_sample], y_sample)
def greedy_change_the_word_K(score, model, x, original_prob, K=10, sign=True): """ selected_points: a list of length K, with each element of the same dimension of x. selected_points[k]: we seletct k indexes of x to change for k = 1, ..., K selected_points[k][i] = 1 if i is the index we select to change, 0 otherwise changed_sequences: a list of length K, with each element of the same dimension of x. changed_sequences[k]: the changed sequence of x with k elements changed for k = 1, ..., K when k == 0: we perturb the sequence until its predicted label is changed. """ if not sign: score = abs(score) selected_points = [] changed_x = [] nums = np.arange(1, K + 1) if args.data == 'agccnn': word = encode_data([x], model.charlen, model.vocab, model.vocab_size, model.vocab_check)[0] changed_sequence = word else: changed_sequence = x original_y = np.argmax(original_prob) if K == 0: current_label = original_y k = 0 while current_label == original_y: k += 1 selected = np.argsort(score)[-k:] # indices of largest k score. d = len(score) selected_k_hot = np.zeros(d) selected_k_hot[selected] = 1.0 if args.data == 'imdbcnn': # selected_points.append(x * selected_k_hot) # selecting largest k. # find the index of the kth change selected_k = np.argsort(score)[-k] # make the change changed_sequences = np.tile( np.expand_dims(changed_sequence, axis=0), [max_features, 1]) #[max_features, d] changed_sequences[:, selected_k] = np.arange(1, max_features + 1) probs_changed_sequences = model.predict(changed_sequences) # index of which change_sequence we want index_sequence = np.argmin(probs_changed_sequences[:, original_y]) changed_sequence = changed_sequences[index_sequence] current_label = np.argmax( probs_changed_sequences[index_sequence]) selected_points.append(x * selected_k_hot) # selecting largest k. changed_x.append(changed_sequence) return selected_points, changed_x for k in nums: selected = np.argsort(score)[-k:] # indices of largest k score. d = len(score) selected_k_hot = np.zeros(d) selected_k_hot[selected] = 1.0 if args.data != 'agccnn': selected_points.append(x * selected_k_hot) # selecting largest k. # find the index of the kth change selected_k = np.argsort(score)[-k] # make the change changed_sequences = np.tile( np.expand_dims(changed_sequence, axis=0), [max_features, 1]) #[max_features, d] changed_sequences[:, selected_k] = np.arange(1, max_features + 1) probs_changed_sequences = model.predict(changed_sequences) # index of which change_sequence we want index_sequence = np.argmin(probs_changed_sequences[:, original_y]) changed_sequence = changed_sequences[index_sequence] changed_x.append(changed_sequence) elif args.data == 'agccnn': selected_points.append(word * np.expand_dims(selected_k_hot, axis=-1)) selected_k = np.argsort(score)[-k] changed_sequences = np.tile( np.expand_dims(changed_sequence, axis=0), [model.vocab_size, 1, 1]) #[69, 1014, 69] changed_sequences[:, selected_k, :] = np.diag( np.ones(model.vocab_size)) probs_changed_sequences = model.predict(changed_sequences) index_sequence = np.argmin(probs_changed_sequences[:, original_y]) changed_sequence = changed_sequences[index_sequence] changed_x.append(changed_sequence) return selected_points, changed_x