class RPNPose(object): """ The class for Pose Estimation. Include train, val, test & 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.val_loss_heatmap = AverageMeter() self.val_loss_associate = AverageMeter() self.pose_visualizer = PoseVisualizer(configer) self.pose_loss_manager = PoseLossManager(configer) self.pose_model_manager = PoseModelManager(configer) self.pose_data_loader = PoseDataLoader(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.pose_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None def init_model(self): self.pose_net = self.pose_model_manager.multi_pose_detector() self.pose_net = self.module_utilizer.load_net(self.pose_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.pose_data_loader.get_trainloader() self.val_loader = self.pose_data_loader.get_valloader() self.mse_loss = self.pose_loss_manager.get_pose_loss('mse_loss') self.embeding_loss = self.pose_loss_manager.get_pose_loss( 'embedding_loss') def _get_parameters(self): return self.pose_net.parameters() def __train(self): """ Train function of every epoch during train phase. """ self.pose_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) # data_tuple: (inputs, heatmap, maskmap, vecmap) for i, (inputs, label, heatmap, maskmap, vecmap, tagmap, num_objects) in enumerate(self.train_loader): self.data_time.update(time.time() - start_time) # Change the data type. inputs, label, heatmap, maskmap, vecmap, tagmap = self.module_utilizer.to_device( inputs, label, heatmap, maskmap, vecmap, tagmap) # Forward pass. paf_out, heatmap_out, embed_out = self.pose_net(inputs) # Compute the loss of the train batch & backward. loss_label = self.mse_loss(embed_out.sum(1).squeeze(), label) loss_heatmap = self.mse_loss(heatmap_out, heatmap, maskmap) loss_paf = self.mse_loss(paf_out, vecmap, maskmap) loss_associate = self.embeding_loss(embed_out, tagmap, num_objects) loss = loss_label + loss_heatmap + loss_paf + loss_associate self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters') % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.pose_net.eval() start_time = time.time() with torch.no_grad(): for j, (inputs, label, heatmap, maskmap, vecmap, tagmap, num_objects) in enumerate(self.val_loader): # Change the data type. inputs, label, heatmap, maskmap, vecmap, tagmap = self.module_utilizer.to_device( inputs, label, heatmap, maskmap, vecmap, tagmap) # Forward pass. paf_out, heatmap_out, embed_out = self.pose_net(inputs) # Compute the loss of the val batch. loss_label = self.mse_loss(embed_out, label) loss_heatmap = self.mse_loss(heatmap_out, heatmap, maskmap) loss_paf = self.mse_loss(paf_out, vecmap, maskmap) loss_associate = self.embeding_loss(embed_out, tagmap, num_objects) loss = loss_label + loss_heatmap + loss_paf + loss_associate self.val_losses.update(loss.item(), inputs.size(0)) self.val_loss_heatmap.update(loss_heatmap.item(), inputs.size(0)) self.val_loss_associate.update(loss_associate.item(), 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.pose_net, metric='iters') Log.info('Loss Heatmap:{}, Loss Asso: {}'.format( self.val_loss_heatmap.avg, self.val_loss_associate.avg)) # 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.pose_net.train() def train(self): cudnn.benchmark = True while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
class YOLOv3(object): """ The class for YOLO v3. Include train, val, test & 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.det_visualizer = DetVisualizer(configer) self.det_loss_manager = DetLossManager(configer) self.det_model_manager = DetModelManager(configer) self.det_data_loader = DetDataLoader(configer) self.yolo_detection_layer = YOLODetectionLayer(configer) self.yolo_target_generator = YOLOTargetGenerator(configer) self.det_running_score = DetRunningScore(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.det_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.det_net = self.det_model_manager.object_detector() self.det_net = self.module_utilizer.load_net(self.det_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.det_data_loader.get_trainloader() self.val_loader = self.det_data_loader.get_valloader() self.det_loss = self.det_loss_manager.get_det_loss('yolov3_loss') def _get_parameters(self): lr_1 = [] lr_10 = [] params_dict = dict(self.det_net.named_parameters()) for key, value in params_dict.items(): if 'backbone.' not in key: lr_10.append(value) else: lr_1.append(value) params = [{ 'params': lr_1, 'lr': self.configer.get('lr', 'base_lr') }, { 'params': lr_10, 'lr': self.configer.get('lr', 'base_lr') * 10. }] return params def warm_lr(self, batch_len): """Sets the learning rate # Adapted from PyTorch Imagenet example: # https://github.com/pytorch/examples/blob/master/imagenet/main.py """ warm_iters = self.configer.get('lr', 'warm')['warm_epoch'] * batch_len if self.configer.get('iters') < warm_iters: lr_ratio = (self.configer.get('iters') + 1) / warm_iters base_lr_list = self.scheduler.get_lr() for param_group, base_lr in zip(self.optimizer.param_groups, base_lr_list): param_group['lr'] = base_lr * lr_ratio if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info('LR: {}'.format([ param_group['lr'] for param_group in self.optimizer.param_groups ])) def __train(self): """ Train function of every epoch during train phase. """ self.det_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) # data_tuple: (inputs, heatmap, maskmap, vecmap) for i, data_dict in enumerate(self.train_loader): if not self.configer.is_empty( 'lr', 'is_warm') and self.configer.get('lr', 'is_warm'): self.warm_lr(len(self.train_loader)) inputs = data_dict['img'] batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] input_size = [inputs.size(3), inputs.size(2)] self.data_time.update(time.time() - start_time) # Change the data type. inputs = self.module_utilizer.to_device(inputs) # Forward pass. feat_list, predictions, _ = self.det_net(inputs) targets, objmask, noobjmask = self.yolo_target_generator( feat_list, batch_gt_bboxes, batch_gt_labels, input_size) targets, objmask, noobjmask = self.module_utilizer.to_device( targets, objmask, noobjmask) # Compute the loss of the train batch & backward. loss = self.det_loss(predictions, targets, objmask, noobjmask) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters')) % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.det_net.eval() start_time = time.time() with torch.no_grad(): for i, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] input_size = [inputs.size(3), inputs.size(2)] # Forward pass. inputs = self.module_utilizer.to_device(inputs) feat_list, predictions, detections = self.det_net(inputs) targets, objmask, noobjmask = self.yolo_target_generator( feat_list, batch_gt_bboxes, batch_gt_labels, input_size) targets, objmask, noobjmask = self.module_utilizer.to_device( targets, objmask, noobjmask) # Compute the loss of the val batch. loss = self.det_loss(predictions, targets, objmask, noobjmask) self.val_losses.update(loss.item(), inputs.size(0)) batch_detections = YOLOv3Test.decode(detections, self.configer) batch_pred_bboxes = self.__get_object_list( batch_detections, input_size) self.det_running_score.update(batch_pred_bboxes, batch_gt_bboxes, batch_gt_labels) # 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.det_net, save_mode='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)) Log.info('Val mAP: {}'.format(self.det_running_score.get_mAP())) self.det_running_score.reset() self.batch_time.reset() self.val_losses.reset() self.det_net.train() def __get_object_list(self, batch_detections, input_size): batch_pred_bboxes = list() for idx, detections in enumerate(batch_detections): object_list = list() if detections is not None: for x1, y1, x2, y2, conf, cls_conf, cls_pred in detections: xmin = x1.cpu().item() * input_size[0] ymin = y1.cpu().item() * input_size[1] xmax = x2.cpu().item() * input_size[0] ymax = y2.cpu().item() * input_size[1] cf = conf.cpu().item() cls_pred = cls_pred.cpu().item() object_list.append([ xmin, ymin, xmax, ymax, int(cls_pred), float('%.2f' % cf) ]) batch_pred_bboxes.append(object_list) return batch_pred_bboxes def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get( 'network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
class ConvPoseMachine(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.pose_visualizer = PoseVisualizer(configer) self.pose_loss_manager = PoseLossManager(configer) self.pose_model_manager = PoseModelManager(configer) self.pose_data_loader = PoseDataLoader(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.data_transformer = DataTransformer(configer) self.heatmap_generator = HeatmapGenerator(configer) self.pose_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.pose_net = self.pose_model_manager.single_pose_detector() self.pose_net = self.module_utilizer.load_net(self.pose_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer(self._get_parameters()) self.train_loader = self.pose_data_loader.get_trainloader() self.val_loader = self.pose_data_loader.get_valloader() self.mse_loss = self.pose_loss_manager.get_pose_loss('mse_loss') def _get_parameters(self): return self.pose_net.parameters() def __train(self): """ Train function of every epoch during train phase. """ self.pose_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) # data_tuple: (inputs, heatmap, maskmap, tagmap, num_objects) for i, data_dict in enumerate(self.train_loader): inputs = data_dict['img'] input_size = [inputs.size(3), inputs.size(2)] heatmap = self.heatmap_generator(data_dict['kpts'], input_size) self.data_time.update(time.time() - start_time) # Change the data type. inputs, heatmap = self.module_utilizer.to_device(inputs, heatmap) # self.pose_visualizer.vis_peaks(heatmap[0], inputs[0], name='cpm') # Forward pass. outputs = self.pose_net(inputs) # Compute the loss of the train batch & backward. loss = self.mse_loss(outputs, heatmap, maskmap) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get('solver', 'display_iter') == 0: Log.info('Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n'.format( self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters') % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.pose_net.eval() start_time = time.time() with torch.no_grad(): for j, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] input_size = [inputs.size(3), inputs.size(2)] heatmap = self.heatmap_generator(data_dict['kpts'], input_size) # Change the data type. inputs, heatmap = self.module_utilizer.to_device(inputs, heatmap) # Forward pass. outputs = self.pose_net(inputs) # Compute the loss of the val batch. loss = self.mse_loss(outputs[-1], heatmap) self.val_losses.update(loss.item(), 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.pose_net, save_mode='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.pose_net.train() def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get('network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get('solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get('solver', 'max_epoch'): break
class FCClassifier(object): """ The class for the training phase of Image classification. """ def __init__(self, configer): self.configer = configer self.batch_time = AverageMeter() self.data_time = AverageMeter() self.train_losses = AverageMeter() self.val_losses = AverageMeter() self.cls_loss_manager = ClsLossManager(configer) self.cls_model_manager = ClsModelManager(configer) self.cls_data_loader = ClsDataLoader(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.cls_running_score = ClsRunningScore(configer) self.cls_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.cls_net = self.cls_model_manager.image_classifier() self.cls_net = self.module_utilizer.load_net(self.cls_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.cls_data_loader.get_trainloader() self.val_loader = self.cls_data_loader.get_valloader() self.ce_loss = self.cls_loss_manager.get_cls_loss('cross_entropy_loss') def _get_parameters(self): return self.cls_net.parameters() def __train(self): """ Train function of every epoch during train phase. """ self.cls_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) for i, data_dict in enumerate(self.train_loader): inputs = data_dict['img'] labels = data_dict['label'] self.data_time.update(time.time() - start_time) # Change the data type. inputs, labels = self.module_utilizer.to_device(inputs, labels) # Forward pass. outputs = self.cls_net(inputs) outputs = self.module_utilizer.gather(outputs) # Compute the loss of the train batch & backward. loss = self.ce_loss(outputs, labels) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters') % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.cls_net.eval() start_time = time.time() with torch.no_grad(): for j, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] labels = data_dict['label'] # Change the data type. inputs, labels = self.module_utilizer.to_device(inputs, labels) # Forward pass. outputs = self.cls_net(inputs) outputs = self.module_utilizer.gather(outputs) # Compute the loss of the val batch. loss = self.ce_loss(outputs, labels) self.cls_running_score.update(outputs, labels) self.val_losses.update(loss.item(), 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.cls_net, save_mode='iters') # Print the log info & reset the states. Log.info('Test Time {batch_time.sum:.3f}s'.format( batch_time=self.batch_time)) Log.info('TestLoss = {loss.avg:.8f}'.format(loss=self.val_losses)) Log.info('Top1 ACC = {}'.format( self.cls_running_score.get_top1_acc())) Log.info('Top5 ACC = {}'.format( self.cls_running_score.get_top5_acc())) self.batch_time.reset() self.val_losses.reset() self.cls_running_score.reset() self.cls_net.train() def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get( 'network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
class OpenPose(object): """ The class for Pose Estimation. Include train, val, test & predict. """ def __init__(self, configer): self.configer = configer self.batch_time = AverageMeter() self.data_time = AverageMeter() self.train_losses = AverageMeter() self.train_loss_heatmap = AverageMeter() self.train_loss_associate = AverageMeter() self.val_losses = AverageMeter() self.val_loss_heatmap = AverageMeter() self.val_loss_associate = AverageMeter() self.pose_visualizer = PoseVisualizer(configer) self.pose_loss_manager = PoseLossManager(configer) self.pose_model_manager = PoseModelManager(configer) self.pose_data_loader = PoseDataLoader(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.heatmap_generator = HeatmapGenerator(configer) self.paf_generator = PafGenerator(configer) self.data_transformer = DataTransformer(configer) self.pose_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.pose_net = self.pose_model_manager.multi_pose_detector() self.pose_net = self.module_utilizer.load_net(self.pose_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.pose_data_loader.get_trainloader() self.val_loader = self.pose_data_loader.get_valloader() self.weights = self.configer.get('network', 'loss_weights') self.mse_loss = self.pose_loss_manager.get_pose_loss('mse_loss') def _get_parameters(self): lr_1 = [] lr_2 = [] lr_4 = [] lr_8 = [] params_dict = dict(self.pose_net.named_parameters()) for key, value in params_dict.items(): if ('model1_' not in key) and ('model0.' not in key) and ('backbone.' not in key): if key[-4:] == 'bias': lr_8.append(value) else: lr_4.append(value) elif key[-4:] == 'bias': lr_2.append(value) else: lr_1.append(value) params = [{ 'params': lr_1, 'lr': self.configer.get('lr', 'base_lr') }, { 'params': lr_2, 'lr': self.configer.get('lr', 'base_lr') * 2., 'weight_decay': 0.0 }, { 'params': lr_4, 'lr': self.configer.get('lr', 'base_lr') * 4. }, { 'params': lr_8, 'lr': self.configer.get('lr', 'base_lr') * 8., 'weight_decay': 0.0 }] return params def __train(self): """ Train function of every epoch during train phase. """ self.pose_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) # data_tuple: (inputs, heatmap, maskmap, vecmap) for i, data_dict in enumerate(self.train_loader): inputs = data_dict['img'] maskmap = data_dict['maskmap'] input_size = [inputs.size(3), inputs.size(2)] heatmap = self.heatmap_generator(data_dict['kpts'], input_size, maskmap=maskmap) vecmap = self.paf_generator(data_dict['kpts'], input_size, maskmap=maskmap) self.data_time.update(time.time() - start_time) # Change the data type. inputs, heatmap, maskmap, vecmap = self.module_utilizer.to_device( inputs, heatmap, maskmap, vecmap) # Forward pass. paf_out, heatmap_out = self.pose_net(inputs) # Compute the loss of the train batch & backward. loss_heatmap = self.mse_loss(heatmap_out, heatmap, mask=maskmap, weights=self.weights) loss_associate = self.mse_loss(paf_out, vecmap, mask=maskmap, weights=self.weights) loss = loss_heatmap + loss_associate self.train_losses.update(loss.item(), inputs.size(0)) self.train_loss_heatmap.update(loss_heatmap.item(), inputs.size(0)) self.train_loss_associate.update(loss_associate.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info('Loss Heatmap:{}, Loss Asso: {}'.format( self.train_loss_heatmap.avg, self.train_loss_associate.avg)) Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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() self.train_loss_heatmap.reset() self.train_loss_associate.reset() # Check to val the current model. if self.val_loader is not None and \ self.configer.get('iters') % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.pose_net.eval() start_time = time.time() with torch.no_grad(): for i, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] maskmap = data_dict['maskmap'] input_size = [inputs.size(3), inputs.size(2)] heatmap = self.heatmap_generator(data_dict['kpts'], input_size, maskmap=maskmap) vecmap = self.paf_generator(data_dict['kpts'], input_size, maskmap=maskmap) # Change the data type. inputs, heatmap, maskmap, vecmap = self.module_utilizer.to_device( inputs, heatmap, maskmap, vecmap) # Forward pass. paf_out, heatmap_out = self.pose_net(inputs) # Compute the loss of the val batch. loss_heatmap = self.mse_loss(heatmap_out[-1], heatmap, maskmap) loss_associate = self.mse_loss(paf_out[-1], vecmap, maskmap) loss = loss_heatmap + loss_associate self.val_losses.update(loss.item(), inputs.size(0)) self.val_loss_heatmap.update(loss_heatmap.item(), inputs.size(0)) self.val_loss_associate.update(loss_associate.item(), 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.pose_net, save_mode='iters') Log.info('Loss Heatmap:{}, Loss Asso: {}'.format( self.val_loss_heatmap.avg, self.val_loss_associate.avg)) # 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.val_loss_heatmap.reset() self.val_loss_associate.reset() self.pose_net.train() def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get( 'network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
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_running_score = SegRunningScore(configer) self.seg_visualizer = SegVisualizer(configer) self.seg_loss_manager = SegLossManager(configer) self.module_utilizer = ModuleUtilizer(configer) self.data_transformer = DataTransformer(configer) self.seg_model_manager = SegModelManager(configer) self.seg_data_loader = SegDataLoader(configer) self.optim_scheduler = OptimScheduler(configer) self.seg_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.seg_net = self.seg_model_manager.semantic_segmentor() self.seg_net = self.module_utilizer.load_net(self.seg_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.seg_data_loader.get_trainloader() self.val_loader = self.seg_data_loader.get_valloader() self.pixel_loss = self.seg_loss_manager.get_seg_loss('fcn_seg_loss') if self.configer.get('network', 'bn_type') == 'syncbn': self.pixel_loss = DataParallelCriterion(self.pixel_loss).cuda() def _get_parameters(self): lr_1 = [] lr_10 = [] params_dict = dict(self.seg_net.named_parameters()) for key, value in params_dict.items(): if 'backbone.' not in key: lr_10.append(value) else: lr_1.append(value) params = [{ 'params': lr_1, 'lr': self.configer.get('lr', 'base_lr') }, { 'params': lr_10, 'lr': self.configer.get('lr', 'base_lr') * 1.0 }] return params def __train(self): """ Train function of every epoch during train phase. """ self.seg_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.scheduler.step(self.configer.get('epoch')) for i, data_dict in enumerate(self.train_loader): inputs = data_dict['img'] targets = data_dict['labelmap'] self.data_time.update(time.time() - start_time) # Change the data type. inputs, targets = self.module_utilizer.to_device(inputs, targets) # Forward pass. outputs = self.seg_net(inputs) # Compute the loss of the train batch & backward. loss = self.pixel_loss(outputs, targets) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters') % self.configer.get('solver', 'test_interval') == 0: self.__val() self.configer.plus_one('epoch') def __val(self): """ Validation function during the train phase. """ self.seg_net.eval() start_time = time.time() for j, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] targets = data_dict['labelmap'] with torch.no_grad(): # Change the data type. inputs, targets = self.module_utilizer.to_device( inputs, targets) # Forward pass. outputs = self.seg_net(inputs) # Compute the loss of the val batch. loss = self.pixel_loss(outputs, targets) outputs = self.module_utilizer.gather(outputs) pred = outputs[0] self.val_losses.update(loss.item(), inputs.size(0)) self.seg_running_score.update( pred.max(1)[1].cpu().numpy(), targets.cpu().numpy()) # Update the vars of the val phase. self.batch_time.update(time.time() - start_time) start_time = time.time() self.configer.update_value(['performance'], self.seg_running_score.get_mean_iou()) self.configer.update_value(['val_loss'], self.val_losses.avg) self.module_utilizer.save_net(self.seg_net, save_mode='performance') self.module_utilizer.save_net(self.seg_net, save_mode='val_loss') # 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)) Log.info('Mean IOU: {}\n'.format( self.seg_running_score.get_mean_iou())) self.batch_time.reset() self.val_losses.reset() self.seg_running_score.reset() self.seg_net.train() def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get( 'network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
class FasterRCNN(object): """ The class for Single Shot Detector. Include train, val, test & 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.det_visualizer = DetVisualizer(configer) self.det_loss_manager = DetLossManager(configer) self.det_model_manager = DetModelManager(configer) self.det_data_loader = DetDataLoader(configer) self.fr_priorbox_layer = FRPriorBoxLayer(configer) self.rpn_target_generator = RPNTargetGenerator(configer) self.det_running_score = DetRunningScore(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.det_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.det_net = self.det_model_manager.object_detector() self.det_net = self.module_utilizer.load_net(self.det_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.det_data_loader.get_trainloader() self.val_loader = self.det_data_loader.get_valloader() self.fr_loss = self.det_loss_manager.get_det_loss('fr_loss') def _get_parameters(self): lr_1 = [] lr_2 = [] params_dict = dict(self.det_net.named_parameters()) for key, value in params_dict.items(): if value.requires_grad: if 'bias' in key: lr_2.append(value) else: lr_1.append(value) params = [{ 'params': lr_1, 'lr': self.configer.get('lr', 'base_lr') }, { 'params': lr_2, 'lr': self.configer.get('lr', 'base_lr') * 2., 'weight_decay': 0 }] return params def __train(self): """ Train function of every epoch during train phase. """ self.det_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) for i, data_dict in enumerate(self.train_loader): inputs = data_dict['img'] img_scale = data_dict['imgscale'] batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] self.data_time.update(time.time() - start_time) # Change the data type. gt_bboxes, gt_nums, gt_labels = self.__make_tensor( batch_gt_bboxes, batch_gt_labels) gt_bboxes, gt_num, gt_labels = self.module_utilizer.to_device( gt_bboxes, gt_nums, gt_labels) inputs = self.module_utilizer.to_device(inputs) # Forward pass. feat_list, train_group = self.det_net(inputs, gt_bboxes, gt_num, gt_labels, img_scale) gt_rpn_locs, gt_rpn_labels = self.rpn_target_generator( feat_list, batch_gt_bboxes, [inputs.size(3), inputs.size(2)]) gt_rpn_locs, gt_rpn_labels = self.module_utilizer.to_device( gt_rpn_locs, gt_rpn_labels) rpn_locs, rpn_scores, sample_roi_locs, sample_roi_scores, gt_roi_bboxes, gt_roi_labels = train_group # Compute the loss of the train batch & backward. loss = self.fr_loss( [rpn_locs, rpn_scores, sample_roi_locs, sample_roi_scores], [gt_rpn_locs, gt_rpn_labels, gt_roi_bboxes, gt_roi_labels]) self.train_losses.update(loss.item(), inputs.size(0)) self.optimizer.zero_grad() loss.backward() self.module_utilizer.clip_grad(self.det_net, 10.) self.optimizer.step() # Update the vars of the train phase. self.batch_time.update(time.time() - start_time) start_time = time.time() self.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters')) % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.det_net.eval() start_time = time.time() with torch.no_grad(): for j, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] img_scale = data_dict['imgscale'] batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] # Change the data type. gt_bboxes, gt_nums, gt_labels = self.__make_tensor( batch_gt_bboxes, batch_gt_labels) gt_bboxes, gt_num, gt_labels = self.module_utilizer.to_device( gt_bboxes, gt_nums, gt_labels) inputs = self.module_utilizer.to_device(inputs) # Forward pass. feat_list, train_group, test_group = self.det_net( inputs, gt_bboxes, gt_nums, gt_labels, img_scale) rpn_locs, rpn_scores, sample_roi_locs, sample_roi_scores, gt_roi_bboxes, gt_roi_labels = train_group gt_rpn_locs, gt_rpn_labels = self.rpn_target_generator( feat_list, batch_gt_bboxes, [inputs.size(3), inputs.size(2)]) gt_rpn_locs, gt_rpn_labels = self.module_utilizer.to_device( gt_rpn_locs, gt_rpn_labels) # Compute the loss of the train batch & backward. loss = self.fr_loss( [rpn_locs, rpn_scores, sample_roi_locs, sample_roi_scores], [gt_rpn_locs, gt_rpn_labels, gt_roi_bboxes, gt_roi_labels]) self.val_losses.update(loss.item(), inputs.size(0)) test_indices_and_rois, test_roi_locs, test_roi_scores, test_rois_num = test_group batch_detections = FastRCNNTest.decode( test_roi_locs, test_roi_scores, test_indices_and_rois, test_rois_num, self.configer, [inputs.size(3), inputs.size(2)]) batch_pred_bboxes = self.__get_object_list(batch_detections) self.det_running_score.update(batch_pred_bboxes, batch_gt_bboxes, batch_gt_labels) # 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.det_net, save_mode='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)) Log.info('Val mAP: {}\n'.format(self.det_running_score.get_mAP())) self.det_running_score.reset() self.batch_time.reset() self.val_losses.reset() self.det_net.train() def __make_tensor(self, gt_bboxes, gt_labels): len_arr = [gt_labels[i].numel() for i in range(len(gt_bboxes))] batch_maxlen = max(max(len_arr), 1) target_bboxes = torch.zeros((len(gt_bboxes), batch_maxlen, 4)).float() target_labels = torch.zeros((len(gt_bboxes), batch_maxlen)).long() for i in range(len(gt_bboxes)): if len_arr[i] == 0: continue target_bboxes[i, :len_arr[i], :] = gt_bboxes[i].clone() target_labels[i, :len_arr[i]] = gt_labels[i].clone() target_bboxes_num = torch.Tensor(len_arr).long() return target_bboxes, target_bboxes_num, target_labels def __get_object_list(self, batch_detections): batch_pred_bboxes = list() for idx, detections in enumerate(batch_detections): object_list = list() if detections is not None: for x1, y1, x2, y2, conf, cls_pred in detections: xmin = x1.cpu().item() ymin = y1.cpu().item() xmax = x2.cpu().item() ymax = y2.cpu().item() cf = conf.cpu().item() cls_pred = int(cls_pred.cpu().item()) - 1 object_list.append( [xmin, ymin, xmax, ymax, cls_pred, float('%.2f' % cf)]) batch_pred_bboxes.append(object_list) return batch_pred_bboxes def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get( 'network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
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_running_score = SegRunningScore(configer) 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.optim_scheduler = OptimScheduler(configer) self.seg_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None def init_model(self): self.seg_net = self.seg_model_manager.semantic_segmentor() self.seg_net = self.module_utilizer.load_net(self.seg_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.seg_data_loader.get_trainloader() self.val_loader = self.seg_data_loader.get_valloader() self.pixel_loss = self.seg_loss_manager.get_seg_loss( 'cross_entropy_loss') def _get_parameters(self): return self.seg_net.parameters() def __train(self): """ Train function of every epoch during train phase. """ if self.configer.get( 'network', 'resume') is not None and self.configer.get('iters') == 0: self.__val() self.seg_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) for i, (inputs, targets) in enumerate(self.train_loader): self.data_time.update(time.time() - start_time) # Change the data type. inputs, targets = self.module_utilizer.to_device(inputs, targets) # Forward pass. outputs = self.seg_net(inputs) # Compute the loss of the train batch & backward. loss = self.pixel_loss(outputs, targets) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters') % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.seg_net.eval() start_time = time.time() with torch.no_grad(): for j, (inputs, targets) in enumerate(self.val_loader): # Change the data type. inputs, targets = self.module_utilizer.to_device( inputs, targets) # Forward pass. outputs = self.seg_net(inputs) # Compute the loss of the val batch. loss = self.pixel_loss(outputs, targets) self.val_losses.update(loss.item(), inputs.size(0)) self.seg_running_score.update( outputs.max(1)[1].unsqueeze(1).data, targets.data) # Update the vars of the val phase. self.batch_time.update(time.time() - start_time) start_time = time.time() self.configer.update_value(['performace'], self.seg_running_score.get_mean_iou()) self.configer.update_value(['val_loss'], self.val_losses.avg) self.module_utilizer.save_net(self.seg_net, metric='performance') self.module_utilizer.save_net(self.seg_net, metric='val_loss') # 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)) Log.info('Mean IOU: {}'.format( self.seg_running_score.get_mean_iou())) self.batch_time.reset() self.val_losses.reset() self.seg_running_score.reset() self.seg_net.train() def train(self): cudnn.benchmark = True while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
class SingleShotDetector(object): """ The class for Single Shot Detector. Include train, val, test & 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.det_visualizer = DetVisualizer(configer) self.det_loss_manager = DetLossManager(configer) self.det_model_manager = DetModelManager(configer) self.det_data_loader = DetDataLoader(configer) self.ssd_target_generator = SSDTargetGenerator(configer) self.ssd_priorbox_layer = SSDPriorBoxLayer(configer) self.det_running_score = DetRunningScore(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.data_transformer = DataTransformer(configer) self.det_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None self._init_model() def _init_model(self): self.det_net = self.det_model_manager.object_detector() self.det_net = self.module_utilizer.load_net(self.det_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.det_data_loader.get_trainloader() self.val_loader = self.det_data_loader.get_valloader() self.det_loss = self.det_loss_manager.get_det_loss('ssd_multibox_loss') def _get_parameters(self): return self.det_net.parameters() def warm_lr(self, batch_len): """Sets the learning rate # Adapted from PyTorch Imagenet example: # https://github.com/pytorch/examples/blob/master/imagenet/main.py """ warm_iters = self.configer.get('lr', 'warm')['warm_epoch'] * batch_len warm_lr = self.configer.get('lr', 'warm')['warm_lr'] if self.configer.get('iters') < warm_iters: lr_delta = (self.configer.get('lr', 'base_lr') - warm_lr) * self.configer.get('iters') / warm_iters lr = warm_lr + lr_delta for param_group in self.optimizer.param_groups: param_group['lr'] = lr def __train(self): """ Train function of every epoch during train phase. """ self.det_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) # data_tuple: (inputs, heatmap, maskmap, vecmap) for i, data_dict in enumerate(self.train_loader): if not self.configer.is_empty( 'lr', 'is_warm') and self.configer.get('lr', 'is_warm'): self.warm_lr(len(self.train_loader)) inputs = data_dict['img'] batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] # Change the data type. inputs = self.module_utilizer.to_device(inputs) self.data_time.update(time.time() - start_time) # Forward pass. feat_list, loc, cls = self.det_net(inputs) bboxes, labels = self.ssd_target_generator( feat_list, batch_gt_bboxes, batch_gt_labels, [inputs.size(3), inputs.size(2)]) bboxes, labels = self.module_utilizer.to_device(bboxes, labels) # Compute the loss of the train batch & backward. loss = self.det_loss(loc, bboxes, cls, labels) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters')) % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.det_net.eval() start_time = time.time() with torch.no_grad(): for j, data_dict in enumerate(self.val_loader): inputs = data_dict['img'] batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] inputs = self.module_utilizer.to_device(inputs) input_size = [inputs.size(3), inputs.size(2)] # Forward pass. feat_list, loc, cls = self.det_net(inputs) bboxes, labels = self.ssd_target_generator( feat_list, batch_gt_bboxes, batch_gt_labels, input_size) bboxes, labels = self.module_utilizer.to_device(bboxes, labels) # Compute the loss of the val batch. loss = self.det_loss(loc, bboxes, cls, labels) self.val_losses.update(loss.item(), inputs.size(0)) batch_detections = SingleShotDetectorTest.decode( loc, cls, self.ssd_priorbox_layer(feat_list, input_size), self.configer, input_size) batch_pred_bboxes = self.__get_object_list(batch_detections) # batch_pred_bboxes = self._get_gt_object_list(batch_gt_bboxes, batch_gt_labels) self.det_running_score.update(batch_pred_bboxes, batch_gt_bboxes, batch_gt_labels) # 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.det_net, save_mode='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)) Log.info('Val mAP: {}'.format(self.det_running_score.get_mAP())) self.det_running_score.reset() self.batch_time.reset() self.val_losses.reset() self.det_net.train() def _get_gt_object_list(self, batch_gt_bboxes, batch_gt_labels): batch_pred_bboxes = list() for i in range(len(batch_gt_bboxes)): object_list = list() if batch_gt_bboxes[i].numel() > 0: for j in range(batch_gt_bboxes[i].size(0)): object_list.append([ batch_gt_bboxes[i][j][0].item(), batch_gt_bboxes[i][j][1].item(), batch_gt_bboxes[i][j][2].item(), batch_gt_bboxes[i][j][3].item(), batch_gt_labels[i][j].item(), 1.0 ]) batch_pred_bboxes.append(object_list) return batch_pred_bboxes def __get_object_list(self, batch_detections): batch_pred_bboxes = list() for idx, detections in enumerate(batch_detections): object_list = list() if detections is not None: for x1, y1, x2, y2, conf, cls_pred in detections: xmin = x1.cpu().item() ymin = y1.cpu().item() xmax = x2.cpu().item() ymax = y2.cpu().item() cf = conf.cpu().item() cls_pred = cls_pred.cpu().item() - 1 object_list.append([ xmin, ymin, xmax, ymax, int(cls_pred), float('%.2f' % cf) ]) batch_pred_bboxes.append(object_list) return batch_pred_bboxes def train(self): cudnn.benchmark = True if self.configer.get('network', 'resume') is not None and self.configer.get( 'network', 'resume_val'): self.__val() while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break
class SingleShotDetector(object): """ The class for Single Shot Detector. Include train, val, test & 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.det_visualizer = DetVisualizer(configer) self.det_loss_manager = DetLossManager(configer) self.det_model_manager = DetModelManager(configer) self.det_data_loader = DetDataLoader(configer) self.module_utilizer = ModuleUtilizer(configer) self.optim_scheduler = OptimScheduler(configer) self.det_net = None self.train_loader = None self.val_loader = None self.optimizer = None self.scheduler = None def init_model(self): self.det_net = self.det_model_manager.object_detector() self.det_net = self.module_utilizer.load_net(self.det_net) self.optimizer, self.scheduler = self.optim_scheduler.init_optimizer( self._get_parameters()) self.train_loader = self.det_data_loader.get_trainloader() self.val_loader = self.det_data_loader.get_valloader() self.det_loss = self.det_loss_manager.get_det_loss('multibox_loss') def _get_parameters(self): return self.det_net.parameters() def __train(self): """ Train function of every epoch during train phase. """ if self.configer.get( 'network', 'resume') is not None and self.configer.get('iters') == 0: self.__val() self.det_net.train() start_time = time.time() # Adjust the learning rate after every epoch. self.configer.plus_one('epoch') self.scheduler.step(self.configer.get('epoch')) # data_tuple: (inputs, heatmap, maskmap, vecmap) for i, (inputs, bboxes, labels) in enumerate(self.train_loader): self.data_time.update(time.time() - start_time) # Change the data type. inputs, bboxes, labels = self.module_utilizer.to_device( inputs, bboxes, labels) # Forward pass. loc, cls = self.det_net(inputs) # Compute the loss of the train batch & backward. loss = self.det_loss(loc, bboxes, cls, labels) self.train_losses.update(loss.item(), 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.configer.plus_one('iters') # Print the log info & reset the states. if self.configer.get('iters') % self.configer.get( 'solver', 'display_iter') == 0: Log.info( 'Train Epoch: {0}\tTrain Iteration: {1}\t' 'Time {batch_time.sum:.3f}s / {2}iters, ({batch_time.avg:.3f})\t' 'Data load {data_time.sum:.3f}s / {2}iters, ({data_time.avg:3f})\n' 'Learning rate = {3}\tLoss = {loss.val:.8f} (ave = {loss.avg:.8f})\n' .format(self.configer.get('epoch'), self.configer.get('iters'), self.configer.get('solver', 'display_iter'), self.scheduler.get_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.configer.get('iters')) % self.configer.get('solver', 'test_interval') == 0: self.__val() def __val(self): """ Validation function during the train phase. """ self.det_net.eval() start_time = time.time() with torch.no_grad(): for j, (inputs, bboxes, labels) in enumerate(self.val_loader): # Change the data type. inputs, bboxes, labels = self.module_utilizer.to_device( inputs, bboxes, labels) # Forward pass. loc, cls = self.det_net(inputs) # Compute the loss of the val batch. loss = self.det_loss(loc, bboxes, cls, labels) self.val_losses.update(loss.item(), 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.det_net, metric='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.det_net.train() def train(self): cudnn.benchmark = True while self.configer.get('epoch') < self.configer.get( 'solver', 'max_epoch'): self.__train() if self.configer.get('epoch') == self.configer.get( 'solver', 'max_epoch'): break