class FCNSegmentor(object):
    """
      The class for Pose Estimation. Include train, val, val & predict.
    """
    def __init__(self, configer):
        self.configer = configer
        self.batch_time = AverageMeter()
        self.data_time = AverageMeter()
        self.train_losses = AverageMeter()
        self.val_losses = AverageMeter()
        self.seg_visualizer = SegVisualizer(configer)
        self.seg_loss_manager = SegLossManager(configer)
        self.module_utilizer = ModuleUtilizer(configer)
        self.seg_model_manager = SegModelManager(configer)
        self.seg_data_loader = SegDataLoader(configer)

        self.seg_net = None
        self.train_loader = None
        self.val_loader = None
        self.optimizer = None
        self.lr = None
        self.iters = None

    def init_model(self):
        self.seg_net = self.seg_model_manager.seg_net()
        self.iters = 0
        self.seg_net, _ = self.module_utilizer.load_net(self.seg_net)

        self.optimizer, self.lr = self.module_utilizer.update_optimizer(self.seg_net, self.iters)

        if self.configer.get('dataset') == 'cityscape':
            self.train_loader = self.seg_data_loader.get_trainloader(FSCityScapeLoader)
            self.val_loader = self.seg_data_loader.get_valloader(FSCityScapeLoader)

        else:
            Log.error('Dataset: {} is not valid!'.format(self.configer.get('dataset')))
            exit(1)

        self.pixel_loss = self.seg_loss_manager.get_seg_loss('cross_entropy_loss')

    def __train(self):
        """
          Train function of every epoch during train phase.
        """
        self.seg_net.train()
        start_time = time.time()

        # data_tuple: (inputs, heatmap, maskmap, tagmap, num_objects)
        for i, data_tuple in enumerate(self.train_loader):
            self.data_time.update(time.time() - start_time)
            # Change the data type.
            if len(data_tuple) < 2:
                Log.error('Train Loader Error!')
                exit(0)

            inputs = Variable(data_tuple[0].cuda(async=True))
            targets = Variable(data_tuple[1].cuda(async=True))

            # Forward pass.
            outputs = self.seg_net(inputs)

            # Compute the loss of the train batch & backward.
            loss_pixel = self.pixel_loss(outputs, targets)
            loss = loss_pixel
            self.train_losses.update(loss.data[0], inputs.size(0))
            self.optimizer.zero_grad()
            loss.backward()
            self.optimizer.step()

            # Update the vars of the train phase.
            self.batch_time.update(time.time() - start_time)
            start_time = time.time()
            self.iters += 1

            # Print the log info & reset the states.
            if self.iters % self.configer.get('solver', 'display_iter') == 0:
                Log.info('Train Iteration: {0}\t'
                         'Time {batch_time.sum:.3f}s / {1}iters, ({batch_time.avg:.3f})\t'
                         'Data load {data_time.sum:.3f}s / {1}iters, ({data_time.avg:3f})\n'
                         'Learning rate = {2}\n'
                         'Loss = {loss.val:.8f} (ave = {loss.avg:.8f})\n'.format(
                         self.iters, self.configer.get('solver', 'display_iter'),
                         self.lr, batch_time=self.batch_time,
                         data_time=self.data_time, loss=self.train_losses))
                self.batch_time.reset()
                self.data_time.reset()
                self.train_losses.reset()

            # Check to val the current model.
            if self.val_loader is not None and \
               self.iters % self.configer.get('solver', 'test_interval') == 0:
                self.__val()

            self.optimizer, self.lr = self.module_utilizer.update_optimizer(self.seg_net, self.iters)

    def __val(self):
        """
          Validation function during the train phase.
        """
        self.seg_net.eval()
        start_time = time.time()

        for j, data_tuple in enumerate(self.val_loader):
            # Change the data type.
            inputs = Variable(data_tuple[0].cuda(async=True), volatile=True)
            targets = Variable(data_tuple[1].cuda(async=True), volatile=True)
            # Forward pass.
            outputs = self.seg_net(inputs)
            # Compute the loss of the val batch.
            loss_pixel = self.pixel_loss(outputs, targets)
            loss = loss_pixel

            self.val_losses.update(loss.data[0], inputs.size(0))

            # Update the vars of the val phase.
            self.batch_time.update(time.time() - start_time)
            start_time = time.time()

        self.module_utilizer.save_net(self.seg_net, self.iters)
        # Print the log info & reset the states.
        Log.info(
            'Test Time {batch_time.sum:.3f}s, ({batch_time.avg:.3f})\t'
            'Loss {loss.avg:.8f}\n'.format(
            batch_time=self.batch_time, loss=self.val_losses))
        self.batch_time.reset()
        self.val_losses.reset()
        self.seg_net.train()

    def train(self):
        cudnn.benchmark = True
        while self.iters < self.configer.get('solver', 'max_iter'):
            self.__train()
            if self.iters == self.configer.get('solver', 'max_iter'):
                break
Example #2
0
class FCNSegmentor(object):
    """
      The class for Pose Estimation. Include train, val, val & predict.
    """
    def __init__(self, configer):
        self.configer = configer
        self.batch_time = AverageMeter()
        self.data_time = AverageMeter()
        self.train_losses = AverageMeter()
        self.val_losses = AverageMeter()
        self.seg_visualizer = SegVisualizer(configer)
        self.seg_loss_manager = SegLossManager(configer)
        self.module_utilizer = ModuleUtilizer(configer)
        self.seg_model_manager = SegModelManager(configer)
        self.seg_data_loader = SegDataLoader(configer)

        self.seg_net = None
        self.train_loader = None
        self.val_loader = None
        self.optimizer = None
        self.lr = None
        self.iters = None

    def init_model(self):
        self.seg_net = self.seg_model_manager.seg_net()
        self.iters = 0
        self.seg_net, _ = self.module_utilizer.load_net(self.seg_net)

        self.optimizer, self.lr = self.module_utilizer.update_optimizer(
            self.seg_net, self.iters)

        if self.configer.get('dataset') == 'cityscape':
            self.train_loader = self.seg_data_loader.get_trainloader(
                FSCityScapeLoader)
            self.val_loader = self.seg_data_loader.get_valloader(
                FSCityScapeLoader)

        else:
            Log.error('Dataset: {} is not valid!'.format(
                self.configer.get('dataset')))
            exit(1)

        self.pixel_loss = self.seg_loss_manager.get_seg_loss(
            'cross_entropy_loss')

    def __train(self):
        """
          Train function of every epoch during train phase.
        """
        self.seg_net.train()
        start_time = time.time()

        # data_tuple: (inputs, heatmap, maskmap, tagmap, num_objects)
        for i, data_tuple in enumerate(self.train_loader):
            self.data_time.update(time.time() - start_time)
            # Change the data type.
            if len(data_tuple) < 2:
                Log.error('Train Loader Error!')
                exit(0)

            inputs = Variable(data_tuple[0].cuda(async=True))
            targets = Variable(data_tuple[1].cuda(async=True))

            # Forward pass.
            outputs = self.seg_net(inputs)

            # Compute the loss of the train batch & backward.
            loss_pixel = self.pixel_loss(outputs, targets)
            loss = loss_pixel
            self.train_losses.update(loss.data[0], inputs.size(0))
            self.optimizer.zero_grad()
            loss.backward()
            self.optimizer.step()

            # Update the vars of the train phase.
            self.batch_time.update(time.time() - start_time)
            start_time = time.time()
            self.iters += 1

            # Print the log info & reset the states.
            if self.iters % self.configer.get('solver', 'display_iter') == 0:
                Log.info(
                    'Train Iteration: {0}\t'
                    'Time {batch_time.sum:.3f}s / {1}iters, ({batch_time.avg:.3f})\t'
                    'Data load {data_time.sum:.3f}s / {1}iters, ({data_time.avg:3f})\n'
                    'Learning rate = {2}\n'
                    'Loss = {loss.val:.8f} (ave = {loss.avg:.8f})\n'.format(
                        self.iters,
                        self.configer.get('solver', 'display_iter'),
                        self.lr,
                        batch_time=self.batch_time,
                        data_time=self.data_time,
                        loss=self.train_losses))
                self.batch_time.reset()
                self.data_time.reset()
                self.train_losses.reset()

            # Check to val the current model.
            if self.val_loader is not None and \
               self.iters % self.configer.get('solver', 'test_interval') == 0:
                self.__val()

            self.optimizer, self.lr = self.module_utilizer.update_optimizer(
                self.seg_net, self.iters)

    def __val(self):
        """
          Validation function during the train phase.
        """
        self.seg_net.eval()
        start_time = time.time()

        for j, data_tuple in enumerate(self.val_loader):
            # Change the data type.
            inputs = Variable(data_tuple[0].cuda(async=True), volatile=True)
            targets = Variable(data_tuple[1].cuda(async=True), volatile=True)
            # Forward pass.
            outputs = self.seg_net(inputs)
            # Compute the loss of the val batch.
            loss_pixel = self.pixel_loss(outputs, targets)
            loss = loss_pixel

            self.val_losses.update(loss.data[0], inputs.size(0))

            # Update the vars of the val phase.
            self.batch_time.update(time.time() - start_time)
            start_time = time.time()

        self.module_utilizer.save_net(self.seg_net, self.iters)
        # Print the log info & reset the states.
        Log.info('Test Time {batch_time.sum:.3f}s, ({batch_time.avg:.3f})\t'
                 'Loss {loss.avg:.8f}\n'.format(batch_time=self.batch_time,
                                                loss=self.val_losses))
        self.batch_time.reset()
        self.val_losses.reset()
        self.seg_net.train()

    def train(self):
        cudnn.benchmark = True
        while self.iters < self.configer.get('solver', 'max_iter'):
            self.__train()
            if self.iters == self.configer.get('solver', 'max_iter'):
                break
Example #3
0
class FCNSegmentorTest(object):
    def __init__(self, configer):
        self.configer = configer

        self.seg_vis = SegVisualizer(configer)
        self.seg_model_manager = SegModelManager(configer)
        self.module_utilizer = ModuleUtilizer(configer)
        self.seg_net = None

    def init_model(self):
        self.seg_net = self.seg_model_manager.seg_net()
        self.seg_net, _ = self.module_utilizer.load_net(self.seg_net)
        self.seg_net.eval()

    def forward(self, image_path):
        image = Image.open(image_path).convert('RGB')
        image = RandomResize(size=self.configer.get('data', 'input_size'),
                             is_base=False)(image)
        image = ToTensor()(image)
        image = Normalize(mean=[128.0, 128.0, 128.0],
                          std=[256.0, 256.0, 256.0])(image)
        inputs = Variable(image.unsqueeze(0).cuda(), volatile=True)
        results = self.seg_net.forward(inputs)
        return results.data.cpu().numpy().argmax(axis=1)[0].squeeze()

    def __test_img(self, image_path, save_path):
        if self.configer.get('dataset') == 'cityscape':
            self.__test_cityscape_img(image_path, save_path)
        elif self.configer.get('dataset') == 'laneline':
            self.__test_laneline_img(image_path, save_path)
        else:
            Log.error('Dataset: {} is not valid.'.format(
                self.configer.get('dataset')))
            exit(1)

    def __test_cityscape_img(self, img_path, save_path):
        color_list = [(128, 64, 128), (244, 35, 232), (70, 70, 70),
                      (102, 102, 156), (190, 153, 153), (153, 153, 153),
                      (250, 170, 30), (220, 220, 0), (107, 142, 35),
                      (152, 251, 152), (70, 130, 180), (220, 20, 60),
                      (255, 0, 0), (0, 0, 142), (0, 0, 70), (0, 60, 100),
                      (0, 80, 100), (0, 0, 230), (119, 11, 32)]

        result = self.forward(img_path)
        width = self.configer.get(
            'data', 'input_size')[0] // self.configer.get('network', 'stride')
        height = self.configer.get(
            'data', 'input_size')[1] // self.configer.get('network', 'stride')
        color_dst = np.zeros((height, width, 3), dtype=np.uint8)
        for i in range(self.configer.get('data', 'num_classes')):
            color_dst[result == i] = color_list[i]

        color_img = np.array(color_dst, dtype=np.uint8)
        color_img = Image.fromarray(color_img, 'RGB')
        color_img.save(save_path)

    def __test_laneline_img(self, img_path, save_path):
        pass

    def test(self):
        base_dir = os.path.join(self.configer.get('project_dir'),
                                'val/results/seg',
                                self.configer.get('dataset'), 'test')
        if not os.path.exists(base_dir):
            os.makedirs(base_dir)

        test_img = self.configer.get('test_img')
        test_dir = self.configer.get('test_dir')
        if test_img is None and test_dir is None:
            Log.error('test_img & test_dir not exists.')
            exit(1)

        if test_img is not None and test_dir is not None:
            Log.error('Either test_img or test_dir.')
            exit(1)

        if test_img is not None:
            filename = test_img.rstrip().split('/')[-1]
            save_path = os.path.join(base_dir, filename)
            self.__test_img(test_img, save_path)

        else:
            for filename in self.__list_dir(test_dir):
                image_path = os.path.join(test_dir, filename)
                save_path = os.path.join(base_dir, filename)
                self.__test_img(image_path, save_path)

    def __create_cityscape_submission(self, test_dir=None, base_dir=None):
        label_list = [
            7, 8, 11, 12, 13, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
            32, 33
        ]

        for filename in self.__list_dir(test_dir):
            image_path = os.path.join(test_dir, filename)
            save_path = os.path.join(base_dir, filename)
            result = self.forward(image_path)
            width = self.configer.get('data',
                                      'input_size')[0] // self.configer.get(
                                          'network', 'stride')
            height = self.configer.get('data',
                                       'input_size')[1] // self.configer.get(
                                           'network', 'stride')
            label_dst = np.ones((height, width), dtype=np.uint8) * 255
            for i in range(self.configer.get('data', 'num_classes')):
                label_dst[result == i] = label_list[i]

            label_img = np.array(label_dst, dtype=np.uint8)
            label_img = Image.fromarray(label_img, 'P')
            label_img.save(save_path)

    def create_submission(self, test_dir=None):
        base_dir = os.path.join(self.configer.get('project_dir'),
                                'val/results/seg',
                                self.configer.get('dataset'), 'submission')
        if not os.path.exists(base_dir):
            os.makedirs(base_dir)

        if self.configer.get('dataset') == 'cityscape':
            self.__create_cityscape_submission(test_dir, base_dir)

        else:
            Log.error('Dataset: {} is not valid.'.format(
                self.configer.get('dataset')))
            exit(1)

    def __list_dir(self, dir_name):
        filename_list = list()
        for item in os.listdir(dir_name):
            if os.path.isdir(item):
                for filename in os.listdir(os.path.join(dir_name, item)):
                    filename_list.append('{}/{}'.format(item, filename))

            else:
                filename_list.append(item)

        return filename_list
class FCNSegmentorTest(object):
    def __init__(self, configer):
        self.configer = configer

        self.seg_vis = SegVisualizer(configer)
        self.seg_model_manager = SegModelManager(configer)
        self.module_utilizer = ModuleUtilizer(configer)
        self.seg_net = None

    def init_model(self):
        self.seg_net = self.seg_model_manager.seg_net()
        self.seg_net, _ = self.module_utilizer.load_net(self.seg_net)
        self.seg_net.eval()

    def forward(self, image_path):
        image = Image.open(image_path).convert('RGB')
        image = RandomResize(size=self.configer.get('data', 'input_size'), is_base=False)(image)
        image = ToTensor()(image)
        image = Normalize(mean=[128.0, 128.0, 128.0], std=[256.0, 256.0, 256.0])(image)
        inputs = Variable(image.unsqueeze(0).cuda(), volatile=True)
        results = self.seg_net.forward(inputs)
        return results.data.cpu().numpy().argmax(axis=1)[0].squeeze()

    def __test_img(self, image_path, save_path):
        if self.configer.get('dataset') == 'cityscape':
            self.__test_cityscape_img(image_path, save_path)
        elif self.configer.get('dataset') == 'laneline':
            self.__test_laneline_img(image_path, save_path)
        else:
            Log.error('Dataset: {} is not valid.'.format(self.configer.get('dataset')))
            exit(1)

    def __test_cityscape_img(self, img_path, save_path):
        color_list = [(128, 64, 128), (244, 35, 232), (70, 70, 70), (102, 102, 156), (190, 153, 153),
                      (153, 153, 153), (250, 170, 30), (220, 220, 0), (107, 142, 35), (152, 251, 152),
                      (70, 130, 180), (220, 20, 60), (255, 0, 0), (0, 0, 142), (0, 0, 70), (0, 60, 100),
                      (0, 80, 100), (0, 0, 230), (119, 11, 32)]

        result = self.forward(img_path)
        width = self.configer.get('data', 'input_size')[0] // self.configer.get('network', 'stride')
        height = self.configer.get('data', 'input_size')[1] // self.configer.get('network', 'stride')
        color_dst = np.zeros((height, width, 3), dtype=np.uint8)
        for i in range(self.configer.get('data', 'num_classes')):
            color_dst[result == i] = color_list[i]

        color_img = np.array(color_dst, dtype=np.uint8)
        color_img = Image.fromarray(color_img, 'RGB')
        color_img.save(save_path)

    def __test_laneline_img(self, img_path, save_path):
        pass

    def test(self):
        base_dir = os.path.join(self.configer.get('project_dir'),
                                'val/results/seg', self.configer.get('dataset'), 'test')
        if not os.path.exists(base_dir):
            os.makedirs(base_dir)

        test_img = self.configer.get('test_img')
        test_dir = self.configer.get('test_dir')
        if test_img is None and test_dir is None:
            Log.error('test_img & test_dir not exists.')
            exit(1)

        if test_img is not None and test_dir is not None:
            Log.error('Either test_img or test_dir.')
            exit(1)

        if test_img is not None:
            filename = test_img.rstrip().split('/')[-1]
            save_path = os.path.join(base_dir, filename)
            self.__test_img(test_img, save_path)

        else:
            for filename in self.__list_dir(test_dir):
                image_path = os.path.join(test_dir, filename)
                save_path = os.path.join(base_dir, filename)
                self.__test_img(image_path, save_path)

    def __create_cityscape_submission(self, test_dir=None, base_dir=None):
        label_list = [7, 8, 11, 12, 13, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 33]

        for filename in self.__list_dir(test_dir):
            image_path = os.path.join(test_dir, filename)
            save_path = os.path.join(base_dir, filename)
            result = self.forward(image_path)
            width = self.configer.get('data', 'input_size')[0] // self.configer.get('network', 'stride')
            height = self.configer.get('data', 'input_size')[1] // self.configer.get('network', 'stride')
            label_dst = np.ones((height, width), dtype=np.uint8) * 255
            for i in range(self.configer.get('data', 'num_classes')):
                label_dst[result == i] = label_list[i]

            label_img = np.array(label_dst, dtype=np.uint8)
            label_img = Image.fromarray(label_img, 'P')
            label_img.save(save_path)

    def create_submission(self, test_dir=None):
        base_dir = os.path.join(self.configer.get('project_dir'),
                                'val/results/seg', self.configer.get('dataset'), 'submission')
        if not os.path.exists(base_dir):
            os.makedirs(base_dir)



        if self.configer.get('dataset') == 'cityscape':
            self.__create_cityscape_submission(test_dir, base_dir)

        else:
            Log.error('Dataset: {} is not valid.'.format(self.configer.get('dataset')))
            exit(1)

    def __list_dir(self, dir_name):
        filename_list = list()
        for item in os.listdir(dir_name):
            if os.path.isdir(item):
                for filename in os.listdir(os.path.join(dir_name, item)):
                    filename_list.append('{}/{}'.format(item, filename))

            else:
                filename_list.append(item)

        return filename_list