class Trainer(): def __init__(self, cfg_data, pwd): self.cfg_data = cfg_data self.train_loader, self.val_loader, self.restore_transform = datasets.loading_data(cfg.DATASET) self.data_mode = cfg.DATASET self.exp_name = cfg.EXP_NAME self.exp_path = cfg.EXP_PATH self.pwd = pwd self.net_name = cfg.NET self.net = CrowdCounter(cfg.GPU_ID,self.net_name).cuda() self.optimizer = optim.Adam(self.net.CCN.parameters(), lr=cfg.LR, weight_decay=1e-4) # self.optimizer = optim.SGD(self.net.parameters(), cfg.LR, momentum=0.95,weight_decay=5e-4) self.scheduler = StepLR(self.optimizer, step_size=cfg.NUM_EPOCH_LR_DECAY, gamma=cfg.LR_DECAY) self.train_record = {'best_mae': 1e20, 'best_mse':1e20, 'best_nae':1e20, 'best_model_name': ''} self.timer = {'iter time' : Timer(),'train time' : Timer(),'val time' : Timer()} self.epoch = 0 self.i_tb = 0 if cfg.PRE_GCC: self.net.load_state_dict(torch.load(cfg.PRE_GCC_MODEL)) if cfg.RESUME: latest_state = torch.load(cfg.RESUME_PATH) self.net.load_state_dict(latest_state['net']) self.optimizer.load_state_dict(latest_state['optimizer']) self.scheduler.load_state_dict(latest_state['scheduler']) self.epoch = latest_state['epoch'] + 1 self.i_tb = latest_state['i_tb'] self.train_record = latest_state['train_record'] self.exp_path = latest_state['exp_path'] self.exp_name = latest_state['exp_name'] self.writer, self.log_txt = logger(self.exp_path, self.exp_name, self.pwd, 'exp', resume=cfg.RESUME) def forward(self): # self.validate() for epoch in range(self.epoch,cfg.MAX_EPOCH): self.epoch = epoch # training self.timer['train time'].tic() self.train() self.timer['train time'].toc(average=False) print( 'train time: {:.2f}s'.format(self.timer['train time'].diff) ) print( '='*20 ) # validation if epoch%cfg.VAL_FREQ==0 or epoch>cfg.VAL_DENSE_START: self.timer['val time'].tic() self.validate() self.timer['val time'].toc(average=False) print( 'val time: {:.2f}s'.format(self.timer['val time'].diff) ) if epoch > cfg.LR_DECAY_START: self.scheduler.step() def train(self): # training for all datasets self.net.train() for i, data in enumerate(self.train_loader, 0): self.timer['iter time'].tic() img, gt_map = data img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() self.optimizer.zero_grad() pred_map, _ = self.net(img, gt_map) loss = self.net.loss loss.backward() self.optimizer.step() if (i + 1) % cfg.PRINT_FREQ == 0: self.i_tb += 1 self.writer.add_scalar('train_loss', loss.item(), self.i_tb) self.timer['iter time'].toc(average=False) print( '[ep %d][it %d][loss %.4f][lr %.4f][%.2fs]' % \ (self.epoch + 1, i + 1, loss.item(), self.optimizer.param_groups[0]['lr']*10000, self.timer['iter time'].diff) ) print( ' [cnt: gt: %.1f pred: %.2f]' % (gt_map[0].sum().data/self.cfg_data.LOG_PARA, pred_map[0].sum().data/self.cfg_data.LOG_PARA) ) def validate(self): self.net.eval() losses = AverageMeter() maes = AverageMeter() mses = AverageMeter() naes = AverageMeter() c_maes = {'level':AverageCategoryMeter(5), 'illum':AverageCategoryMeter(4)} c_mses = {'level':AverageCategoryMeter(5), 'illum':AverageCategoryMeter(4)} c_naes = {'level':AverageCategoryMeter(5), 'illum':AverageCategoryMeter(4)} for vi, data in enumerate(self.val_loader, 0): img, dot_map, attributes_pt = data with torch.no_grad(): img = Variable(img).cuda() dot_map = Variable(dot_map).cuda() # crop the img and gt_map with a max stride on x and y axis # size: HW: __C_NWPU.TRAIN_SIZE # stack them with a the batchsize: __C_NWPU.TRAIN_BATCH_SIZE crop_imgs, crop_dots, crop_masks = [], [], [] b, c, h, w = img.shape rh, rw = self.cfg_data.TRAIN_SIZE for i in range(0, h, rh): gis, gie = max(min(h-rh, i), 0), min(h, i+rh) for j in range(0, w, rw): gjs, gje = max(min(w-rw, j), 0), min(w, j+rw) crop_imgs.append(img[:, :, gis:gie, gjs:gje]) crop_dots.append(dot_map[:, :, gis:gie, gjs:gje]) mask = torch.zeros_like(dot_map).cuda() mask[:, :, gis:gie, gjs:gje].fill_(1.0) crop_masks.append(mask) crop_imgs, crop_dots, crop_masks = map(lambda x: torch.cat(x, dim=0), (crop_imgs, crop_dots, crop_masks)) # forward may need repeatng crop_preds, crop_dens = [], [] nz, bz = crop_imgs.size(0), self.cfg_data.TRAIN_BATCH_SIZE for i in range(0, nz, bz): gs, gt = i, min(nz, i+bz) crop_pred, crop_den = self.net.forward(crop_imgs[gs:gt], crop_dots[gs:gt]) crop_preds.append(crop_pred) crop_dens.append(crop_den) crop_preds = torch.cat(crop_preds, dim=0) crop_dens = torch.cat(crop_dens, dim=0) # splice them to the original size idx = 0 pred_map = torch.zeros_like(dot_map).cuda() den_map = torch.zeros_like(dot_map).cuda() for i in range(0, h, rh): gis, gie = max(min(h-rh, i), 0), min(h, i+rh) for j in range(0, w, rw): gjs, gje = max(min(w-rw, j), 0), min(w, j+rw) pred_map[:, :, gis:gie, gjs:gje] += crop_preds[idx] den_map[:, :, gis:gie, gjs:gje] += crop_dens[idx] idx += 1 # for the overlapping area, compute average value mask = crop_masks.sum(dim=0).unsqueeze(0) pred_map = pred_map / mask den_map = den_map / mask pred_map = pred_map.data.cpu().numpy() dot_map = dot_map.data.cpu().numpy() den_map = den_map.data.cpu().numpy() pred_cnt = np.sum(pred_map)/self.cfg_data.LOG_PARA gt_count = np.sum(dot_map)/self.cfg_data.LOG_PARA s_mae = abs(gt_count-pred_cnt) s_mse = (gt_count-pred_cnt)*(gt_count-pred_cnt) losses.update(self.net.loss.item()) maes.update(s_mae) mses.update(s_mse) attributes_pt = attributes_pt.squeeze() c_maes['level'].update(s_mae,attributes_pt[1]) c_mses['level'].update(s_mse,attributes_pt[1]) c_maes['illum'].update(s_mae,attributes_pt[0]) c_mses['illum'].update(s_mse,attributes_pt[0]) if gt_count != 0: s_nae = abs(gt_count-pred_cnt)/gt_count naes.update(s_nae) c_naes['level'].update(s_nae,attributes_pt[1]) c_naes['illum'].update(s_nae,attributes_pt[0]) if vi==0: vis_results(self.exp_name, self.epoch, self.writer, self.restore_transform, img, pred_map, den_map) loss = losses.avg overall_mae = maes.avg overall_mse = np.sqrt(mses.avg) overall_nae = naes.avg self.writer.add_scalar('val_loss', loss, self.epoch + 1) self.writer.add_scalar('overall_mae', overall_mae, self.epoch + 1) self.writer.add_scalar('overall_mse', overall_mse, self.epoch + 1) self.writer.add_scalar('overall_nae', overall_nae, self.epoch + 1) self.train_record = update_model(self.net,self.optimizer,self.scheduler,self.epoch,self.i_tb,self.exp_path,self.exp_name, \ [overall_mae, overall_mse, overall_nae, loss],self.train_record,self.log_txt) print_NWPU_summary(self.exp_name, self.log_txt,self.epoch,[overall_mae, overall_mse, overall_nae, loss],self.train_record,c_maes,c_mses, c_naes)
class Trainer(): def __init__(self, dataloader, cfg_data, pwd): self.cfg_data = cfg_data self.data_mode = cfg.DATASET self.exp_name = cfg.EXP_NAME self.exp_path = cfg.EXP_PATH self.pwd = pwd self.net_name = cfg.NET self.net = CrowdCounter(cfg.GPU_ID,self.net_name).cuda() self.optimizer = optim.Adam(self.net.CCN.parameters(), lr=cfg.LR, weight_decay=1e-4) # self.optimizer = optim.SGD(self.net.parameters(), cfg.LR, momentum=0.95,weight_decay=5e-4) self.scheduler = StepLR(self.optimizer, step_size=cfg.NUM_EPOCH_LR_DECAY, gamma=cfg.LR_DECAY) self.train_record = {'best_mae': 1e20, 'best_mse':1e20, 'best_model_name': ''} self.timer = {'iter time' : Timer(),'train time' : Timer(),'val time' : Timer()} self.epoch = 0 self.i_tb = 0 if cfg.PRE_GCC: self.net.load_state_dict(torch.load(cfg.PRE_GCC_MODEL)) self.train_loader, self.val_loader, self.restore_transform = dataloader() if cfg.RESUME: latest_state = torch.load(cfg.RESUME_PATH) self.net.load_state_dict(latest_state['net']) self.optimizer.load_state_dict(latest_state['optimizer']) self.scheduler.load_state_dict(latest_state['scheduler']) self.epoch = latest_state['epoch'] + 1 self.i_tb = latest_state['i_tb'] self.train_record = latest_state['train_record'] self.exp_path = latest_state['exp_path'] self.exp_name = latest_state['exp_name'] self.writer, self.log_txt = logger(self.exp_path, self.exp_name, self.pwd, 'exp', resume=cfg.RESUME) def forward(self): # self.validate_V3() for epoch in range(self.epoch,cfg.MAX_EPOCH): self.epoch = epoch if epoch > cfg.LR_DECAY_START: self.scheduler.step() # training self.timer['train time'].tic() self.train() self.timer['train time'].toc(average=False) print 'train time: {:.2f}s'.format(self.timer['train time'].diff) print '='*20 # validation if epoch%cfg.VAL_FREQ==0 or epoch>cfg.VAL_DENSE_START: self.timer['val time'].tic() if self.data_mode in ['SHHA', 'SHHB', 'QNRF', 'UCF50']: self.validate_V1() elif self.data_mode is 'WE': self.validate_V2() elif self.data_mode is 'GCC': self.validate_V3() self.timer['val time'].toc(average=False) print 'val time: {:.2f}s'.format(self.timer['val time'].diff) def train(self): # training for all datasets self.net.train() for i, data in enumerate(self.train_loader, 0): self.timer['iter time'].tic() img, gt_map = data img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() self.optimizer.zero_grad() pred_map = self.net(img, gt_map) loss = self.net.loss loss.backward() self.optimizer.step() if (i + 1) % cfg.PRINT_FREQ == 0: self.i_tb += 1 self.writer.add_scalar('train_loss', loss.item(), self.i_tb) self.timer['iter time'].toc(average=False) print '[ep %d][it %d][loss %.4f][lr %.4f][%.2fs]' % \ (self.epoch + 1, i + 1, loss.item(), self.optimizer.param_groups[0]['lr']*10000, self.timer['iter time'].diff) print ' [cnt: gt: %.1f pred: %.2f]' % (gt_map[0].sum().data/self.cfg_data.LOG_PARA, pred_map[0].sum().data/self.cfg_data.LOG_PARA) def validate_V1(self):# validate_V1 for SHHA, SHHB, UCF-QNRF, UCF50 self.net.eval() losses = AverageMeter() maes = AverageMeter() mses = AverageMeter() for vi, data in enumerate(self.val_loader, 0): img, gt_map = data with torch.no_grad(): img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() pred_map = self.net.forward(img,gt_map) pred_map = pred_map.data.cpu().numpy() gt_map = gt_map.data.cpu().numpy() for i_img in range(pred_map.shape[0]): pred_cnt = np.sum(pred_map[i_img])/self.cfg_data.LOG_PARA gt_count = np.sum(gt_map[i_img])/self.cfg_data.LOG_PARA losses.update(self.net.loss.item()) maes.update(abs(gt_count-pred_cnt)) mses.update((gt_count-pred_cnt)*(gt_count-pred_cnt)) if vi==0: vis_results(self.exp_name, self.epoch, self.writer, self.restore_transform, img, pred_map, gt_map) mae = maes.avg mse = np.sqrt(mses.avg) loss = losses.avg self.writer.add_scalar('val_loss', loss, self.epoch + 1) self.writer.add_scalar('mae', mae, self.epoch + 1) self.writer.add_scalar('mse', mse, self.epoch + 1) self.train_record = update_model(self.net,self.optimizer,self.scheduler,self.epoch,self.i_tb,self.exp_path,self.exp_name, \ [mae, mse, loss],self.train_record,self.log_txt) print_summary(self.exp_name,[mae, mse, loss],self.train_record) def validate_V2(self):# validate_V2 for WE self.net.eval() losses = AverageCategoryMeter(5) maes = AverageCategoryMeter(5) roi_mask = [] from datasets.WE.setting import cfg_data from scipy import io as sio for val_folder in cfg_data.VAL_FOLDER: roi_mask.append(sio.loadmat(os.path.join(cfg_data.DATA_PATH,'test',val_folder + '_roi.mat'))['BW']) for i_sub,i_loader in enumerate(self.val_loader,0): mask = roi_mask[i_sub] for vi, data in enumerate(i_loader, 0): img, gt_map = data with torch.no_grad(): img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() pred_map = self.net.forward(img,gt_map) pred_map = pred_map.data.cpu().numpy() gt_map = gt_map.data.cpu().numpy() for i_img in range(pred_map.shape[0]): pred_cnt = np.sum(pred_map[i_img])/self.cfg_data.LOG_PARA gt_count = np.sum(gt_map[i_img])/self.cfg_data.LOG_PARA losses.update(self.net.loss.item(),i_sub) maes.update(abs(gt_count-pred_cnt),i_sub) if vi==0: vis_results(self.exp_name, self.epoch, self.writer, self.restore_transform, img, pred_map, gt_map) mae = np.average(maes.avg) loss = np.average(losses.avg) self.writer.add_scalar('val_loss', loss, self.epoch + 1) self.writer.add_scalar('mae', mae, self.epoch + 1) self.writer.add_scalar('mae_s1', maes.avg[0], self.epoch + 1) self.writer.add_scalar('mae_s2', maes.avg[1], self.epoch + 1) self.writer.add_scalar('mae_s3', maes.avg[2], self.epoch + 1) self.writer.add_scalar('mae_s4', maes.avg[3], self.epoch + 1) self.writer.add_scalar('mae_s5', maes.avg[4], self.epoch + 1) self.train_record = update_model(self.net,self.optimizer,self.scheduler,self.epoch,self.i_tb,self.exp_path,self.exp_name, \ [mae, mse, loss],self.train_record,self.log_txt) print_WE_summary(self.log_txt,self.epoch,[mae, 0, loss],self.train_record,maes) def validate_V3(self):# validate_V3 for GCC self.net.eval() losses = AverageMeter() maes = AverageMeter() mses = AverageMeter() c_maes = {'level':AverageCategoryMeter(9), 'time':AverageCategoryMeter(8),'weather':AverageCategoryMeter(7)} c_mses = {'level':AverageCategoryMeter(9), 'time':AverageCategoryMeter(8),'weather':AverageCategoryMeter(7)} for vi, data in enumerate(self.val_loader, 0): img, gt_map, attributes_pt = data with torch.no_grad(): img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() pred_map = self.net.forward(img,gt_map) pred_map = pred_map.data.cpu().numpy() gt_map = gt_map.data.cpu().numpy() for i_img in range(pred_map.shape[0]): pred_cnt = np.sum(pred_map[i_img])/self.cfg_data.LOG_PARA gt_count = np.sum(gt_map[i_img])/self.cfg_data.LOG_PARA s_mae = abs(gt_count-pred_cnt) s_mse = (gt_count-pred_cnt)*(gt_count-pred_cnt) losses.update(self.net.loss.item()) maes.update(s_mae) mses.update(s_mse) attributes_pt = attributes_pt.squeeze() c_maes['level'].update(s_mae,attributes_pt[i_img][0]) c_mses['level'].update(s_mse,attributes_pt[i_img][0]) c_maes['time'].update(s_mae,attributes_pt[i_img][1]/3) c_mses['time'].update(s_mse,attributes_pt[i_img][1]/3) c_maes['weather'].update(s_mae,attributes_pt[i_img][2]) c_mses['weather'].update(s_mse,attributes_pt[i_img][2]) if vi==0: vis_results(self.exp_name, self.epoch, self.writer, self.restore_transform, img, pred_map, gt_map) loss = losses.avg mae = maes.avg mse = np.sqrt(mses.avg) self.writer.add_scalar('val_loss', loss, self.epoch + 1) self.writer.add_scalar('mae', mae, self.epoch + 1) self.writer.add_scalar('mse', mse, self.epoch + 1) self.train_record = update_model(self.net,self.optimizer,self.scheduler,self.epoch,self.i_tb,self.exp_path,self.exp_name, \ [mae, mse, loss],self.train_record,self.log_txt) print_GCC_summary(self.log_txt,self.epoch,[mae, mse, loss],self.train_record,c_maes,c_mses)
class Trainer(): def __init__(self, dataloader, cfg_data, pwd, cfg): self.cfg_data = cfg_data self.data_mode = cfg.DATASET self.exp_name = cfg.EXP_NAME self.exp_path = cfg.EXP_PATH self.pwd = pwd self.cfg = cfg self.net_name = cfg.NET self.net = CrowdCounter(cfg.GPU_ID, self.net_name, DA=True).cuda() self.num_parameters = sum( [param.nelement() for param in self.net.parameters()]) print('num_parameters:', self.num_parameters) self.optimizer = optim.Adam(self.net.CCN.parameters(), lr=cfg.LR, weight_decay=1e-4) # self.optimizer = optim.SGD(self.net.parameters(), cfg.LR, momentum=0.95,weight_decay=5e-4) self.scheduler = StepLR(self.optimizer, step_size=cfg.NUM_EPOCH_LR_DECAY, gamma=cfg.LR_DECAY) self.train_record = { 'best_mae': 1e20, 'best_mse': 1e20, 'best_model_name': '_' } self.hparam = { 'lr': cfg.LR, 'n_epochs': cfg.MAX_EPOCH, 'number of parameters': self.num_parameters, 'dataset': cfg.DATASET } # ,'finetuned':cfg.FINETUNE} self.timer = { 'iter time': Timer(), 'train time': Timer(), 'val time': Timer() } self.epoch = 0 self.i_tb = 0 '''discriminator''' if cfg.GAN == 'Vanilla': self.bce_loss = torch.nn.BCELoss() elif cfg.GAN == 'LS': self.bce_loss = torch.nn.MSELoss() if cfg.NET == 'Res50': self.channel1, self.channel2 = 1024, 128 self.D = [ FCDiscriminator(self.channel1, self.bce_loss).cuda(), FCDiscriminator(self.channel2, self.bce_loss).cuda() ] self.D[0].apply(weights_init()) self.D[1].apply(weights_init()) self.dis = self.cfg.DIS self.d_opt = [ optim.Adam(self.D[0].parameters(), lr=self.cfg.D_LR, betas=(0.9, 0.99)), optim.Adam(self.D[1].parameters(), lr=self.cfg.D_LR, betas=(0.9, 0.99)) ] self.scheduler_D = [ StepLR(self.d_opt[0], step_size=cfg.NUM_EPOCH_LR_DECAY, gamma=cfg.LR_DECAY), StepLR(self.d_opt[1], step_size=cfg.NUM_EPOCH_LR_DECAY, gamma=cfg.LR_DECAY) ] '''loss and lambdas here''' self.lambda_adv = [cfg.LAMBDA_ADV1, cfg.LAMBDA_ADV2] if cfg.PRE_GCC: print('===================Loaded Pretrained GCC================') weight = torch.load(cfg.PRE_GCC_MODEL)['net'] # weight=torch.load(cfg.PRE_GCC_MODEL) try: self.net.load_state_dict(convert_state_dict_gcc(weight)) except: self.net.load_state_dict(weight) # self.net=torch.nn.DataParallel(self.net, device_ids=cfg.GPU_ID).cuda() '''modify dataloader''' self.source_loader, self.target_loader, self.test_loader, self.restore_transform = dataloader( ) self.source_len = len(self.source_loader.dataset) self.target_len = len(self.target_loader.dataset) print("source:", self.source_len) print("target:", self.target_len) self.source_loader_iter = cycle(self.source_loader) self.target_loader_iter = cycle(self.target_loader) if cfg.RESUME: print('===================Loaded model to resume================') latest_state = torch.load(cfg.RESUME_PATH) self.net.load_state_dict(latest_state['net']) self.optimizer.load_state_dict(latest_state['optimizer']) self.scheduler.load_state_dict(latest_state['scheduler']) self.epoch = latest_state['epoch'] + 1 self.i_tb = latest_state['i_tb'] self.train_record = latest_state['train_record'] self.exp_path = latest_state['exp_path'] self.exp_name = latest_state['exp_name'] self.writer, self.log_txt = logger(self.exp_path, self.exp_name, self.pwd, 'exp', self.source_loader, self.test_loader, resume=cfg.RESUME, cfg=cfg) def forward(self): print('forward!!') # self.validate_V3() with open(self.log_txt, 'a') as f: f.write(str(self.net) + '\n') f.write('num_parameters:' + str(self.num_parameters) + '\n') for epoch in range(self.epoch, self.cfg.MAX_EPOCH): self.epoch = epoch # training self.timer['train time'].tic() self.train() self.timer['train time'].toc(average=False) if epoch > self.cfg.LR_DECAY_START: self.scheduler.step() self.scheduler_D[0].step() self.scheduler_D[1].step() print('train time: {:.2f}s'.format(self.timer['train time'].diff)) print('=' * 20) self.net.eval() # validation if epoch % self.cfg.VAL_FREQ == 0 or epoch > self.cfg.VAL_DENSE_START: self.timer['val time'].tic() if self.data_mode in ['SHHA', 'SHHB', 'QNRF', 'UCF50', 'Mall']: self.validate_V1() elif self.data_mode is 'WE': self.validate_V2() elif self.data_mode is 'GCC': self.validate_V3() elif self.data_mode is 'NTU': self.validate_V4() # self.validate_train() self.timer['val time'].toc(average=False) print('val time: {:.2f}s'.format(self.timer['val time'].diff)) def train(self): # training for all datasets self.net.train() for i in range(max(len(self.source_loader), len(self.target_loader))): torch.cuda.empty_cache() self.timer['iter time'].tic() img, gt_img = self.source_loader_iter.__next__() tar, gt_tar = self.target_loader_iter.__next__() img = Variable(img).cuda() gt_img = Variable(gt_img).cuda() tar = Variable(tar).cuda() gt_tar = Variable(gt_tar).cuda() #gen loss # loss, loss_adv, pred, pred1, pred2, pred_tar, pred_tar1, pred_tar2 = self.gen_update(img,tar,gt_img,gt_tar) self.optimizer.zero_grad() for param in self.D[0].parameters(): param.requires_grad = False for param in self.D[1].parameters(): param.requires_grad = False # source pred = self.net(img, gt_img) loss = self.net.loss if not self.cfg.LOSS_TOG: loss.backward() # target pred_tar = self.net(tar, gt_tar) loss_adv = self.D[self.dis].cal_loss(pred_tar[self.dis], 0) * self.lambda_adv[self.dis] if not self.cfg.LOSS_TOG: loss_adv.backward() else: loss += loss_adv loss.backward() #dis loss loss_d = self.dis_update(pred, pred_tar) self.d_opt[0].step() self.d_opt[1].step() self.optimizer.step() if (i + 1) % self.cfg.PRINT_FREQ == 0: self.i_tb += 1 self.writer.add_scalar('train_loss', loss.item(), self.i_tb) self.writer.add_scalar('loss_adv', loss_adv.item(), self.i_tb) self.writer.add_scalar('loss_d', loss_d.item(), self.i_tb) self.timer['iter time'].toc(average=False) print('[ep %d][it %d][loss %.4f][loss_adv %.8f][loss_d %.4f][lr %.8f][%.2fs]' % \ (self.epoch + 1, i + 1, loss.item(), loss_adv.item() if loss_adv else 0, loss_d.item(), self.optimizer.param_groups[0]['lr'], self.timer['iter time'].diff)) print(' [cnt: gt: %.1f pred: %.2f]' % (gt_img[0].sum().data / self.cfg_data.LOG_PARA, pred[-1][0].sum().data / self.cfg_data.LOG_PARA)) print(' [tar: gt: %.1f pred: %.2f]' % (gt_tar[0].sum().data / self.cfg_data.LOG_PARA, pred_tar[-1][0].sum().data / self.cfg_data.LOG_PARA)) self.writer.add_scalar('lr', self.optimizer.param_groups[0]['lr'], self.epoch + 1) def gen_update(self, img, tar, gt_img, gt_tar): pass # return loss,loss_adv,pred,pred1,pred2,pred_tar,pred_tar1,pred_tar2 def dis_update(self, pred, pred_tar): self.d_opt[self.dis].zero_grad() for param in self.D[0].parameters(): param.requires_grad = True for param in self.D[1].parameters(): param.requires_grad = True #source pred = [pred[0].detach(), pred[1].detach()] loss_d = self.D[self.dis].cal_loss(pred[self.dis], 0) if not self.cfg.LOSS_TOG: loss_d.backward() loss_D = loss_d #target pred_tar = [pred_tar[0].detach(), pred_tar[1].detach()] loss_d = self.D[self.dis].cal_loss(pred_tar[self.dis], 1) if not self.cfg.LOSS_TOG: loss_d.backward() loss_D += loss_d if self.cfg.LOSS_TOG: loss_D.backward() return loss_D def validate_train(self): self.net.eval() losses = AverageMeter() maes = AverageMeter() mses = AverageMeter() for img, gt_map in self.source_loader: with torch.no_grad(): img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() _, _, pred_map = self.net.forward(img, gt_map) pred_map = pred_map.data.cpu().numpy() gt_map = gt_map.data.cpu().numpy() for i_img in range(pred_map.shape[0]): pred_cnt = np.sum(pred_map[i_img]) / self.cfg_data.LOG_PARA gt_count = np.sum(gt_map[i_img]) / self.cfg_data.LOG_PARA s_mae = abs(gt_count - pred_cnt) s_mse = (gt_count - pred_cnt) * (gt_count - pred_cnt) losses.update(self.net.loss.item()) maes.update(s_mae) mses.update(s_mse) loss = losses.avg mae = maes.avg mse = np.sqrt(mses.avg) print("test on source domain") print_NTU_summary(self.log_txt, self.epoch, [mae, mse, loss], self.train_record) def validate_V4(self): # validate_V4 for NTU self.net.eval() losses = AverageMeter() maes = AverageMeter() mses = AverageMeter() for vi, data in enumerate(self.test_loader, 0): img, gt_map = data with torch.no_grad(): img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() _, _, pred_map = self.net.forward(img, gt_map) pred_map = pred_map.data.cpu().numpy() gt_map = gt_map.data.cpu().numpy() for i_img in range(pred_map.shape[0]): pred_cnt = np.sum(pred_map[i_img]) / self.cfg_data.LOG_PARA gt_count = np.sum(gt_map[i_img]) / self.cfg_data.LOG_PARA s_mae = abs(gt_count - pred_cnt) s_mse = (gt_count - pred_cnt) * (gt_count - pred_cnt) losses.update(self.net.loss.item()) maes.update(s_mae) mses.update(s_mse) if vi == 0: vis_results(self.exp_name, self.epoch, self.writer, self.restore_transform, img, pred_map, gt_map) loss = losses.avg mae = maes.avg mse = np.sqrt(mses.avg) self.writer.add_scalar('val_loss', loss, self.epoch + 1) self.writer.add_scalar('mae', mae, self.epoch + 1) self.writer.add_scalar('mse', mse, self.epoch + 1) self.train_record = update_model(self.net, self.optimizer, self.scheduler, self.epoch, self.i_tb, self.exp_path, self.exp_name, [mae, mse, loss], self.train_record, False, self.log_txt) print_NTU_summary(self.log_txt, self.epoch, [mae, mse, loss], self.train_record)
def test(file_list, model_path): net = CrowdCounter(cfg.GPU_ID, 'Res101_SFCN') net.cuda() lastest_state = torch.load(model_path) net.load_state_dict(lastest_state['net']) #net.load_state_dict(torch.load(model_path)) net.eval() #f = open('submmited.txt', 'w+') for infos in file_list: filename = infos.split()[0] #print(filename) imgname = os.path.join(dataRoot, 'img', filename + '.jpg') img = Image.open(imgname) dotname = imgname.replace('img', 'dot').replace('jpg', 'png') dot_map = Image.open(dotname) dot_map = dot_transform(dot_map) if img.mode == 'L': img = img.convert('RGB') img = img_transform(img)[None, :, :, :] dot_map = dot_map[None, :, :, :] with torch.no_grad(): img = Variable(img).cuda() dot_map = Variable(dot_map).cuda() algt = torch.sum(dot_map).item() crop_imgs, crop_dots, crop_masks = [], [], [] b, c, h, w = img.shape rh, rw = 576, 768 for i in range(0, h, rh): gis, gie = max(min(h - rh, i), 0), min(h, i + rh) for j in range(0, w, rw): gjs, gje = max(min(w - rw, j), 0), min(w, j + rw) crop_imgs.append(img[:, :, gis:gie, gjs:gje]) crop_dots.append(dot_map[:, :, gis:gie, gjs:gje]) mask = torch.zeros_like(dot_map).cuda() mask[:, :, gis:gie, gjs:gje].fill_(1.0) crop_masks.append(mask) crop_imgs, crop_dots, crop_masks = map( lambda x: torch.cat(x, dim=0), (crop_imgs, crop_dots, crop_masks)) # forward may need repeatng crop_preds, crop_dens = [], [] nz, bz = crop_imgs.size(0), 1 for i in range(0, nz, bz): gs, gt = i, min(nz, i + bz) crop_pred, crop_den = net.forward(crop_imgs[gs:gt], crop_dots[gs:gt]) crop_preds.append(crop_pred) crop_dens.append(crop_den) crop_preds = torch.cat(crop_preds, dim=0) crop_dens = torch.cat(crop_dens, dim=0) # splice them to the original size idx = 0 pred_map = torch.zeros_like(dot_map).cuda() den_map = torch.zeros_like(dot_map).cuda() for i in range(0, h, rh): gis, gie = max(min(h - rh, i), 0), min(h, i + rh) for j in range(0, w, rw): gjs, gje = max(min(w - rw, j), 0), min(w, j + rw) pred_map[:, :, gis:gie, gjs:gje] += crop_preds[idx] den_map[:, :, gis:gie, gjs:gje] += crop_dens[idx] idx += 1 # for the overlapping area, compute average value mask = crop_masks.sum(dim=0).unsqueeze(0) pred_map = pred_map / mask den_map = den_map / mask pred_map /= LOG_PARA pred = torch.sum(pred_map).item() pred_map = pred_map.cpu().data.numpy()[0, 0, :, :] den_map = den_map.cpu().data.numpy()[0, 0, :, :] print(pred_map.sum(), den_map.sum()) psnr = calc_psnr(den_map, pred_map) ssim = calc_ssim(den_map, pred_map) if psnr == 'NaN': plt.imsave(os.path.join( 'pred', f'[{filename}]_[{pred:.2f}|{algt:.2f}]_[{psnr}]_[{ssim:.4f}].png' ), pred_map, cmap='jet') else: plt.imsave(os.path.join( 'pred', f'[{filename}]_[{pred:.2f}|{algt:.2f}]_[{psnr:.2f}]_[{ssim:.4f}].png' ), pred_map, cmap='jet')
class Trainer(): def __init__(self, cfg_data, pwd): self.cfg_data = cfg_data self.train_loader, self.val_loader, self.restore_transform = datasets.loading_data( cfg.DATASET) self.data_mode = cfg.DATASET self.exp_name = cfg.EXP_NAME self.exp_path = cfg.EXP_PATH self.pwd = pwd self.net_name = cfg.NET self.net = CrowdCounter(cfg.GPU_ID, self.net_name).cuda() self.optimizer = optim.Adam(self.net.CCN.parameters(), lr=cfg.LR, weight_decay=1e-4) # self.optimizer = optim.SGD(self.net.parameters(), cfg.LR, momentum=0.95,weight_decay=5e-4) self.scheduler = StepLR(self.optimizer, step_size=cfg.NUM_EPOCH_LR_DECAY, gamma=cfg.LR_DECAY) self.train_record = {'best_bce_loss': 1e20, 'best_model_name': ''} self.timer = { 'iter time': Timer(), 'train time': Timer(), 'val time': Timer() } self.epoch = 0 self.i_tb = 0 if cfg.PRE_GCC: self.net.load_state_dict(torch.load(cfg.PRE_GCC_MODEL)) if cfg.RESUME: latest_state = torch.load(cfg.RESUME_PATH) self.net.load_state_dict(latest_state['net']) self.optimizer.load_state_dict(latest_state['optimizer']) self.scheduler.load_state_dict(latest_state['scheduler']) self.epoch = latest_state['epoch'] + 1 self.i_tb = latest_state['i_tb'] self.train_record = latest_state['train_record'] self.exp_path = latest_state['exp_path'] self.exp_name = latest_state['exp_name'] self.writer, self.log_txt = logger(self.exp_path, self.exp_name, self.pwd, 'exp', resume=cfg.RESUME) def forward(self): self.validate() for epoch in range(self.epoch, cfg.MAX_EPOCH): self.epoch = epoch # training self.timer['train time'].tic() self.train() self.timer['train time'].toc(average=False) print('train time: {:.2f}s'.format(self.timer['train time'].diff)) print('=' * 20) # validation if epoch % cfg.VAL_FREQ == 0 or epoch > cfg.VAL_DENSE_START: self.timer['val time'].tic() self.validate() self.timer['val time'].toc(average=False) print('val time: {:.2f}s'.format(self.timer['val time'].diff)) if epoch > cfg.LR_DECAY_START: self.scheduler.step() def train(self): # training for all datasets self.net.train() for i, data in enumerate(self.train_loader, 0): self.timer['iter time'].tic() img, gt_map = data img = Variable(img).cuda() gt_map = Variable(gt_map).cuda() self.optimizer.zero_grad() pred_map, _ = self.net(img, gt_map) loss = self.net.loss loss.backward() self.optimizer.step() if (i + 1) % cfg.PRINT_FREQ == 0: self.i_tb += 1 self.writer.add_scalar('train_loss', loss.item(), self.i_tb) self.timer['iter time'].toc(average=False) print( '[ep %d][it %d][loss %.4f][lr %.4f][%.2fs]' % \ (self.epoch + 1, i + 1, loss.item(), self.optimizer.param_groups[0]['lr']*10000, self.timer['iter time'].diff) ) def validate(self): self.net.eval() losses = AverageMeter() for vi, data in enumerate(self.val_loader, 0): img, dot_map, attributes_pt = data with torch.no_grad(): img = Variable(img).cuda() dot_map = Variable(dot_map).cuda() pred_map, loc_gt_map = self.net.forward(img, dot_map) pred_map = F.softmax(pred_map, dim=1).data.max(1) pred_map = pred_map[1].squeeze_(1) # # crop the img and gt_map with a max stride on x and y axis # # size: HW: __C_NWPU.TRAIN_SIZE # # stack them with a the batchsize: __C_NWPU.TRAIN_BATCH_SIZE # crop_imgs, crop_dots, crop_masks = [], [], [] # b, c, h, w = img.shape # rh, rw = self.cfg_data.TRAIN_SIZE # for i in range(0, h, rh): # gis, gie = max(min(h-rh, i), 0), min(h, i+rh) # for j in range(0, w, rw): # gjs, gje = max(min(w-rw, j), 0), min(w, j+rw) # crop_imgs.append(img[:, :, gis:gie, gjs:gje]) # crop_dots.append(dot_map[:, :, gis:gie, gjs:gje]) # mask = torch.zeros_like(dot_map).cuda() # mask[:, :, gis:gie, gjs:gje].fill_(1.0) # crop_masks.append(mask) # crop_imgs, crop_dots, crop_masks = map(lambda x: torch.cat(x, dim=0), (crop_imgs, crop_dots, crop_masks)) # # forward may need repeatng # crop_preds, crop_loc_gts = [], [] # nz, bz = crop_imgs.size(0), self.cfg_data.TRAIN_BATCH_SIZE # for i in range(0, nz, bz): # gs, gt = i, min(nz, i+bz) # #pdb.set_trace() # # print(crop_imgs[gs:gt].shape) # # print(crop_dots[gs:gt].shape) # crop_pred, crop_loc_gt = self.net.forward(crop_imgs[gs:gt], crop_dots[gs:gt]) # crop_pred = F.softmax(crop_pred,dim=1).data.max(1) # crop_pred = crop_pred[1].squeeze_(1) # crop_preds.append(crop_pred) # crop_loc_gts.append(crop_loc_gt) # crop_preds = torch.cat(crop_preds, dim=0) # crop_loc_gts = torch.cat(crop_loc_gts, dim=0) # # splice them to the original size # idx = 0 # pred_map = torch.zeros_like(dot_map).cuda() # loc_gt_map = torch.zeros_like(dot_map).cuda() # for i in range(0, h, rh): # gis, gie = max(min(h-rh, i), 0), min(h, i+rh) # for j in range(0, w, rw): # gjs, gje = max(min(w-rw, j), 0), min(w, j+rw) # pred_map[:, :, gis:gie, gjs:gje] += crop_preds[idx] # loc_gt_map[:, :, gis:gie, gjs:gje] += crop_loc_gts[idx] # idx += 1 # # for the overlapping area, compute average value # mask = crop_masks.sum(dim=0).unsqueeze(0) # pred_map = (pred_map / mask).bool().long() # loc_gt_map = (loc_gt_map / mask).bool().long() pred_map = pred_map.bool().long() loc_gt_map = loc_gt_map.bool().long() # pdb.set_trace() pred_map = pred_map.data.cpu().numpy() loc_gt_map = loc_gt_map.data.cpu().numpy() losses.update(self.net.loss.item()) if vi == 0: vis_results(self.exp_name, self.epoch, self.writer, self.restore_transform, img, pred_map, loc_gt_map) loss = losses.avg self.writer.add_scalar('val_loss', loss, self.epoch + 1) self.train_record = update_model(self.net,self.optimizer,self.scheduler,self.epoch,self.i_tb,self.exp_path,self.exp_name, \ loss,self.train_record,self.log_txt) print_NWPU_summary(self.exp_name, self.log_txt, self.epoch, loss, self.train_record)