How to loop through a batch of data to do some operation per sample

This is my code for applying grad-cam:


    for idx, (data, target, meta) in enumerate(tqdm(dataloader_test)):
        print('idx', idx)
        data, target = map(lambda x: x.to(device), (data, target))
        output = model(data)
        output[:,5].sum().backward()
        grads=grad[0].cpu().data.numpy().squeeze()
        fmap=activation[0].cpu().data.numpy().squeeze()
        tmp=grads.reshape([grads.shape[0],-1])
        # Get the mean value of the gradients of every featuremap
        weights=np.mean(tmp,axis=1)
        cam = np.zeros(grads.shape[1:])
        for i,w in enumerate(weights):
            cam += w*fmap[i,:]
        #relu
        cam=(cam>0)*cam
        #cam = np.maximum(cam, 0)
        #print("cam.shape",cam.shape)
        #normalize heatmap
        cam=cam/cam.max()*224
        
        # make the heatmap to be a numpy array
        # impath = meta['impath']
        # impath = cv2.imread(impath)
        # print('shape data', data.shape)
        # data = torch.squeeze(data, dim=1)
        # print('squeeze data', data.shape)
        for data in idx:
            print('shape data', data.shape)
            npic = np.array(torchvision.transforms.ToPILImage()(data).convert('RGB'))
            cam = cv2.resize(cam,(npic.shape[1], npic.shape[0]))
            heatmap=cv2.applyColorMap(np.uint8(cam),cv2.COLORMAP_JET)
            cam_img=npic*0.7+heatmap*0.3
            print(cam_img.shape)
            cv2.imwrite('./visualize/map'+str(count)+'.jpg', cam_img)
            count = count + 1

I have added a loop for data in idx: because I want to apply the heatmap per sample instead of per batch but I get this error

TypeError: 'int' object is not iterable

Any ideas how to solve it? Thank you very much

Hi @peony,

Should your for data in idx line be for data in range(idx)? You can’t iterative over an integer (which is why you get this error)

1 Like

Hello @AlphaBetaGamma96 ,

I tried your suggestion but I get:



TypeError: pic should be Tensor or ndarray. Got <class 'int'>.

I want to for loop over each sample in each batch to be able to apply this operation
npic = np.array(torchvision.transforms.ToPILImage()(data).convert('RGB'))

Ok, so that makes senses why it’s now an int. Why are you using the for data in idx loop anyway? It might be best to just remove it?

I am using it because for each data in batch, I want to apply the heatmap

perhaps change for data in range(idx) to for count in range(idx), perhaps you shouldn’t have the data object within the iterator?