Download CGFormer/engine/engine_refzom.py from dianecy/MRaCL: direct link, hf CLI and curl.
- Browser
- Download file 10.2 kB
-
https://huggingface.co/dianecy/MRaCL/resolve/main/CGFormer/engine/engine_refzom.py
- Command line
-
hf download hf://dianecy/MRaCL/CGFormer/engine/engine_refzom.py
-
curl -L -o engine_refzom.py https://huggingface.co/dianecy/MRaCL/resolve/main/CGFormer/engine/engine_refzom.py
10.2 kB
| import os | |
| import time | |
| from tqdm import tqdm | |
| import cv2 | |
| import numpy as np | |
| import torch | |
| import torch.cuda.amp as amp | |
| import torch.distributed as dist | |
| import torch.nn.functional as F | |
| import wandb | |
| from PIL import Image | |
| from loguru import logger | |
| from utils.misc import (AverageMeter, ProgressMeter, concat_all_gather, concat_all_gather_varsize, trainMetricGPU) | |
| def train(train_loader, model, optimizer, scheduler, scaler, epoch, args): | |
| batch_time = AverageMeter('Batch', ':2.2f') | |
| data_time = AverageMeter('Data', ':2.2f') | |
| lr = AverageMeter('Lr', ':1.6f') | |
| loss_meter = AverageMeter('Loss', ':2.4f') | |
| iou_meter = AverageMeter('IoU', ':2.2f') | |
| pr_meter = AverageMeter('Prec@50', ':2.2f') | |
| progress = ProgressMeter( | |
| len(train_loader), | |
| [batch_time, data_time, lr, loss_meter, iou_meter, pr_meter], | |
| prefix="Training: Epoch=[{}/{}] ".format(epoch, args.epochs)) | |
| model.train() | |
| time.sleep(2) | |
| end = time.time() | |
| # size_list = [320, 352, 384, 416, 448, 480, 512] | |
| for i, (image, text, target, l_mask, source_type) in enumerate(train_loader): | |
| data_time.update(time.time() - end) | |
| # data | |
| try: | |
| dist.barrier() | |
| except: | |
| logger.error(f"Barrier failed at iteration {i}, rank {dist.get_rank()}") | |
| continue | |
| image = image.cuda(non_blocking=True) | |
| text = text.cuda(non_blocking=True) | |
| target = target.cuda(non_blocking=True) | |
| l_mask = l_mask.cuda(non_blocking=True) | |
| # # multi-scale training | |
| # image = F.interpolate(image, size=(new_size, new_size), mode='bilinear', align_corners=True) | |
| text = text.squeeze(1) | |
| l_mask = l_mask.squeeze(1) | |
| # forward | |
| with amp.autocast(): | |
| pred, target, loss = \ | |
| model(image, text, l_mask, mask=target) | |
| dist.barrier() | |
| # metric | |
| iou, pr5 = trainMetricGPU(pred, target, 0.35) | |
| dist.all_reduce(loss.detach()) | |
| dist.all_reduce(iou) | |
| dist.all_reduce(pr5) | |
| loss = loss / dist.get_world_size() | |
| iou = iou / dist.get_world_size() | |
| pr5 = pr5 / dist.get_world_size() | |
| del pred, target, text, l_mask | |
| #delete all opts and backptop | |
| optimizer.zero_grad() | |
| scaler.scale(loss).backward() | |
| scaler.step(optimizer) | |
| scaler.update() | |
| loss_meter.update(loss.item(), image.size(0)) | |
| iou_meter.update(iou.item(), image.size(0)) | |
| pr_meter.update(pr5.item(), image.size(0)) | |
| lr.update(optimizer.param_groups[0]["lr"]) | |
| batch_time.update(time.time() - end) | |
| end = time.time() | |
| if (i + 1) % args.print_freq == 0: | |
| progress.display(i + 1) | |
| if dist.get_rank() in [-1, 0]: | |
| wandb.log( | |
| { | |
| "time/batch": batch_time.val, | |
| "time/data": data_time.val, | |
| "training/lr": lr.val, | |
| "training/loss": loss_meter.val, | |
| "training/iou": iou_meter.val, | |
| "training/prec@50": pr_meter.val, | |
| }, | |
| step=epoch * len(train_loader) + (i + 1)) | |
| # flush every 10 steps | |
| if i % 10 == 0: | |
| torch.cuda.empty_cache() | |
| def validate(val_loader, model, epoch, args): | |
| iou_list = [] | |
| I_sum = 0 | |
| U_sum = 0 | |
| mean_acc = [] | |
| model.eval() | |
| time.sleep(2) | |
| for idx, (imgs, text, masks, l_mask, source_type) in enumerate(val_loader): | |
| # data | |
| # imgs = torch.stack(imgs).cuda(non_blocking=True) | |
| # text = torch.stack(text).cuda(non_blocking=True) | |
| # l_mask = torch.stack(l_mask).cuda(non_blocking=True) | |
| imgs = imgs.cuda(non_blocking=True) | |
| text = text.cuda(non_blocking=True) | |
| l_mask = l_mask.cuda(non_blocking=True) | |
| text = text.squeeze(1) | |
| l_mask = l_mask.squeeze(1) | |
| # print(imgs.shape, text.shape) | |
| # if idx % 50 == 0: | |
| # print(source_type) | |
| # inference | |
| with amp.autocast(): # does inference need fp16? | |
| preds, maps = model(imgs, text, l_mask) | |
| preds = torch.sigmoid(preds) | |
| # process one batch | |
| for pred, mask, stype in zip(preds, masks, source_type): | |
| # iou | |
| pred = pred.cpu().numpy() | |
| mask = mask.cpu().numpy() | |
| pred = np.array(pred > 0.5) | |
| if stype == 'zero': # Handle 'zero' source_type differently | |
| incorrect_num = np.sum(pred) | |
| acc = 1 if incorrect_num == 0 else 0 | |
| mean_acc.append(acc) | |
| else : | |
| # IoU calculation | |
| inter_sum = np.sum(np.logical_and(pred, mask)) | |
| union_sum = np.sum(np.logical_or(pred, mask)) | |
| iou = inter_sum / (union_sum + 1e-6) | |
| iou_list.append(iou) | |
| I_sum += inter_sum | |
| U_sum += union_sum | |
| dist.barrier() | |
| # iou_list = np.stack(iou_list) | |
| # iou_list = torch.from_numpy(iou_list).to(imgs.device) | |
| # iou_list = concat_all_gather(iou_list) | |
| iou_list = torch.tensor(iou_list, device=imgs.device) | |
| I_sum = torch.tensor([I_sum], device=imgs.device) | |
| U_sum = torch.tensor([U_sum], device=imgs.device) | |
| print("Before ioi list concat and gather ", iou_list.shape) | |
| print("Before Isum, Usum concat and gather", I_sum.shape, U_sum.shape) | |
| gathered_iou = concat_all_gather(iou_list) | |
| gathered_I = concat_all_gather(I_sum) | |
| gathered_U = concat_all_gather(U_sum) | |
| print("Before I and U concat and gather ", gathered_I.shape, gathered_U.shape) | |
| print("After ioi list concat and gather ", gathered_iou.shape) | |
| gathered_I_sum = gathered_I.sum().item() | |
| gathered_U_sum = gathered_U.sum().item() | |
| iou = gathered_iou.mean().item() | |
| oIoU = gathered_I_sum / (gathered_U_sum + 1e-6) | |
| print("iou:", iou, "oIoU:", oIoU) | |
| torch.cuda.empty_cache() | |
| prec_list = [] | |
| for thres in torch.arange(0.5, 1.0, 0.1): | |
| tmp = (gathered_iou > thres).float().mean() | |
| prec_list.append(tmp) | |
| prec = {} | |
| temp = ' ' | |
| for i, thres in enumerate(range(5, 10)): | |
| key = 'Pr@{}'.format(thres * 10) | |
| value = prec_list[i].item() | |
| prec[key] = value | |
| temp += "{}: {:.2f} ".format(key, 100. * value) | |
| dist.barrier() | |
| # head = 'Evaluation: Epoch=[{}/{}] mIoU={:.2f} oIoU={:.2f}'.format( | |
| # epoch, args.epochs, 100. * iou, 100.*(oIoU)) | |
| # if mean_acc: | |
| # # Calculate accuracy for 'zero' cases | |
| # mean_acc = np.mean(mean_acc) | |
| # head += ' Acc={:.2f}'.format(100. * mean_acc) | |
| # else: | |
| # mean_acc = 0 | |
| # logger.info(head + temp) | |
| if dist.get_rank() == 0: | |
| head = 'Evaluation: Epoch=[{}/{}] mIoU={:.2f} oIoU={:.2f}'.format( | |
| epoch, args.epochs, 100. * iou, 100.*(oIoU)) | |
| if mean_acc: | |
| mean_acc = np.mean(mean_acc) | |
| head += ' Acc={:.2f}'.format(100. * mean_acc) | |
| else: | |
| mean_acc = 0 | |
| logger.info(head + temp) | |
| print(head + temp) | |
| return iou, oIoU, prec, mean_acc | |
| def inference(test_loader, model, args): | |
| iou_list = [] | |
| I_sum = 0 | |
| U_sum = 0 | |
| mean_acc = [] | |
| tbar = tqdm(test_loader, desc='Inference:', ncols=100) | |
| model.eval() | |
| time.sleep(2) | |
| for ori_img, img, texts, mask, l_masks, seg_id, sents, source_type in tbar: | |
| img = img.cuda(non_blocking=True) | |
| mask = mask.cpu().numpy() | |
| # print(len(texts), source_type) | |
| # for all sentences for each referrals | |
| for text, l_mask, sent in zip(texts, l_masks, sents): | |
| text = text.cuda(non_blocking=True) | |
| l_mask = l_mask.cuda(non_blocking=True) | |
| text = text.squeeze(1) | |
| l_mask = l_mask.squeeze(1) | |
| with amp.autocast(): | |
| pred, maps = model(img, text, l_mask) | |
| pred = torch.sigmoid(pred) | |
| if pred.shape[-2:] != ori_img.shape[:-1]: | |
| #print(f"before** {pred.shape}, {ori_img.shape}, {mask.shape}") | |
| pred = F.interpolate(pred, size=ori_img.shape[1:-1], mode='bicubic', align_corners=True) | |
| # # process one sentence | |
| pred = pred.cpu().numpy() | |
| pred = np.array(pred > 0.35) | |
| if source_type == 'zero': | |
| incorrect_num = np.sum(pred) | |
| acc = 1 if incorrect_num == 0 else 0 | |
| mean_acc.append(acc) | |
| else: | |
| inter_sum = np.sum(np.logical_and(pred, mask)) # sum of intersection | |
| union_sum = np.sum(np.logical_or(pred, mask)) # sum of union | |
| if union_sum == 0 : | |
| iou = 0.0 | |
| else : | |
| iou = inter_sum*1.0 / union_sum | |
| iou_list.append(iou) | |
| I_sum += inter_sum | |
| U_sum += union_sum | |
| logger.info('=> Metric Calculation <=') | |
| iou_list = np.stack(iou_list) | |
| iou_list = torch.from_numpy(iou_list).to(img.device) | |
| # print(iou_list.shape) | |
| overall_IoU = I_sum / U_sum | |
| prec_list = [] | |
| for thres in torch.arange(0.5, 1.0, 0.1): | |
| tmp = (iou_list > thres).float().mean() | |
| prec_list.append(tmp) | |
| iou = iou_list.mean() | |
| prec = {} | |
| for i, thres in enumerate(range(5, 10)): | |
| key = 'Pr@{}'.format(thres*10) | |
| value = prec_list[i].item() | |
| prec[key] = value | |
| logger.info('oIoU={:.2f}'.format(100.*(I_sum/U_sum))) | |
| logger.info('mIoU={:.2f}'.format(100.*iou.item())) | |
| if mean_acc: | |
| # Calculate accuracy for 'zero' cases | |
| mean_acc = np.mean(mean_acc) | |
| logger.info('Acc={:.2f}'.format(100. * mean_acc)) | |
| else: | |
| mean_acc = 0 | |
| for k, v in prec.items(): | |
| logger.info('{}: {:.2f}.'.format(k, 100.*v)) | |
| return iou.item(), overall_IoU, prec, mean_acc | |