I personally haven’t really tried torch.autograd.grad in practice, so I’m not sure if I’m correct
My suggestion is:
model1_output should be a Variable with requires_grad to be True, and logit is a function of model1_output.
For example:
model1_output = model1(input) # input can not be volatile
logit = model2(model1_output)
Gradinput = torch.autograd.grad(logit, model1_output, doutput)

BTW, there is a pytorch grad cam implementation which just came out. This uses register_hook to save the gradients.

  
      github.com
  
  
    jacobgil/pytorch-grad-cam/blob/master/grad-cam.py 126
import torch
from torch.autograd import Variable
from torch.autograd import Function
from torchvision import models
from torchvision import utils
import cv2
import sys
import numpy as np
import argparse

class FeatureExtractor():
    """ Class for extracting activations and 
    registering gradients from targetted intermediate layers """
    def __init__(self, model, target_layers):
        self.model = model
        self.target_layers = target_layers
        self.gradients = []

    def save_gradient(self, grad):
    	self.gradients.append(grad)


  This file has been truncated. show original