def get_blob(self, data_dict, scale=None, flip=False): assert scale is not None img_list, meta_list = [], [] for image, meta in zip(DCHelper.tolist(data_dict['img']), DCHelper.tolist(data_dict['meta'])): c, h, w = image.size() border_hw = [int(h*scale), int(w*scale)] meta['border_hw'] = border_hw image = TensorHelper.resize(image, border_hw, mode='bilinear', align_corners=True) if flip: image = image.flip([2]) if self.configer.exists('test', 'fit_stride'): stride = self.configer.get('test', 'fit_stride') pad_w = 0 if (border_hw[1] % stride == 0) else stride - (border_hw[1] % stride) # right pad_h = 0 if (border_hw[0] % stride == 0) else stride - (border_hw[0] % stride) # down expand_image = torch.zeros((c, border_hw[0] + pad_h, border_hw[1] + pad_w)).to(image.device) expand_image[:, 0:border_hw[0], 0:border_hw[1]] = image image = expand_image img_list.append(image) meta_list.append(meta) new_data_dict = dict( img=DCHelper.todc(img_list, stack=True, samples_per_gpu=True), meta=DCHelper.todc(meta_list, samples_per_gpu=True, cpu_only=True) ) return new_data_dict
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'] metas = data_dict['meta'] data_dict['bboxes'] = DCHelper.todc( batch_gt_bboxes, gpu_list=self.configer.get('gpu'), cpu_only=True) data_dict['labels'] = DCHelper.todc( batch_gt_labels, gpu_list=self.configer.get('gpu'), cpu_only=True) data_dict['meta'] = DCHelper.todc( metas, gpu_list=self.configer.get('gpu'), cpu_only=True) # Forward pass. inputs = RunnerHelper.to_device(self, inputs) loss, test_group = self.det_net(data_dict) # Compute the loss of the train batch & backward. loss = loss.mean() 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, metas) 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() RunnerHelper.save_net(self, self.det_net, iters=self.runner_state['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 _crop_predict(self, data_dict, crop_size, crop_stride_ratio): split_batch = list() height_starts_list = list() width_starts_list = list() hw_list = list() for image in DCHelper.tolist(data_dict['img']): height, width = image.size()[2:] hw_list.append([height, width]) np_image = image.squeeze(0).permute(1, 2, 0).cpu().numpy() height_starts = self._decide_intersection(height, crop_size[1], crop_stride_ratio) width_starts = self._decide_intersection(width, crop_size[0], crop_stride_ratio) split_crops = [] for height in height_starts: for width in width_starts: image_crop = np_image[height:height + crop_size[1], width:width + crop_size[0]] split_crops.append(image_crop[np.newaxis, :]) height_starts_list.append(height_starts) width_starts_list.append(width_starts) split_crops = np.concatenate(split_crops, axis=0) # (n, crop_image_size, crop_image_size, 3) inputs = torch.from_numpy(split_crops).permute(0, 3, 1, 2).to(self.device) split_batch.append(inputs) out_list = list() with torch.no_grad(): results = self.seg_net.forward(DCHelper.todc(split_batch, stack=True, samples_per_gpu=1)) for res in results: out_list.append(res[-1].permute(0, 2, 3, 1).cpu().numpy()) total_logits = [np.zeros((hw[0], hw[1], self.configer.get('data', 'num_classes')), np.float32) for hw in hw_list] count_predictions = [np.zeros((hw[0], hw[1], self.configer.get('data', 'num_classes')), np.float32) for hw in hw_list] for i in range(len(height_starts_list)): index = 0 for height in height_starts_list[i]: for width in width_starts_list[i]: total_logits[i][height:height+crop_size[1], width:width+crop_size[0]] += out_list[i][index] count_predictions[i][height:height+crop_size[1], width:width+crop_size[0]] += 1 index += 1 for i in range(len(total_logits)): total_logits[i] /= count_predictions[i] for i, meta in enumerate(DCHelper.tolist(data_dict['meta'])): total_logits[i] = cv2.resize(total_logits[i][:meta['border_hw'][0], :meta['border_hw'][1]], (meta['ori_img_size'][0], meta['ori_img_size'][1]), interpolation=cv2.INTER_CUBIC) return total_logits
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.runner_state['epoch'] += 1 for i, data_dict in enumerate(self.train_loader): Trainer.update(self) batch_gt_bboxes = data_dict['bboxes'] batch_gt_labels = data_dict['labels'] metas = data_dict['meta'] data_dict['bboxes'] = DCHelper.todc( batch_gt_bboxes, gpu_list=self.configer.get('gpu'), cpu_only=True) data_dict['labels'] = DCHelper.todc( batch_gt_labels, gpu_list=self.configer.get('gpu'), cpu_only=True) data_dict['meta'] = DCHelper.todc( metas, gpu_list=self.configer.get('gpu'), cpu_only=True) self.data_time.update(time.time() - start_time) # Forward pass. loss = self.det_net(data_dict) loss = loss.mean() self.train_losses.update(loss.item(), data_dict['img'].size(0)) self.optimizer.zero_grad() loss.backward() RunnerHelper.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.runner_state['iters'] += 1 # Print the log info & reset the states. if self.runner_state['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.runner_state['epoch'], self.runner_state['iters'], self.configer.get('solver', 'display_iter'), RunnerHelper.get_lr(self.optimizer), 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() if self.configer.get('lr', 'metric') == 'iters' \ and self.runner_state['iters'] == self.configer.get('solver', 'max_iters'): break # Check to val the current model. if self.runner_state['iters'] % self.configer.get( 'solver', 'test_interval') == 0: self.val()