Wired performance in Conv2d forward using forward Hook

Hi, I want to implement detailed quantize operation by using forward Hook function. My code skeleton is:


model = alexnet(pretrained=True).cuda()
model.eval()


def hook_net(net):
    MAX_ITER = 100
    feature_maps = []
    hooks = []
    A = []

    def extractF_hook(module, inputs, outputs):
        #do this func in each OP
        f_map = outputs.data.cpu()
        feature_maps.append(f_map)

        module_B = deepcopy(module)
        state_dict = module.state_dict()
        state_dict_quant = OrderedDict()
        for k, v in state_dict.items():
            state_dict_quant[k] = torch.sign(v)
        module_B.load_state_dict(state_dict_quant)
        print(type(module_B))
        outputs_B = module_B(inputs)

    keys_list_0 = net._modules.keys()

    for k0 in keys_list_0:
        m = net._modules.get(k0)
        if type(m) ==  torch.nn.modules.container.ModuleList:
            keys_list_1 = m._modules.keys()
            for k1 in keys_list_1:
                mm = m._modules.get(k1) # value, name of the op
                if k0 == 'modules_list' and k1 == '3': # take specific layer output
                    hook = mm.register_forward_hook(extractF_hook)
                    hooks.append(extractF_hook)
        elif type(m) ==  torch.nn.modules.container.Sequential:
            for mm in m._modules.values():
                hook = mm.register_forward_hook(extractF_hook)
                hooks.append(extractF_hook)


    # return layers, feature_maps, hooks
    return feature_maps, hooks

imsize = (256, 256)
loader = transforms.Compose([
        transforms.Resize(imsize),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.256, 0.225]),
        ])

def image_loader(image_name):
    """load image, returns cuda tensor"""
    image = Image.open(image_name)
    image = loader(image).float()
    image = torch.autograd.Variable(image, requires_grad=True)
    image = image.unsqueeze(0)  #this is for VGG, may not be needed for ResNet
    return image.cuda()  #assumes that you're using GPU

image = image_loader('cat.jpg')
dataset_features, hooks = hook_net(model)
model(image)

But I got wired error:

Traceback (most recent call last):
  File "tmp.py", line 87, in <module>
    model(image)
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 357, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/xxx/HashCNN-pytorch/alexnet.py", line 43, in forward
    x = self.features(x)
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 357, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/modules/container.py", line 67, in forward
    input = module(input)
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 359, in __call__
    hook_result = hook(self, input, result)
  File "tmp.py", line 38, in extractF_hook
    outputs_B = module_B(inputs) # \tilde{x}^{l} in paper
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 357, in __call__
    result = self.forward(*input, **kwargs)
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/modules/conv.py", line 282, in forward
    self.padding, self.dilation, self.groups)
  File "/home/xxx/anaconda2/lib/python2.7/site-packages/torch/nn/functional.py", line 84, in conv2d
    if input is not None and input.dim() != 4:
AttributeError: 'tuple' object has no attribute 'dim'

Can anyone help with this?

I know it. inputs in my code should be input[0]

More generally, inputs to the hook is a tuple, your should call outputs_B = module_B(*inputs) so that it works with multiple inputs as well.

That’s very important for me. Thanks!