def __init__(
            self,
            model_path='../model/deepglobe_deeplabv3_weights-cityscapes_19-outputs/model.pth',
            dataset='deepglobe',
            output_channels=19,
            split='valid',
            net_type='deeplab',
            batch_size=1,
            shuffle=True):
        """
        Initializes the tester by loading the model with the good parameters.
        :param model_path: Path to model weights
        :param dataset: dataset used amongst {'deepglobe', 'pascal', 'cityscapes'}
        :param output_channels: num of output channels of model
        :param split: split to be used amongst {'train', 'valid'}
        :param net_type: model type to be used amongst {'deeplab', 'unet'}
        :param batch_size: batch size when loading images (always 1 here)
        :param shuffle: when loading images from dataset
        """

        print('[Tester] [Init] Initializing tester...')
        self.dataset = dataset
        self.model_path = model_path

        # Load model
        print('[Tester] [Init] Loading model ' + model_path + ' with ' +
              str(output_channels) + ' output channels...')

        self.device = torch.device(
            'cuda:0' if torch.cuda.is_available() else 'cpu')
        self.model = SPPNet(output_channels=output_channels).to(self.device)
        param = torch.load(model_path)
        self.model.load_state_dict(param)
        del param

        # Create data loader depending on dataset, split and net type
        if dataset == 'pascal':
            self.valid_dataset = PascalVocDataset(split=split,
                                                  net_type=net_type)
        elif dataset == 'cityscapes':
            self.valid_dataset = CityscapesDataset(split=split,
                                                   net_type=net_type)
        elif dataset == 'deepglobe':
            self.valid_dataset = DeepGlobeDataset(split=split,
                                                  net_type=net_type)
        else:
            raise NotImplementedError

        self.valid_loader = DataLoader(self.valid_dataset,
                                       batch_size=batch_size,
                                       shuffle=shuffle)

        print('[Tester] [Init] ...done!')
        print('[Tester] [Init] Tester created.')
Ejemplo n.º 2
0
    def __init__(
            self,
            model_path='../model/deepglobe_deeplabv3_weights-cityscapes_19-outputs/model.pth',
            dataset='deepglobe',
            output_channels=19,
            split='valid',
            net_type='deeplab',
            batch_size=1,
            shuffle=True):
        print('[Score Calculator] Initializing calculator...')
        self.dataset = dataset
        self.model_path = model_path
        self.net_type = net_type

        self.fp16 = True

        # Load model
        print('[Score Calculator] Loading model ' + model_path + ' with ' +
              str(output_channels) + ' output channels...')

        self.device = torch.device(
            'cuda:0' if torch.cuda.is_available() else 'cpu')
        self.model = SPPNet(output_channels=output_channels).to(self.device)
        param = torch.load(model_path)
        self.model.load_state_dict(param)
        del param

        # Create data loader depending on dataset, split and net type
        if dataset == 'pascal':
            self.valid_dataset = PascalVocDataset(split=split,
                                                  net_type=net_type)
            self.classes = np.arange(1, 22)
        elif dataset == 'cityscapes':
            self.valid_dataset = CityscapesDataset(split=split,
                                                   net_type=net_type)
            self.classes = np.arange(1, 20)
        elif dataset == 'deepglobe':
            self.valid_dataset = DeepGlobeDataset(split=split,
                                                  net_type=net_type)
            self.classes = np.arange(1, 8)
        else:
            raise NotImplementedError

        self.valid_loader = DataLoader(self.valid_dataset,
                                       batch_size=batch_size,
                                       shuffle=shuffle)

        # fp16
        if self.fp16:
            from utils.apex.apex.fp16_utils.fp16util import BN_convert_float
            self.model = BN_convert_float(self.model.half())
            print('[Score Calculator] fp16 applied')

        print('[Score Calculator] ...done!')
        print('[Score Calculator] Calculator created.')
Ejemplo n.º 3
0
def load_model(output_channels=2, model_path='../model/sherbrooke_deeplabv3p_lgpu30-2/model.pth'):
    '''
    Returns torch model with pretrained weights

    :param output_channels:
    :param model_path:
    :return:
    '''
    model_path = Path(model_path)
    path, model_dir = os.path.split(model_path.parent)  # separate path and filename
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') #work on GPU if available

    print(f'Device: {device}')
    if 'mnv2' in model_dir:
        model = SPPNet(enc_type='mobilenetv2', dec_type = 'maspp', output_channels = output_channels).to(device)
    else:
        model = SPPNet(output_channels=output_channels).to(device)

    if device == torch.device('cpu'):
        param = torch.load(model_path, map_location='cpu')  # parameters saved in checkpoint via model_path
    else:
        param = torch.load(model_path)  # parameters saved in checkpoint via model_path

    print(f'Parameters loaded from {model_path}')

    model.load_state_dict(param) #apply method load_state_dict to model?
    del param # why delete parameters? Reduce memory usage?

    return model
Ejemplo n.º 4
0
def load_model(out_channels=2, enc_type='efficientnet', dec_type='unet', pretrained=True, output_stride=8):
    # Network
    global net_type
    if 'unet' in dec_type:
        net_type = 'unet'
        if 'efficient' in enc_type:
            model = EfficientUnet(enc_type, out_channels=out_channels, concat_input=True,
                                         pretrained=pretrained)#, model_name=enc_type)
        else:
            model = EncoderDecoderNet(**net_config)
    else:
        net_type = 'deeplab'
        model = SPPNet(output_channels=out_channels, enc_type=enc_type, dec_type=dec_type, output_stride=output_stride)
    return model
Ejemplo n.º 5
0
import albumentations as albu
import cv2
import datetime
import sys

import argparse
parser = argparse.ArgumentParser(description='Freespace detection module')
parser.add_argument("video_path", help = "video file tor run segmentation on" )
parser.add_argument("--bs", dest = "batch_size", default = 1, type = int, help="number of sample per batch")
parser.add_argument("--dim", dest = "input_dim", help = "Input resolution of the network. Increase to increase accuracy. Decrease to increase speed", default = 256, type = int)
parser.add_argument("--dev", dest = "device_id", help = "ID of graphic card device", default = '0')
args = parser.parse_args()

print("Loading network...")
device = torch.device('cuda:'+args.device_id if torch.cuda.is_available() else 'cpu')
model = SPPNet(output_channels=10, enc_type='xception65', dec_type='aspp').to(device)
model_path = '../model/bdd100k_deeplabv3p_xception65_total/model_tmp.pth'
print("Setting the parameters...")
param = torch.load(model_path, map_location='cuda:1')
model.load_state_dict(param)
del param
print("Setting hyper parameter...")
batch_size = int(args.batch_size)
dim = int(args.input_dim)
resizer = albu.Compose([albu.Resize(height=dim, width=dim)])
print("Setting up the model in evalutation mode...")
model.eval()

print("Loading video...")
videofile = args.video_path
cap = cv2.VideoCapture(videofile)
Ejemplo n.º 6
0
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

import torch
import torch.nn.functional as F
from torch.utils.data import DataLoader

from models.net import SPPNet
from dataset.cityscapes import CityscapesDataset
from utils.preprocess import minmax_normalize


device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model = SPPNet(output_channels=19).to(device)
model_path = '../model/cityscapes_deeplab_v3_plus/model.pth'
param = torch.load(model_path)
model.load_state_dict(param)
del param

batch_size = 1

valid_dataset = CityscapesDataset(split='valid', preprocess='deeplab')
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=True)

images_list = []
labels_list = []
preds_list = []

model.eval()
Ejemplo n.º 7
0
import matplotlib.pyplot as plt

import torch
import torch.nn.functional as F
from torch.utils.data import DataLoader

from models.net import SPPNet
from dataset.cityscapes import CityscapesDataset
from utils.preprocess import minmax_normalize

import datetime
from torchsummary import summary

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
#model = SPPNet(output_channels=19).to(device)
model = SPPNet(output_channels=19, enc_type='mobilenetv2',
               dec_type='maspp').to(device)
summary(model, (3, 128, 256))
#model_path = '../model/cityscapes_deeplab_v3_plus/model.pth'
#model_path = '../model/cityscapes_mobilenetv2/model.pth'
model_path = '../model/cityscapes_deeplabv3p_mobilenetv2/model_tmp.pth'
param = torch.load(model_path)
model.load_state_dict(param)
del param

batch_size = 1

valid_dataset = CityscapesDataset(split='valid', net_type='deeplab')
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=True)

images_list = []
labels_list = []
Ejemplo n.º 8
0
def convert_xception65(ckpt_path, num_classes):
    def conv_converter(pt_layer, tf_layer_name, depthwise=False, bias=False):
        if depthwise:
            pt_layer.weight.data = torch.Tensor(
                reader.get_tensor(
                    f'{tf_layer_name}/depthwise_weights').transpose(
                        2, 3, 0, 1))
        else:
            pt_layer.weight.data = torch.Tensor(
                reader.get_tensor(f'{tf_layer_name}/weights').transpose(
                    3, 2, 0, 1))

        if bias:
            pt_layer.bias.data = torch.Tensor(
                reader.get_tensor(f'{tf_layer_name}/biases'))

    def bn_converter(pt_layer, tf_layer_name):
        pt_layer.bias.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/beta'))
        pt_layer.weight.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/gamma'))
        pt_layer.running_mean.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/moving_mean'))
        pt_layer.running_var.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/moving_variance'))

    def sepconv_converter(pt_layer, tf_layer_name):
        conv_converter(pt_layer.depthwise, f'{tf_layer_name}_depthwise', True)
        bn_converter(pt_layer.bn_depth, f'{tf_layer_name}_depthwise/BatchNorm')
        conv_converter(pt_layer.pointwise, f'{tf_layer_name}_pointwise')
        bn_converter(pt_layer.bn_point, f'{tf_layer_name}_pointwise/BatchNorm')

    def block_converter(pt_block, tf_block_name):
        if pt_block.skip_connection_type == 'conv':
            conv_converter(pt_block.conv, f'{tf_block_name}/shortcut')
            bn_converter(pt_block.bn, f'{tf_block_name}/shortcut/BatchNorm')

        sepconv_converter(pt_block.sep_conv1.block,
                          f'{tf_block_name}/separable_conv1')
        sepconv_converter(pt_block.sep_conv2.block,
                          f'{tf_block_name}/separable_conv2')
        sepconv_converter(pt_block.sep_conv3.block,
                          f'{tf_block_name}/separable_conv3')

    reader = tf.train.NewCheckpointReader(ckpt_path)
    model = SPPNet(num_classes,
                   enc_type='xception65',
                   dec_type='aspp',
                   output_stride=8)

    # Xception
    ## Entry flow
    conv_converter(model.encoder.conv1, 'xception_65/entry_flow/conv1_1')
    bn_converter(model.encoder.bn1, 'xception_65/entry_flow/conv1_1/BatchNorm')
    conv_converter(model.encoder.conv2, 'xception_65/entry_flow/conv1_2')
    bn_converter(model.encoder.bn2, 'xception_65/entry_flow/conv1_2/BatchNorm')
    block_converter(model.encoder.block1,
                    'xception_65/entry_flow/block1/unit_1/xception_module')
    block_converter(model.encoder.block2,
                    'xception_65/entry_flow/block2/unit_1/xception_module')
    block_converter(model.encoder.block3,
                    'xception_65/entry_flow/block3/unit_1/xception_module')
    ## Middle flow
    block_converter(model.encoder.block4,
                    'xception_65/middle_flow/block1/unit_1/xception_module')
    block_converter(model.encoder.block5,
                    'xception_65/middle_flow/block1/unit_2/xception_module')
    block_converter(model.encoder.block6,
                    'xception_65/middle_flow/block1/unit_3/xception_module')
    block_converter(model.encoder.block7,
                    'xception_65/middle_flow/block1/unit_4/xception_module')
    block_converter(model.encoder.block8,
                    'xception_65/middle_flow/block1/unit_5/xception_module')
    block_converter(model.encoder.block9,
                    'xception_65/middle_flow/block1/unit_6/xception_module')
    block_converter(model.encoder.block10,
                    'xception_65/middle_flow/block1/unit_7/xception_module')
    block_converter(model.encoder.block11,
                    'xception_65/middle_flow/block1/unit_8/xception_module')
    block_converter(model.encoder.block12,
                    'xception_65/middle_flow/block1/unit_9/xception_module')
    block_converter(model.encoder.block13,
                    'xception_65/middle_flow/block1/unit_10/xception_module')
    block_converter(model.encoder.block14,
                    'xception_65/middle_flow/block1/unit_11/xception_module')
    block_converter(model.encoder.block15,
                    'xception_65/middle_flow/block1/unit_12/xception_module')
    block_converter(model.encoder.block16,
                    'xception_65/middle_flow/block1/unit_13/xception_module')
    block_converter(model.encoder.block17,
                    'xception_65/middle_flow/block1/unit_14/xception_module')
    block_converter(model.encoder.block18,
                    'xception_65/middle_flow/block1/unit_15/xception_module')
    block_converter(model.encoder.block19,
                    'xception_65/middle_flow/block1/unit_16/xception_module')
    ## Exit flow
    block_converter(model.encoder.block20,
                    'xception_65/exit_flow/block1/unit_1/xception_module')
    block_converter(model.encoder.block21,
                    'xception_65/exit_flow/block2/unit_1/xception_module')

    # ASPP
    conv_converter(model.spp.aspp0.conv, 'aspp0')
    bn_converter(model.spp.aspp0.bn, 'aspp0/BatchNorm')
    sepconv_converter(model.spp.aspp1.block, 'aspp1')
    sepconv_converter(model.spp.aspp2.block, 'aspp2')
    sepconv_converter(model.spp.aspp3.block, 'aspp3')

    conv_converter(model.spp.image_pooling.conv, 'image_pooling')
    bn_converter(model.spp.image_pooling.bn, 'image_pooling/BatchNorm')
    conv_converter(model.spp.conv, 'concat_projection')
    bn_converter(model.spp.bn, 'concat_projection/BatchNorm')

    # Decoder
    conv_converter(model.decoder.conv, 'decoder/feature_projection0')
    bn_converter(model.decoder.bn, 'decoder/feature_projection0/BatchNorm')

    sepconv_converter(model.decoder.sep1.block, 'decoder/decoder_conv0')
    sepconv_converter(model.decoder.sep2.block, 'decoder/decoder_conv1')

    # Logits
    conv_converter(model.logits, 'logits/semantic', bias=True)

    return model
Ejemplo n.º 9
0
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

import torch
import torch.nn.functional as F
from torch.utils.data import DataLoader

from models.net import SPPNet
from dataset.cityscapes import CityscapesDataset
from utils.preprocess import minmax_normalize


device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model = SPPNet(output_channels=19).to(device)
model_path = '../model/cityscapes_deeplab_v3_plus/model.pth'
param = torch.load(model_path)
model.load_state_dict(param)
del param

batch_size = 1

valid_dataset = CityscapesDataset(split='valid', net_type='deeplab')
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=True)

images_list = []
labels_list = []
preds_list = []

model.eval()
def convert_mobilenetv2(ckpt_path, num_classes):
    def conv_converter(pt_layer, tf_layer_name, depthwise=False, bias=False):
        if depthwise:
            pt_layer.weight.data = torch.Tensor(
                reader.get_tensor(
                    f'{tf_layer_name}/depthwise_weights').transpose(
                        2, 3, 0, 1))
        else:
            pt_layer.weight.data = torch.Tensor(
                reader.get_tensor(f'{tf_layer_name}/weights').transpose(
                    3, 2, 0, 1))

        if bias:
            pt_layer.bias.data = torch.Tensor(
                reader.get_tensor(f'{tf_layer_name}/biases'))

    def bn_converter(pt_layer, tf_layer_name):
        pt_layer.bias.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/beta'))
        pt_layer.weight.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/gamma'))
        pt_layer.running_mean.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/moving_mean'))
        pt_layer.running_var.data = torch.Tensor(
            reader.get_tensor(f'{tf_layer_name}/moving_variance'))

    def block_converter(pt_layer, tf_layer_name):
        if hasattr(pt_layer, 'expand'):
            conv_converter(pt_layer.expand.conv, f'{tf_layer_name}/expand')
            bn_converter(pt_layer.expand.bn,
                         f'{tf_layer_name}/expand/BatchNorm')

        conv_converter(pt_layer.depthwise.conv,
                       f'{tf_layer_name}/depthwise',
                       depthwise=True)
        bn_converter(pt_layer.depthwise.bn,
                     f'{tf_layer_name}/depthwise/BatchNorm')

        conv_converter(pt_layer.project.conv, f'{tf_layer_name}/project')
        bn_converter(pt_layer.project.bn, f'{tf_layer_name}/project/BatchNorm')

    reader = tf.train.NewCheckpointReader(ckpt_path)
    model = SPPNet(num_classes, enc_type='mobilenetv2', dec_type='maspp')

    # MobileNetV2
    conv_converter(model.encoder.conv, 'MobilenetV2/Conv')
    bn_converter(model.encoder.bn, 'MobilenetV2/Conv/BatchNorm')

    block_converter(model.encoder.block0, 'MobilenetV2/expanded_conv')
    block_converter(model.encoder.block1, 'MobilenetV2/expanded_conv_1')
    block_converter(model.encoder.block2, 'MobilenetV2/expanded_conv_2')
    block_converter(model.encoder.block3, 'MobilenetV2/expanded_conv_3')
    block_converter(model.encoder.block4, 'MobilenetV2/expanded_conv_4')
    block_converter(model.encoder.block5, 'MobilenetV2/expanded_conv_5')
    block_converter(model.encoder.block6, 'MobilenetV2/expanded_conv_6')
    block_converter(model.encoder.block7, 'MobilenetV2/expanded_conv_7')
    block_converter(model.encoder.block8, 'MobilenetV2/expanded_conv_8')
    block_converter(model.encoder.block9, 'MobilenetV2/expanded_conv_9')
    block_converter(model.encoder.block10, 'MobilenetV2/expanded_conv_10')
    block_converter(model.encoder.block11, 'MobilenetV2/expanded_conv_11')
    block_converter(model.encoder.block12, 'MobilenetV2/expanded_conv_12')
    block_converter(model.encoder.block13, 'MobilenetV2/expanded_conv_13')
    block_converter(model.encoder.block14, 'MobilenetV2/expanded_conv_14')
    block_converter(model.encoder.block15, 'MobilenetV2/expanded_conv_15')
    block_converter(model.encoder.block16, 'MobilenetV2/expanded_conv_16')

    # SPP
    conv_converter(model.spp.aspp0.conv, 'aspp0')
    bn_converter(model.spp.aspp0.bn, 'aspp0/BatchNorm')
    conv_converter(model.spp.image_pooling.conv, 'image_pooling')
    bn_converter(model.spp.image_pooling.bn, 'image_pooling/BatchNorm')
    conv_converter(model.spp.conv, 'concat_projection')
    bn_converter(model.spp.bn, 'concat_projection/BatchNorm')

    # Logits
    conv_converter(model.logits, 'logits/semantic', bias=True)

    return model
Ejemplo n.º 11
0
def process(config_path):
    gc.collect()
    torch.cuda.empty_cache()
    config = yaml.load(open(config_path))
    net_config = config['Net']
    data_config = config['Data']
    train_config = config['Train']
    loss_config = config['Loss']
    opt_config = config['Optimizer']
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    t_max = opt_config['t_max']

    # Collect training parameters
    max_epoch = train_config['max_epoch']
    batch_size = train_config['batch_size']
    fp16 = train_config['fp16']
    resume = train_config['resume']
    pretrained_path = train_config['pretrained_path']
    freeze_enabled = train_config['freeze']
    seed_enabled = train_config['seed']

    #########################################
    # Deterministic training
    if seed_enabled:
        seed = 100
        torch.manual_seed(seed)
        torch.cuda.manual_seed_all(seed)
        np.random.seed(seed=seed)
        import random
        random.seed(a=100)
    #########################################

    # Network
    if 'unet' in net_config['dec_type']:
        net_type = 'unet'
        model = EncoderDecoderNet(**net_config)
    else:
        net_type = 'deeplab'
        net_config['output_channels'] = 19
        model = SPPNet(**net_config)

    dataset = data_config['dataset']
    if dataset == 'deepglobe-dynamic':
        from dataset.deepglobe_dynamic import DeepGlobeDatasetDynamic as Dataset
        net_config['output_channels'] = 7
        classes = np.arange(0, 7)
    else:
        raise NotImplementedError
    del data_config['dataset']

    modelname = config_path.stem
    timestamp = datetime.timestamp(datetime.now())
    print("timestamp =", datetime.fromtimestamp(timestamp))
    output_dir = Path(os.path.join(ROOT_DIR, f'model/{modelname}_{datetime.fromtimestamp(timestamp)}') )
    output_dir.mkdir(exist_ok=True)
    log_dir = Path(os.path.join(ROOT_DIR, f'logs/{modelname}_{datetime.fromtimestamp(timestamp)}') )
    log_dir.mkdir(exist_ok=True)
    dataset_dir= '/home/sfoucher/DEV/pytorch-segmentation/data/deepglobe_as_pascalvoc/VOCdevkit/VOC2012'
    logger = debug_logger(log_dir)
    logger.debug(config)
    logger.info(f'Device: {device}')
    logger.info(f'Max Epoch: {max_epoch}')

    # Loss
    loss_fn = MultiClassCriterion(**loss_config).to(device)
    params = model.parameters()
    optimizer, scheduler = create_optimizer(params, **opt_config)

    # history
    if resume:
        with open(log_dir.joinpath('history.pkl'), 'rb') as f:
            history_dict = pickle.load(f)
            best_metrics = history_dict['best_metrics']
            loss_history = history_dict['loss']
            iou_history = history_dict['iou']
            start_epoch = len(iou_history)
            for _ in range(start_epoch):
                scheduler.step()
    else:
        start_epoch = 0
        best_metrics = 0
        loss_history = []
        iou_history = []


    affine_augmenter = albu.Compose([albu.HorizontalFlip(p=.5),albu.VerticalFlip(p=.5)
                                    # Rotate(5, p=.5)
                                    ])
    # image_augmenter = albu.Compose([albu.GaussNoise(p=.5),
    #                                 albu.RandomBrightnessContrast(p=.5)])
    image_augmenter = None

    # This has been put in the loop for the dynamic training

    """
    # Dataset
    train_dataset = Dataset(affine_augmenter=affine_augmenter, image_augmenter=image_augmenter,
                            net_type=net_type, **data_config)
    valid_dataset = Dataset(split='valid', net_type=net_type, **data_config)
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4,
                            pin_memory=True, drop_last=True)
    valid_loader = DataLoader(valid_dataset, batch_size=1, shuffle=False, num_workers=4, pin_memory=True)
    """

    

    # Pretrained model
    if pretrained_path:
        logger.info(f'Resume from {pretrained_path}')
        param = torch.load(pretrained_path)
        model.load_state_dict(param)
        model.logits = torch.nn.Conv2d(256, net_config['output_channels'], 1)
        del param

    # To device
    model = model.to(device)

    #########################################
    if freeze_enabled:
        # Code de Rémi
        # Freeze layers
        for param_index in range(int((len(optimizer.param_groups[0]['params']))*0.5)):
            optimizer.param_groups[0]['params'][param_index].requires_grad = False
    #########################################
        params_to_update = model.parameters()
        print("Params to learn:")
        if freeze_enabled:
            params_to_update = []
            for name,param in model.named_parameters():
                if param.requires_grad == True:
                    params_to_update.append(param)
                    print("\t",name)
        optimizer, scheduler = create_optimizer(params_to_update, **opt_config)

    # fp16
    if fp16:
        # I only took the necessary files because I don't need the C backend of apex,
        # which is broken and can't be installed
        # from apex import fp16_utils
        from utils.apex.apex.fp16_utils.fp16util import BN_convert_float
        from utils.apex.apex.fp16_utils.fp16_optimizer import FP16_Optimizer
        # model = fp16_utils.BN_convert_float(model.half())
        model = BN_convert_float(model.half())
        # optimizer = fp16_utils.FP16_Optimizer(optimizer, verbose=False, dynamic_loss_scale=True)
        optimizer = FP16_Optimizer(optimizer, verbose=False, dynamic_loss_scale=True)
        logger.info('Apply fp16')

    # Restore model
    if resume:
        model_path = output_dir.joinpath(f'model_tmp.pth')
        logger.info(f'Resume from {model_path}')
        param = torch.load(model_path)
        model.load_state_dict(param)
        del param
        opt_path = output_dir.joinpath(f'opt_tmp.pth')
        param = torch.load(opt_path)
        optimizer.load_state_dict(param)
        del param
    i_iter = 0
    ma_loss= 0
    ma_iou= 0
    # Train
    for i_epoch in range(start_epoch, max_epoch):
        logger.info(f'Epoch: {i_epoch}')
        logger.info(f'Learning rate: {optimizer.param_groups[0]["lr"]}')

        train_losses = []
        train_ious = []
        model.train()

        # Initialize randomized but balanced datasets
        train_dataset = Dataset(base_dir = dataset_dir,
                                affine_augmenter=affine_augmenter, image_augmenter=image_augmenter,
                                net_type=net_type, **data_config)
        valid_dataset = Dataset(base_dir = dataset_dir,
                                split='valid', net_type=net_type, **data_config)
        train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4,
                                pin_memory=True, drop_last=True)
        valid_loader = DataLoader(valid_dataset, batch_size=1, shuffle=False, num_workers=4, pin_memory=True)

        with tqdm(train_loader) as _tqdm:
            for i, batched in enumerate(_tqdm):
                images, labels = batched
                if fp16:
                    images = images.half()
                images, labels = images.to(device), labels.to(device)
                optimizer.zero_grad()
                preds = model(images)
                if net_type == 'deeplab':
                    preds = F.interpolate(preds, size=labels.shape[1:], mode='bilinear', align_corners=True)
                if fp16:
                    loss = loss_fn(preds.float(), labels)
                else:
                    loss = loss_fn(preds, labels)

                preds_np = preds.detach().cpu().numpy()
                labels_np = labels.detach().cpu().numpy()
                iou = compute_iou_batch(np.argmax(preds_np, axis=1), labels_np, classes)

                _tqdm.set_postfix(OrderedDict(seg_loss=f'{loss.item():.5f}', iou=f'{iou:.3f}'))
                train_losses.append(loss.item())
                train_ious.append(iou)
                ma_loss= 0.01*loss.item() +  0.99 * ma_loss
                ma_iou= 0.01*iou +  0.99 * ma_iou
                plotter.plot('loss', 'train', 'iteration Loss', i_iter, loss.item())
                plotter.plot('iou', 'train', 'iteration iou', i_iter, iou)
                plotter.plot('loss', 'ma_loss', 'iteration Loss', i_iter, ma_loss)
                plotter.plot('iou', 'ma_iou', 'iteration iou', i_iter, ma_iou)
                if fp16:
                    optimizer.backward(loss)
                else:
                    loss.backward()
                optimizer.step()
                i_iter += 1
        scheduler.step()

        train_loss = np.mean(train_losses)
        train_iou = np.nanmean(train_ious)
        logger.info(f'train loss: {train_loss}')
        logger.info(f'train iou: {train_iou}')
        plotter.plot('loss-epoch', 'train', 'iteration Loss', i_epoch, train_loss)
        plotter.plot('iou-epoch', 'train', 'iteration iou', i_epoch, train_iou)
        torch.save(model.state_dict(), output_dir.joinpath('model_tmp.pth'))
        torch.save(optimizer.state_dict(), output_dir.joinpath('opt_tmp.pth'))

        valid_losses = []
        valid_ious = []
        model.eval()
        with torch.no_grad():
            with tqdm(valid_loader) as _tqdm:
                for batched in _tqdm:
                    images, labels = batched
                    if fp16:
                        images = images.half()
                    images, labels = images.to(device), labels.to(device)
                    preds = model.tta(images, net_type=net_type)
                    if fp16:
                        loss = loss_fn(preds.float(), labels)
                    else:
                        loss = loss_fn(preds, labels)

                    preds_np = preds.detach().cpu().numpy()
                    labels_np = labels.detach().cpu().numpy()

                    # I changed a parameter in the compute_iou method to prevent it from yielding nans
                    iou = compute_iou_batch(np.argmax(preds_np, axis=1), labels_np, classes)

                    _tqdm.set_postfix(OrderedDict(seg_loss=f'{loss.item():.5f}', iou=f'{iou:.3f}'))
                    valid_losses.append(loss.item())
                    valid_ious.append(iou)

        valid_loss = np.mean(valid_losses)
        valid_iou = np.mean(valid_ious)
        logger.info(f'valid seg loss: {valid_loss}')
        logger.info(f'valid iou: {valid_iou}')
        plotter.plot('loss-epoch', 'valid', 'iteration Loss', i_epoch, valid_loss)
        plotter.plot('iou-epoch', 'valid', 'iteration iou', i_epoch, valid_iou)
        if best_metrics < valid_iou:
            best_metrics = valid_iou
            logger.info('Best Model!')
            torch.save(model.state_dict(), output_dir.joinpath('model.pth'))
            torch.save(optimizer.state_dict(), output_dir.joinpath('opt.pth'))

        loss_history.append([train_loss, valid_loss])
        iou_history.append([train_iou, valid_iou])
        history_ploter(loss_history, log_dir.joinpath('loss.png'))
        history_ploter(iou_history, log_dir.joinpath('iou.png'))

        history_dict = {'loss': loss_history,
                        'iou': iou_history,
                        'best_metrics': best_metrics}
        with open(log_dir.joinpath('history.pkl'), 'wb') as f:
            pickle.dump(history_dict, f)
Ejemplo n.º 12
0
    output_dir.mkdir(exist_ok=True, parents=True)
    log_dir = Path('../logs').joinpath(modelname)
    log_dir.mkdir(exist_ok=True, parents=True)

    logger = debug_logger(log_dir)
    logger.info(f'Device: {device}')
    logger.info(f'Max Epoch: {max_epoch}')

    del data_config['dataset']
    train_dataset = Dataset(split='train', **data_config)
    valid_dataset = Dataset(split='valid', **data_config)
    train_loader = DataLoader(train_dataset,
                              batch_size=batch_size,
                              shuffle=True,
                              num_workers=4,
                              pin_memory=True)
    valid_loader = DataLoader(valid_dataset,
                              batch_size=batch_size,
                              shuffle=False,
                              num_workers=4,
                              pin_memory=True)

    if 'unet' in net_config['dec_type']:
        model = EncoderDecoderNet(**net_config).to(device)
    else:
        model = SPPNet(**net_config).to(device)
    loss_fn = CrossEntropy2d(**loss_config).to(device)
    optimizer, scheduler = create_optimizer(model=model, **opt_config)

    train()
from models.net import SPPNet
from dataset.cityscapes import CityscapesDataset
from dataset.bdd100k import BDD100KDataset
from dataset.avm import AVMDataset
from utils.preprocess import minmax_normalize

import datetime
from torchsummary import summary

import cv2

device = torch.device('cuda:2' if torch.cuda.is_available() else 'cpu')
torch.cuda.set_device(device)
#model = SPPNet(output_channels=19).to(device)
model = SPPNet(output_channels=4, enc_type='xception65',
               dec_type='aspp').to(device)
summary(model, (3, 128, 256))
#model_path = '../model/cityscapes_deeplab_v3_plus/model.pth'
#model_path = '../model/cityscapes_mobilenetv2/model.pth'
#model_path = '../model/cityscapes_deeplabv3p_mobilenetv2/model_tmp.pth'
#model_path = '../model/bdd100k_deeplabv3p_mobilenetv2/model_tmp.pth'
model_path = '../model/avm_deeplabv3p_xception65/model_tmp.pth'
#model_path = '../model/cityscapes_deeplabv3p_double_epoch/model.pth'
param = torch.load(model_path)
model.load_state_dict(param)
del param

batch_size = 1

#valid_dataset = BDD100KDataset(split='valid', net_type='deeplab')
valid_dataset = AVMDataset(split='valid', net_type='deeplab')
Ejemplo n.º 14
0
def eval_from_model(split,
                    output_channels,
                    model_path,
                    postproc=False,
                    vis=True,
                    debug=True):

    model_path = Path(model_path)
    path, model_dir = os.path.split(
        model_path.parent)  # separate path and filename
    device = torch.device('cuda:0' if torch.cuda.is_available() else
                          'cpu')  #work on GPU if available

    print(f'Device: {device}')

    if 'mnv2' in model_dir:
        model = SPPNet(enc_type='mobilenetv2',
                       dec_type='maspp',
                       output_channels=output_channels).to(device)
        defaults = True
    else:
        model = SPPNet(output_channels=output_channels).to(device)
        defaults = False

    if device == torch.device('cpu'):
        param = torch.load(model_path, map_location='cpu'
                           )  # parameters saved in checkpoint via model_path
    else:
        param = torch.load(
            model_path)  # parameters saved in checkpoint via model_path

    print(f'Parameters loaded from {model_path}')

    model.load_state_dict(param)  #apply method load_state_dict to model?
    del param  # delete parameters? Reduce memory usage?

    dataset = SherbrookeDataset(
        split=split, net_type='deeplab',
        defaults=defaults)  #reach cityscapes dataset, validation split
    classes = np.arange(1, dataset.n_classes)
    img_paths = dataset.img_paths
    base_dir = dataset.base_dir
    split = dataset.split
    if len(img_paths) == 0:
        raise ValueError('Your dataset seems empty...')
    else:
        print(f'{len(img_paths)} images found in {base_dir}\\{split}')

    model.eval()  #apply eval method on model. ?

    #print(f'Files containing \'{filetype}\' will be converted to \'{colortype}\' colormap and saved to:\n{output_folder}')

    valid_ious = []
    count = 0
    predicted_boxes = {}
    ground_truth_boxes = {}

    with torch.no_grad():
        #dataloader is a 2 element list with images and labels as torch tensors
        print('Generating predictions...')

        with tqdm(range(len(dataset))) as _tqdm:
            for i in _tqdm:
                count += 1
                image, label = dataset[i]
                img_path = dataset.img_paths[i]
                #filename = img_path.stem
                filename = img_path.name

                #if isinstance(image, tuple): #take only image in label is also returned by __getitem__
                #    image = image[0]

                image = image[
                    None]  # mimick dataloader with 4th channel (batch channel)
                image = image.to(device)
                # next line reaches to tta.py --> net.py --> xception.py ...
                # output: predictions (segmentation maps)
                pred = model.tta(image, net_type='deeplab')
                # pred = model(image)
                # pred = F.interpolate(pred, size=label.shape, mode='bilinear', align_corners=True)
                # pred = pred.argmax(dim=1)
                pred = pred.detach().cpu().numpy()
                label = label.numpy()

                # take first pred of single item list of preds...
                pred = pred[0]

                pred = softmax_from_feat_map(pred)

                # take channel corresponding to softmax scores in class 1. Reduces array to 2D
                pred = pred[1, :, :]

                if pred.shape[1] / pred.shape[0] == 4:
                    pred = topcrop(pred, reverse=True)
                    label = topcrop(label, reverse=True)

                if debug:
                    print(
                        f'Prediction shape after evaluation: {pred.shape}\nLabel shape: {label.shape}'
                    )

                if defaults:
                    # set all pixel in pred corresponding to an ignore_pixel in label to 0
                    pred[label == dataset.ignore_index] = 0

                #perc = round(len(np.unique(pred)) *0.5) #find index at median
                #val_at_perc = np.unique(pred)[perc]
                val_at_perc = 0.0002
                #print(
                #    f'Value at median in prediction is: {val_at_perc}')

                pred_masked = np.where(pred >= val_at_perc, pred, np.nan)
                pred_binary = threshold(
                    pred.copy(), value=val_at_perc
                )  # set values under 0.5 to 0, else to 1. result: binary array
                bbox_list, scores_list = contour_proc(pred_binary, pred_masked)

                #add key to predicted_boxes: {'filename': {'boxes':bbox_list, 'scores':scores_list}}
                predicted_boxes.update(
                    {filename: {
                        "boxes": bbox_list,
                        "scores": scores_list
                    }})

                #pred = filter_by_activation(pred, percentile=90)
                #pred = threshold(pred)

                bbox_list_lbl, _ = contour_proc(label, label.copy())

                #add key to predicted_boxes: {'filename': {'boxes':bbox_list, 'scores':scores_list}}
                ground_truth_boxes.update({filename: bbox_list_lbl})

                if debug:
                    print(f'Label unique values: {np.unique(label)}')

                _tqdm.set_postfix(OrderedDict(last_image=f'{filename}'))

    with open('predicted_boxes_GSV.json', 'w') as json_file:
        json.dump(predicted_boxes, json_file, sort_keys=True)

    with open('ground_truth_boxes_GSV.json', 'w') as json_file:
        json.dump(ground_truth_boxes, json_file, sort_keys=True)
Ejemplo n.º 15
0
class Tester:
    def __init__(
            self,
            model_path='../model/deepglobe_deeplabv3_weights-cityscapes_19-outputs/model.pth',
            dataset='deepglobe',
            output_channels=19,
            split='valid',
            net_type='deeplab',
            batch_size=1,
            shuffle=True):
        """
        Initializes the tester by loading the model with the good parameters.
        :param model_path: Path to model weights
        :param dataset: dataset used amongst {'deepglobe', 'pascal', 'cityscapes'}
        :param output_channels: num of output channels of model
        :param split: split to be used amongst {'train', 'valid'}
        :param net_type: model type to be used amongst {'deeplab', 'unet'}
        :param batch_size: batch size when loading images (always 1 here)
        :param shuffle: when loading images from dataset
        """
        model_path = '/home/sfoucher/DEV/pytorch-segmentation/model/my_pascal_unet_res18_scse/model.pth'
        dataset_dir = '/home/sfoucher/DEV/pytorch-segmentation/data/deepglobe_as_pascalvoc/VOCdevkit/VOC2012'

        output_channels = 8
        net_type = 'unet'
        print('[Tester] [Init] Initializing tester...')
        self.dataset = dataset
        self.model_path = model_path

        # Load model
        print('[Tester] [Init] Loading model ' + model_path + ' with ' +
              str(output_channels) + ' output channels...')

        self.device = torch.device(
            'cuda:0' if torch.cuda.is_available() else 'cpu')
        if net_type == 'unet':
            self.model = EncoderDecoderNet(output_channels=8,
                                           enc_type='resnet18',
                                           dec_type='unet_scse',
                                           num_filters=8)
        else:
            self.model = SPPNet(output_channels=output_channels).to(
                self.device)
        param = torch.load(model_path)
        self.model.load_state_dict(param)
        del param

        # Create data loader depending on dataset, split and net type
        if dataset == 'pascal':
            self.valid_dataset = PascalVocDataset(split=split,
                                                  net_type=net_type)
        elif dataset == 'cityscapes':
            self.valid_dataset = CityscapesDataset(split=split,
                                                   net_type=net_type)
        elif dataset == 'deepglobe':
            self.valid_dataset = DeepGlobeDataset(base_dir=dataset_dir,
                                                  target_size=(64, 64),
                                                  split=split,
                                                  net_type=net_type)
        else:
            raise NotImplementedError

        self.valid_loader = DataLoader(self.valid_dataset,
                                       batch_size=batch_size,
                                       shuffle=shuffle)

        print('[Tester] [Init] ...done!')
        print('[Tester] [Init] Tester created.')

    def make_demo_image(self):
        """
        Picks 4 images from dataset randomly and creates image with raw, inferred and label pictures.
        :return: null
        """
        images_list = []
        labels_list = []
        preds_list = []

        print('[Tester] [Demo] Gathering images and inferring...')
        self.model.eval()
        with torch.no_grad():
            for batched in self.valid_loader:
                images, labels = batched
                images_np = images.numpy().transpose(0, 2, 3, 1)
                labels_np = labels.numpy()

                images, labels = images.to(self.device), labels.to(self.device)
                preds = self.model.tta(images, net_type='deeplab')
                preds = preds.argmax(dim=1)
                preds_np = preds.detach().cpu().numpy()

                images_list.append(images_np)
                labels_list.append(labels_np)
                preds_list.append(preds_np)

                if len(images_list) == 4:
                    break

        print('[Tester] [Demo] Processing results...')

        images = np.concatenate(images_list)
        labels = np.concatenate(labels_list)
        preds = np.concatenate(preds_list)

        # Ignore index
        ignore_pixel = labels == 255
        preds[ignore_pixel] = 0
        labels[ignore_pixel] = 0

        # Plot
        fig, axes = plt.subplots(4, 3, figsize=(12, 10))
        plt.tight_layout()

        axes[0, 0].set_title('input image')
        axes[0, 1].set_title('prediction')
        axes[0, 2].set_title('ground truth')

        for ax, img, lbl, pred in zip(axes, images, labels, preds):
            ax[0].imshow(
                minmax_normalize(img, norm_range=(0, 1), orig_range=(-1, 1)))
            ax[1].imshow(pred)
            ax[2].imshow(lbl)
            ax[0].set_xticks([])
            ax[0].set_yticks([])
            ax[1].set_xticks([])
            ax[1].set_yticks([])
            ax[2].set_xticks([])
            ax[2].set_yticks([])

        plt.savefig('eval.png')
        plt.show()
        plt.close()

    def infer_image_by_path(
            self,
            image_path='/home/ubuntu/data/Segmentation/pytorch-segmentation/test1.jpg',
            output_name='single_test_output',
            display=False):
        """
        Opens image from fs and passes it through the loaded network, then displays and saves the result.
        :param output_name: Output image name
        :param display: Display images in windows or not
        :param image_path: Path of input images
        :return: null
        """
        if not self.dataset == 'deepglobe':
            print(
                '[ERROR] Inference script only available for the Deepglobe dataset.'
            )
            exit(-1)

        print('[Tester] [Single test] Opening image ' + image_path + '...')
        # Open and prepare image
        input_img = Image.open(image_path)
        if display:
            input_img.show()

        custom_img = np.array(input_img)
        custom_img = minmax_normalize(custom_img, norm_range=(-1, 1))
        custom_img = custom_img.transpose(2, 0, 1)
        custom_img = torch.FloatTensor([custom_img])

        print('[Tester] [Single test] Inferring image...')
        self.model.eval().to(self.device)
        with torch.no_grad():
            # Send to GPU, infer and collect
            custom_img = custom_img.to(self.device)
            #preds = self.model.tta(custom_img, net_type='deeplab')
            preds = self.model.tta(custom_img, net_type='unet')
            preds = preds.argmax(dim=1)
            preds_np = preds.detach().cpu().numpy()

        print('[Tester] [Single test] Processing result...')

        good_preds = preds_np[0]
        good_mask = Image.fromarray(good_preds.astype('uint8'), 'P')

        # Transform mask to set good indexes and palette
        good_mask = DeepGlobeDataset.index_to_palette(good_mask)

        if display:
            good_mask.show()
        good_mask.save(output_name + '_prediction.png')

        overlay = Tester.make_overlay(good_mask, input_img, 100)
        if display:
            overlay.show()
        overlay.save(output_name + '_overlay.png')
        print('[Tester] [Single test] Done.')

    def infer_image_by_name(self,
                            image_name='255876',
                            output_name='single_test_output',
                            display=True):
        """
        Opens image from fs and passes it through the loaded network, then displays and saves the result.
        :param output_name: Output image name
        :param display: Display images in windows or not
        :param image_path: Path of input images
        :return: null
        """
        if not self.dataset == 'deepglobe':
            print(
                '[ERROR] Inference script only available for the Deepglobe dataset.'
            )
            exit(-1)

        print('[Tester] [Single test] Opening image ' + image_name + '...')
        # Open and prepare image
        input_img = Image.open(
            '/home/ubuntu/data/Segmentation/pytorch-segmentation/data/deepglobe_as_pascalvoc/VOCdevkit/VOC2012/JPEGImages/'
            + image_name + '.jpg')
        label = Image.open(
            '/home/ubuntu/data/Segmentation/pytorch-segmentation/data/deepglobe_as_pascalvoc/VOCdevkit/VOC2012/SegmentationClass/'
            + image_name + '.png')
        label_raw = copy.deepcopy(label)
        overlay_ground_truth = Tester.make_overlay(label_raw, input_img, 100)
        label = label.convert('P', palette=Image.WEB)

        if display:
            input_img.show(title='Input raw image')
            label.show(title='Ground truth')
            overlay_ground_truth.show(title='Overlay_ground_truth')

        custom_img = np.array(input_img)
        custom_img = minmax_normalize(custom_img, norm_range=(-1, 1))
        custom_img = custom_img.transpose(2, 0, 1)
        custom_img = torch.FloatTensor([custom_img])

        print('[Tester] [Single test] Inferring image...')
        self.model.eval()
        with torch.no_grad():
            # Send to GPU, infer and collect
            custom_img = custom_img.to(self.device)
            preds = self.model.tta(custom_img, net_type='deeplab')
            preds = preds.argmax(dim=1)
            preds_np = preds.detach().cpu().numpy()

        print('[Tester] [Single test] Processing result...')

        good_preds = preds_np[0]
        good_mask = Image.fromarray(good_preds.astype('uint8'), 'P')

        # Transform mask to set good indexes and palette
        good_mask = DeepGlobeDataset.index_to_palette(good_mask)

        overlay = Tester.make_overlay(good_mask, input_img, 100)
        if display:
            good_mask.show(title='Prediction')
            overlay.show(title='Overlay')

        good_mask.save(output_name + '_prediction.png')
        overlay.save(output_name + '_overlay.png')
        overlay_ground_truth.save(output_name + '_overlay_truth.png')

        print('[Tester] [Single test] Done.')

    @staticmethod
    def make_overlay(pred_in, img_in, transparency):
        """
        Build PIL image from input img and mask overlay with given transparency.
        :param pred_in: mask input
        :param img_in: img input
        :param transparency: transparency wanted between 0..255
        :return: PIL image result
        """
        pred = copy.deepcopy(pred_in)
        img = copy.deepcopy(img_in)
        print('[Tester] [Overlay] Building overlay...')
        if transparency < 0 or transparency > 255:
            print('ERROR : Transparency should be in range 0..255.')
            exit(-1)
        # Make preds semi_transparent
        pred = pred.convert('RGBA')
        data = pred.getdata()  # you'll get a list of tuples
        new_data = []
        for a in data:
            a = a[:3]  # you'll get your tuple shorten to RGB
            a = a + (
                transparency,
            )  # change the 100 to any transparency number you like between (0,255)
            new_data.append(a)
        pred.putdata(new_data)  # you'll get your new img ready

        # Paste translucid preds on input image
        img.paste(pred, (0, 0), pred)
        print('[Tester] [Overlay] Done.')
        return img
Ejemplo n.º 16
0
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
t_max = opt_config['t_max']

max_epoch = train_config['max_epoch']
batch_size = train_config['batch_size']
fp16 = train_config['fp16']
resume = train_config['resume']
pretrained_path = train_config['pretrained_path']

# Network
if 'unet' in net_config['dec_type']:
    net_type = 'unet'
    model = EncoderDecoderNet(**net_config)
else:
    net_type = 'deeplab'
    model = SPPNet(**net_config)

dataset = data_config['dataset']
if dataset == 'pascal':
    from dataset.pascal_voc import PascalVocDataset as Dataset
    net_config['output_channels'] = 21
    classes = np.arange(1, 21)
elif dataset == 'cityscapes':
    from dataset.cityscapes import CityscapesDataset as Dataset
    net_config['output_channels'] = 19
    classes = np.arange(1, 19)
elif dataset == 'sherbrooke':
    from dataset.sherbrooke import SherbrookeDataset as Dataset
    net_config['output_channels'] = 2
    classes = np.arange(1, 2)
else:
Ejemplo n.º 17
0
import matplotlib.pyplot as plt

import torch
import torch.nn.functional as F
from torch.utils.data import DataLoader

from models.net import SPPNet
from dataset.cityscapes import CityscapesDataset
from utils.preprocess import minmax_normalize

import datetime
from torchsummary import summary

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
#model = SPPNet(output_channels=19).to(device)
model = SPPNet(output_channels=19, enc_type='mobilenetv2',
               dec_type='maspp').to(device)
summary(model, (3, 128, 256))
model_path = '../model/cityscapes_deeplab_v3_plus/model.pth'
#model_path = '../model/cityscapes_mobilenetv2/model.pth'
#model_path = '../model/cityscapes_deeplabv3p_mobilenetv2/model_tmp.pth'
param = torch.load(model_path)
model.load_state_dict(param)
del param

batch_size = 1

valid_dataset = CityscapesDataset(split='valid', net_type='deeplab')
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=True)

images_list = []
labels_list = []
Ejemplo n.º 18
0
def eval_from_model(split,
                    output_channels,
                    model_path,
                    postproc=False,
                    vis=True,
                    debug=True,
                    mean_AP=False):

    model_path = Path(model_path)
    path, model_dir = os.path.split(
        model_path.parent)  # separate path and filename
    device = torch.device('cuda:0' if torch.cuda.is_available() else
                          'cpu')  #work on GPU if available

    print(f'Device: {device}')

    if 'mnv2' in model_dir:
        model = SPPNet(enc_type='mobilenetv2',
                       dec_type='maspp',
                       output_channels=output_channels).to(device)
        defects = True
    else:
        model = SPPNet(output_channels=output_channels).to(device)
        defects = False

    if device == torch.device('cpu'):
        param = torch.load(model_path, map_location='cpu'
                           )  # parameters saved in checkpoint via model_path
    else:
        param = torch.load(
            model_path)  # parameters saved in checkpoint via model_path

    print(f'Parameters loaded from {model_path}')

    model.load_state_dict(param)  #apply method load_state_dict to model?
    del param  # delete parameters? Reduce memory usage?

    dataset = SherbrookeDataset(
        split=split, net_type='deeplab',
        defects=defects)  #reach cityscapes dataset, validation split
    classes = np.arange(1, dataset.n_classes)
    img_paths = dataset.img_paths
    base_dir = dataset.base_dir
    split = dataset.split
    if len(img_paths) == 0:
        raise ValueError('Your dataset seems empty...')
    else:
        print(f'{len(img_paths)} images found in {base_dir}\\{split}')

    model.eval()  #apply eval method on model. ?

    #print(f'Files containing \'{filetype}\' will be converted to \'{colortype}\' colormap and saved to:\n{output_folder}')

    valid_ious = []
    count = 0
    predicted_boxes = {}
    ground_truth_boxes = {}

    with torch.no_grad():
        #dataloader is a 2 element list with images and labels as torch tensors
        print('Generating predictions...')

        with tqdm(range(len(dataset))) as _tqdm:
            for i in _tqdm:
                count += 1
                if count % 1 == 10:
                    print(f'Evaluation progress: {count}/{len(img_paths)}')
                image, label = dataset[i]
                img_path = dataset.img_paths[i]
                orig_image = np.array(Image.open(img_path))
                filename = img_path.name

                #if isinstance(image, tuple): #take only image in label is also returned by __getitem__
                #    image = image[0]

                image = image[
                    None]  # mimick dataloader with 4th channel (batch channel)
                image = image.to(device)
                # next line reaches to tta.py --> net.py --> xception.py ...
                # output: predictions (segmentation maps)
                pred = model.tta(image, net_type='deeplab')
                # pred = model(image)
                # pred = F.interpolate(pred, size=label.shape, mode='bilinear', align_corners=True)

                # take first pred of single item list of preds...
                pred = pred[0]

                softmax = torch.nn.Softmax(dim=1)
                pred = softmax(pred)
                #pred = softmax_from_feat_map(pred)

                pred = pred.detach().cpu().numpy()
                label = label.numpy()

                if pred.shape[1] / pred.shape[0] == 2:
                    pred, label = dataset.postprocess(pred, label)

                if mean_AP and not postproc:
                    raise Exception(
                        'postproc argument in eval_from_model function must be true if mean_AP is set to True'
                    )
                elif postproc:
                    # take channel corresponding to softmax scores in channel 1 (class 1). Reduces array to 2D
                    pred = pred[1, :, :]

                    if dataset.defects:
                        # set all pixel in pred corresponding to an ignore_pixel in label to 0
                        pred[label == dataset.ignore_index] = 0

                    if mean_AP:
                        val_at_perc = 0.0002
                        # print(
                        #    f'Value at median in prediction is: {val_at_perc}')

                        #create array copy and wreplace all values under threshold by nan values
                        pred_masked = np.where(pred >= val_at_perc, pred,
                                               np.nan)

                        #create copy of pred array and set all values above threshold to 1 and under to 0
                        pred_binary = threshold(pred.copy(), value=val_at_perc)

                        # set values under 0.5 to 0, else to 1. result: binary array
                        bbox_list, scores_list = contour_proc(
                            pred_binary, pred_masked)

                        # add key to predicted_boxes: {'filename': {'boxes':bbox_list, 'scores':scores_list}}
                        predicted_boxes.update({
                            filename: {
                                "boxes": bbox_list,
                                "scores": scores_list
                            }
                        })

                        # pred = filter_by_activation(pred, percentile=90)
                        # pred = threshold(pred)

                        bbox_list_lbl, _ = contour_proc(label, label.copy())

                        # add key to predicted_boxes: {'filename': {'boxes':bbox_list, 'scores':scores_list}}
                        ground_truth_boxes.update({filename: bbox_list_lbl})

                        pred_masked = np.where(pred >= val_at_perc, pred,
                                               np.nan)
                        pred_binary = threshold(
                            pred.copy(), value=val_at_perc
                        )  # set values under 0.5 to 0, else to 1. result: binary array
                        bbox_list, scores_list = contour_proc(
                            pred_binary, pred_masked)

                        #add key to predicted_boxes: {'filename': {'boxes':bbox_list, 'scores':scores_list}}
                        predicted_boxes.update({
                            filename: {
                                "boxes": bbox_list,
                                "scores": scores_list
                            }
                        })

                    pred = filter_by_activation(pred, percentile=90)

                else:
                    pred = np.argmax(pred, axis=0)

                if debug:
                    print(f'Label unique values: {np.unique(label)}')

                # print(np.unique(pred))
                if output_channels == 19:
                    # create mask for values other than 0 (background) and 1(sidewalk)
                    for i in range(2, 19):
                        pred[
                            pred ==
                            i] = 0  # convert these classes to background value

                if dataset.split == 'val':
                    # compute iou
                    iou = compute_iou_batch(pred, label, classes)
                    print(f'Iou for {filename}: {iou}')
                    valid_ious.append(iou)

                if vis:

                    output_dir = Path(
                        f'../data/output/{model_dir}/{split}/{os.path.split(img_path.parent)[1]}'
                    )
                    output_dir.mkdir(parents=True, exist_ok=True)

                    folder = output_dir.joinpath('figures')
                    folder.mkdir(parents=True, exist_ok=True)
                    label[label == 255] = 0
                    conf_overlay = np.add(label, pred * 2)
                    print(np.unique(conf_overlay))
                    confus_overlay = vis_segmentation(conf_overlay, img_path)
                    confus_overlay.save(
                        folder.joinpath(f'{filename}_overlay.jpg'))

                elif dataset.split == 'bootstrap':
                    # convert 1 values to 8. For bootstrapping.
                    pred = encode_mask(pred)

                    pred_pil = Image.fromarray(pred.astype(np.uint8))
                    img_pil = Image.open(img_path)
                    if pred_pil.size != img_pil.size:
                        pred_pil = pred_pil.resize(
                            (img_pil.size[0], img_pil.size[1]), Image.NEAREST)

                    pred_pil.save(
                        output_dir.joinpath(f'{filename}_gtFine_labelIds.png'))
                    #save_colormap(pred[0], savename, output_dir, filetype, colortype=colortype)
                else:
                    raise NotImplementedError

            _tqdm.set_postfix(OrderedDict(last_image=f'{filename}'))

    if mean_AP:
        with open('predicted_boxes_GSV.json', 'w') as json_file:
            json.dump(predicted_boxes, json_file, sort_keys=True)

        with open('ground_truth_boxes_GSV.json', 'w') as json_file:
            json.dump(ground_truth_boxes, json_file, sort_keys=True)

    if dataset.split == 'val':
        valid_iou = np.nanmean(valid_ious)
        print(f'mean valid iou: {valid_iou}')
        #print(f'Confusion matrix: \n{conf_mat}')

    with open('predicted_boxes_GSV.json', 'w') as json_file:
        json.dump(predicted_boxes, json_file)  # , sort_keys=True)

    with open('ground_truth_boxes_GSV.json', 'w') as json_file:
        json.dump(ground_truth_boxes, json_file, sort_keys=True)

    if vis:
        print(f'Files were be saved to {output_dir.parent}')