How to break down "sum of lists" generated by for loop, into separate outputs for visualization?

Viewed 36

I have a code that outputs 6 prediction masks but sums up the result using sum operation

                for (i, mask) in enumerate(masks):
                    quad_preds[i] = (1 - mask) * quad_preds[i]
                    quad_preds[i] = nn.functional.upsample(quad_preds[i], size=segSize, mode='bilinear')
                    for j in range(i+1,len(quad_preds)):
                        mask = nn.functional.upsample(mask, scale_factor=2)
                        quad_preds[j] = mask * quad_preds[j]
                quad_preds[-1] = nn.functional.upsample(quad_preds[-1], size=segSize, mode='bilinear')
                x = sum(quad_preds)
           x = nn.functional.softmax(x[:,1:,:,:], dim=1)
           return x

The shape of x is returned as

torch.Size([1, 151, 512, 683])

"quad_preds" is of type list with a length of 6

This is the len of quad_preds: 6

I am trying to visualize all the 6 masks being produced by for loop and return as x

When I try to append all the masks into x[] as follows:

                x=[]
                for i in range(1, len(quad_preds)):
                    quad_preds[i] = nn.functional.upsample(quad_preds[0], size=segSize, mode='bilinear')
                    x.append(quad_preds[i])

I get the following error:

Traceback (most recent call last):
  File "test.py", line 180, in <module>
    main(args)
  File "test.py", line 113, in main
    test(segmentation_module, loader_val, args)
  File "test.py", line 61, in test
    pred_tmp = segmentation_module(feed_dict, segSize=segSize)
  File "/project/xfu/aamir/anaconda3/envs/QGN/lib/python3.8/site-packages/torch/nn/modules/module.py", line 722, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/project/xfu/aamir/Golden-QGN/models/models.py", line 78, in forward
    pred = self.decoder(self.encoder(inputs, return_feature_maps=True), labels_scaled, segSize=segSize)
  File "/project/xfu/aamir/anaconda3/envs/QGN/lib/python3.8/site-packages/torch/nn/modules/module.py", line 722, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/project/xfu/aamir/Golden-QGN/models/models.py", line 608, in forward
    x = nn.functional.softmax(x[:,1:,:,:], dim=1)
TypeError: list indices must be integers or slices, not tuple

To solve this error, when I convert it into numpy array as follows:

                x=[]
                for i in range(1, len(quad_preds)):
                    quad_preds[i] = nn.functional.upsample(quad_preds[0], size=segSize, mode='bilinear')
                    x.append(quad_preds[i])
                x=np.array(x)

I get the following error:

  File "/project/xfu/aamir/Golden-QGN/models/models.py", line 576, in forward
    x=np.array(x)
  File "/project/xfu/aamir/anaconda3/envs/QGN/lib/python3.8/site-packages/torch/tensor.py", line 480, in __array__
    return self.numpy()
TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

In order to solve this error I use:

                x=[]
                for i in range(1, len(quad_preds)):
                    quad_preds[i] = nn.functional.upsample(quad_preds[0], size=segSize, mode='bilinear')
                    x.append(quad_preds[i])
                x=x.cpu().numpy()

I get this error:

  File "/project/xfu/aamir/anaconda3/envs/QGN/lib/python3.8/site-packages/torch/nn/modules/module.py", line 722, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/project/xfu/aamir/Golden-QGN/models/models.py", line 582, in forward
    x=x.cpu().numpy()

If I use FloatTensor command as follows:

                x=[]
                for i in range(1, len(quad_preds)):
                    quad_preds[i] = nn.functional.upsample(quad_preds[0], size=segSize, mode='bilinear')
                    x.append(quad_preds[i])
                x=torch.FloatTensor(x)

I get this error:

  File "/project/xfu/aamir/Golden-QGN/models/models.py", line 581, in forward
    x=torch.FloatTensor(x)
ValueError: only one element tensors can be converted to Python scalars

So the QUESTION is: How to store all 6 prediction masks into x for visualization? Here is the visualization code that is in another file and reads the returned value of x to display the output. Sharing for reference:

# System libs
import os
import datetime
import argparse
from distutils.version import LooseVersion
# Numerical libs
import numpy as np
import torch
import torch.nn as nn
from torch.autograd import Variable
from scipy.io import loadmat
# Our libs
from dataset import TestDataset
from models import ModelBuilder, SegmentationModule
from utils import colorEncode
from lib.nn import user_scattered_collate, async_copy_to
from lib.utils import as_numpy, mark_volatile
import lib.utils.data as torchdata
import cv2


def visualize_result(preds, args):    #(data, preds, args)
    colors = loadmat('data/color150.mat')['colors']
    #(img, info) = data

    # prediction
    pred_color = colorEncode(preds, colors)

    # aggregate images and save
    im_vis = np.concatenate((img, pred_color),
                            axis=1).astype(np.uint8)

    img_name = info.split('/')[-1]
    cv2.imwrite(os.path.join(args.result,
                img_name.replace('.jpg', '.png')), im_vis)


def test(segmentation_module, loader, args):
    segmentation_module.eval()

    for i, batch_data in enumerate(loader):
        # process data
        batch_data = batch_data[0]
        segSize = (batch_data['img_ori'].shape[0],
                   batch_data['img_ori'].shape[1])
        #print (i, batch_data.shape) 
        img_resized_list = batch_data['img_data']

        with torch.no_grad():
            pred = torch.zeros(1, args.num_class, segSize[0], segSize[1])
            pred = Variable(pred).cuda()

            for img in img_resized_list:
                feed_dict = batch_data.copy()
                feed_dict['img_data'] = img
                del feed_dict['img_ori']
                del feed_dict['info']
                feed_dict = async_copy_to(feed_dict, args.gpu_id)

                # forward pass
                pred_tmp = segmentation_module(feed_dict, segSize=segSize)
                pred = pred + pred_tmp / len(args.imgSize)
                
                
            _, preds = torch.max(pred.data.cpu(), dim=1)
            preds = as_numpy(preds.squeeze(0))

        # visualization
        #visualize_result(
            #(batch_data['img_ori'], batch_data['info']),
            #preds, args)

        visualize_result(preds, args)

        print("shape of preds:", preds.shape)
        
        print('[{}] iter {}'
              .format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), i))


def main(args):
    torch.cuda.set_device(args.gpu_id)

    # Network Builders
    builder = ModelBuilder()
    net_encoder = builder.build_encoder(arch=args.arch_encoder,
                                        fc_dim=args.fc_dim,
                                        weights=args.weights_encoder)
    net_decoder = builder.build_decoder(arch=args.arch_decoder,
                                        fc_dim=args.fc_dim,
                                        weights=args.weights_decoder,
                                        use_softmax=True)

    crit = nn.NLLLoss(ignore_index=-1)

    segmentation_module = SegmentationModule(net_encoder, net_decoder, crit)

    # Dataset and Loader
    list_test = [{'fpath_img': args.test_img}]
    dataset_val = TestDataset(
        list_test, args, max_sample=args.num_val)
    loader_val = torchdata.DataLoader(
        dataset_val,
        batch_size=args.batch_size,
        shuffle=False,
        collate_fn=user_scattered_collate,
        num_workers=5,
        drop_last=True)

    segmentation_module.cuda()

    # Main loop
    test(segmentation_module, loader_val, args)

    print('Inference done!')


if __name__ == '__main__':
    assert LooseVersion(torch.__version__) >= LooseVersion('0.4.0'), \
        'PyTorch>=0.4.0 is required'

    parser = argparse.ArgumentParser()
    # Path related arguments
    parser.add_argument('--test_img', required=True)
    parser.add_argument('--model_path', required=True,
                        help='folder to model path')
    parser.add_argument('--suffix', default='_epoch_1.pth',
                        help="which snapshot to load")

    # Model related arguments
    parser.add_argument('--arch_encoder', default='resnet50',
                        help="architecture of net_encoder")
    parser.add_argument('--arch_decoder', default='QGN_dense_resnet34',
                        help="architecture of net_decoder")
    parser.add_argument('--fc_dim', default=2048, type=int,
                        help='number of features between encoder and decoder')

    # Data related arguments
    parser.add_argument('--num_val', default=-1, type=int,
                        help='number of images to evalutate')
    parser.add_argument('--num_class', default=150, type=int,
                        help='number of classes')
    parser.add_argument('--batch_size', default=1, type=int,
                        help='batchsize. current only supports 1')
    parser.add_argument('--imgSize', default=[300, 400, 500, 600],
                        nargs='+', type=int,
                        help='list of input image sizes.'
                             'for multiscale testing, e.g. 300 400 500')
    parser.add_argument('--imgMaxSize', default=1000, type=int,
                        help='maximum input image size of long edge')
    parser.add_argument('--padding_constant', default=32, type=int,
                        help='maxmimum downsampling rate of the network')
    parser.add_argument('--segm_downsampling_rate', default=8, type=int,
                        help='downsampling rate of the segmentation label')

    # Misc arguments
    parser.add_argument('--result', default='.',
                        help='folder to output visualization results')
    parser.add_argument('--gpu_id', default=0, type=int,
                        help='gpu_id for evaluation')

    args = parser.parse_args()
    print(args)

    # torch.cuda.set_device(args.gpu_id)

    # absolute paths of model weights
    args.weights_encoder = os.path.join(args.model_path,
                                        'encoder' + args.suffix)
    args.weights_decoder = os.path.join(args.model_path,
                                        'decoder' + args.suffix)
    
    print(args.weights_encoder)
    assert os.path.exists(args.weights_encoder) and \
           os.path.exists(args.weights_decoder), 'checkpoint does not exitst!'

    if not os.path.isdir(args.result):
        os.makedirs(args.result)

    main(args)
0 Answers
Related