Closed ngopee closed 4 years ago
Hi @ngopee, does test_input_tensor
contain token indices ?
If you want to use LayerConductance you need to configure the InterpretableEmbeddingBase
.
LayerConductance doesn't have the logic of replacing the indices with embedding vectors.
you'll need to call:
interpretable_embedding = configure_interpretable_embedding_layer(model, '<EMBEDDING-LAYER>')
input_embeddings = interpretable_embedding.indices_to_embeddings(test_input_tensor)
cond = LayerConductance(model, model.convs)
cond_vals = cond.attribute(input_embeddings, target=1)
remove_interpretable_embedding_layer(model, input_embeddings)
You'll find some examples here: https://captum.ai/tutorials/Multimodal_VQA_Captum_Insights https://captum.ai/tutorials/Bert_SQUAD_Interpret
@ngopee , did it work for you ? If so, can we close the issue ?
@NarineK Thank you so much for this.
I am actually getting this error when I tried the code above:
IndexError: index 1 is out of bounds for dimension 1 with size 1
Spent whole day trying to figure out if it wasn't a silly mistake. Your help is very much appreciated!
#Setting layer conductance parameters: Conv layer
cond = LayerConductance(model, model.convs)
interpretable_embedding = configure_interpretable_embedding_layer(model, 'embedding')
def compute_input_tensor(model, sentence, min_len = 7, label = 0):
text = [tok.text for tok in nlp.tokenizer(sentence)]
if len(text) < min_len:
text += ['pad'] * (min_len - len(text))
indexed = [TEXT.vocab.stoi[t] for t in text]
print(indexed)
model.zero_grad()
input_indices = torch.tensor(indexed, device=device)
input_indices = input_indices.unsqueeze(0)
input_embeddings = interpretable_embedding.indices_to_embeddings(input_indices)
cond_vals = cond.attribute(input_embeddings,target=1)
return input_indices
compute_input_tensor(model, 'It was a fantastic performance !', label=1)
@ngopee , can it be that the output of your model is one dimensional and when you try to access target=1
it can't access that index of output?Can you try with target=0 or without specifying the target ?
Tried with both target = 0 and without any. Still same error.
This is the tutorial I am trying to run and get the layer conductance: https://captum.ai/tutorials/IMDB_TorchText_Interpret
It can be that model.convs
is a moduleList, would you try:model.convs[0]
instead ? I'll also give a try.
Doesn't seem to be it.
Thank you for the help!
@ngopee , I tried this code snippet and it worked for me:
# accumalate couple samples in this array for visualization purposes
vis_data_records_ig = []
lc = LayerConductance(model, model.convs[0])
def interpret_sentence(model, sentence, min_len = 7, label = 0):
text = [tok.text for tok in nlp.tokenizer(sentence)]
if len(text) < min_len:
text += ['pad'] * (min_len - len(text))
indexed = [TEXT.vocab.stoi[t] for t in text]
model.zero_grad()
input_indices = torch.tensor(indexed, device=device)
input_indices = input_indices.unsqueeze(0)
# input_indices dim: [sequence_length]
seq_length = min_len
# predict
pred = forward_with_sigmoid(input_indices).item()
pred_ind = round(pred)
# generate reference indices for each sample
reference_indices = token_reference.generate_reference(seq_length, device=device).unsqueeze(0)
# compute attributions and approximation delta using layer integrated gradients
#attributions_ig, delta = lig.attribute(input_indices, reference_indices, \
# n_steps=500, return_convergence_delta=True)
interpretable_embedding = configure_interpretable_embedding_layer(model, 'embedding')
input_embeddings = interpretable_embedding.indices_to_embeddings(input_indices)
attributions_ig, delta = lc.attribute(input_embeddings, return_convergence_delta=True)
remove_interpretable_embedding_layer(model, interpretable_embedding)
print('pred: ', Label.vocab.itos[pred_ind], '(', '%.2f'%pred, ')', ', delta: ', abs(delta))
add_attributions_to_visualizer(attributions_ig, text, pred, pred_ind, label, delta, vis_data_records_ig)
def add_attributions_to_visualizer(attributions, text, pred, pred_ind, label, delta, vis_data_records):
attributions = attributions.sum(dim=2).squeeze(0)
attributions = attributions / torch.norm(attributions)
attributions = attributions.cpu().detach().numpy()
# storing couple samples in an array for visualization purposes
vis_data_records.append(visualization.VisualizationDataRecord(
attributions,
pred,
Label.vocab.itos[pred_ind],
Label.vocab.itos[label],
Label.vocab.itos[1],
attributions.sum(),
text,
delta))
Do you have the latest version of captum ? Maybe that can be a reason for inconsistency
Yes this works perfectly! I still have no clue what I missed. I'll look into it and post a follow up when I figure it out.
Thank you very much!!
I am trying to compute layer conductance in the IMDB tutorial, and I keep getting a scalar issue. Any guidance on how I should pass the input (test_input_tensor) to get the attributions.
Thank you!