예제 #1
0
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]
예제 #2
0
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]
예제 #3
0
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
예제 #4
0
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