transform = transforms.Compose([
transforms.Resize(224),
transforms.ToTensor(),
transforms.Normalize()
])
img = Image.open('image/for/which/I/need/prediction.jpg')
input = transform(img).unsqueeze(0)
input.size()
>> torch.Size(1, 3, 224, 224)
Inspired by the official Captum tutorial
model = models.resnet18(pretrained=True)
model = model.eval()
output = F.softmax(model(input), dim=1)
output.size()
>> torch.Size(1, 1000)
prediction_score, pred_label_idx = torch.topk(output, 1)
pred_label_idx.squeeze_()
>> 21
from captum.attr import IntegratedGradients
integrated_gradients = IntegratedGradients(model)
attributions_ig = integrated_gradients.attribute(input,
target=pred_label_idx,
n_steps=200)
attributions_ig.size()
>> torch.Size([1, 3, 224, 224])
from transformers import BertTokenizer, BertForQuestionAnswering
model = BertForQuestionAnswering.from_pretrained(model_path)
tokenized_question = BertTokenizer("What's up")
tensor_answer = model(tokenized_question)
integrated_gradients = IntegratedGradients(model)
attributions_ig = integrated_gradients.attribute(tokenized_question,
target=tensor_answer,
n_steps=200)
More here
"Baseline input is meant to represent “absence” of feature input"
"How F(x) changes is we change x"
baseline = torch.zeros_like(input)
input.requires_grad = True
steps=200
scaled_inputs = [baseline + (i / steps) * (input - baseline)
for i in range(0, steps)]
gradients = []
for scaled_input in scaled_inputs:
output = F.softmax(model(scaled_input), dim=1)
output = output.gather(1, pred_label_idx)
model.zero_grad()
output.backward()
gradient = input.grad.detach().cpu().numpy()[0]
gradients.append(gradient)
avg_grads = np.average(gradients, axis=0)
attributions_ig = (input - baseline) * avg_grads
attributions_ig.size()
>> torch.Size([1, 3, 224, 224])
"There's no such thing as a stupid question!"
Piotr Mazurek
Presentation avalibe at: https://tugot17.github.io/Integrated-Gradients-Presentation/