From 1a7c02ab530f8dc4619c6030f07cf25fd44b5618 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Sat, 8 Jul 2023 05:25:48 +0330 Subject: [PATCH 01/12] Add test_cpu.py for CPU-based testing --- test_cpu.py | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 test_cpu.py diff --git a/test_cpu.py b/test_cpu.py new file mode 100644 index 00000000..f5abb31a --- /dev/null +++ b/test_cpu.py @@ -0,0 +1,191 @@ +# System libs +import os +import argparse +from distutils.version import LooseVersion +# Numerical libs +import numpy as np +import torch +import torch.nn as nn +from scipy.io import loadmat +import csv +# Our libs +from mit_semseg.dataset import TestDataset +from mit_semseg.models import ModelBuilder, SegmentationModule +from mit_semseg.utils import colorEncode, find_recursive, setup_logger +from mit_semseg.lib.nn import user_scattered_collate, async_copy_to +from mit_semseg.lib.utils import as_numpy +from PIL import Image +from tqdm import tqdm +from mit_semseg.config import cfg + +colors = loadmat('data/color150.mat')['colors'] +names = {} +with open('data/object150_info.csv') as f: + reader = csv.reader(f) + next(reader) + for row in reader: + names[int(row[0])] = row[5].split(";")[0] + + +def visualize_result(data, pred, cfg): + (img, info) = data + + # print predictions in descending order + pred = np.int32(pred) + pixs = pred.size + uniques, counts = np.unique(pred, return_counts=True) + print("Predictions in [{}]:".format(info)) + for idx in np.argsort(counts)[::-1]: + name = names[uniques[idx] + 1] + ratio = counts[idx] / pixs * 100 + if ratio > 0.1: + print(" {}: {:.2f}%".format(name, ratio)) + + # colorize prediction + pred_color = colorEncode(pred, colors).astype(np.uint8) + + # aggregate images and save + im_vis = np.concatenate((img, pred_color), axis=1) + + img_name = info.split('/')[-1] + Image.fromarray(im_vis).save( + os.path.join(cfg.TEST.result, img_name.replace('.jpg', '.png'))) + + +def test(segmentation_module, loader): + segmentation_module.eval() + + pbar = tqdm(total=len(loader)) + for batch_data in loader: + # process data + batch_data = batch_data[0] + segSize = (batch_data['img_ori'].shape[0], + batch_data['img_ori'].shape[1]) + img_resized_list = batch_data['img_data'] + + with torch.no_grad(): + scores = torch.zeros(1, cfg.DATASET.num_class, segSize[0], segSize[1]) + + for img in img_resized_list: + feed_dict = batch_data.copy() + feed_dict['img_data'] = img + del feed_dict['img_ori'] + del feed_dict['info'] + + # forward pass + pred_tmp = segmentation_module(feed_dict, segSize=segSize) + scores = scores + pred_tmp / len(cfg.DATASET.imgSizes) + + _, pred = torch.max(scores, dim=1) + pred = as_numpy(pred.squeeze(0)) + + # visualization + visualize_result( + (batch_data['img_ori'], batch_data['info']), + pred, + cfg + ) + + pbar.update(1) + + + +def main(cfg): + # Network Builders + net_encoder = ModelBuilder.build_encoder( + arch=cfg.MODEL.arch_encoder, + fc_dim=cfg.MODEL.fc_dim, + weights=cfg.MODEL.weights_encoder) + net_decoder = ModelBuilder.build_decoder( + arch=cfg.MODEL.arch_decoder, + fc_dim=cfg.MODEL.fc_dim, + num_class=cfg.DATASET.num_class, + weights=cfg.MODEL.weights_decoder, + use_softmax=True) + + crit = nn.NLLLoss(ignore_index=-1) + + segmentation_module = SegmentationModule(net_encoder, net_decoder, crit).cpu() + + # Dataset and Loader + dataset_test = TestDataset( + cfg.list_test, + cfg.DATASET) + loader_test = torch.utils.data.DataLoader( + dataset_test, + batch_size=cfg.TEST.batch_size, + shuffle=False, + collate_fn=user_scattered_collate, + num_workers=5, + drop_last=True) + + # Main loop + test(segmentation_module, loader_test) + + print('Inference done!') + + +if __name__ == '__main__': + assert LooseVersion(torch.__version__) >= LooseVersion('0.4.0'), \ + 'PyTorch>=0.4.0 is required' + + parser = argparse.ArgumentParser( + description="PyTorch Semantic Segmentation Testing" + ) + parser.add_argument( + "--imgs", + required=True, + type=str, + help="an image path, or a directory name" + ) + parser.add_argument( + "--cfg", + default="config/ade20k-resnet50dilated-ppm_deepsup.yaml", + metavar="FILE", + help="path to config file", + type=str, + ) + parser.add_argument( + "opts", + help="Modify config options using the command-line", + default=None, + nargs=argparse.REMAINDER, + ) + args = parser.parse_args() + + cfg.merge_from_file(args.cfg) + cfg.merge_from_list(args.opts) + # cfg.freeze() + + logger = setup_logger(distributed_rank=0) # TODO + logger.info("Loaded configuration file {}".format(args.cfg)) + logger.info("Running with config:\n{}".format(cfg)) + + cfg.MODEL.arch_encoder = cfg.MODEL.arch_encoder.lower() + cfg.MODEL.arch_decoder = cfg.MODEL.arch_decoder.lower() + + # absolute paths of model weights + cfg.MODEL.weights_encoder = os.path.join( + cfg.DIR, 'encoder_' + cfg.TEST.checkpoint) + cfg.MODEL.weights_decoder = os.path.join( + cfg.DIR, 'decoder_' + cfg.TEST.checkpoint) + + + print(cfg.MODEL.weights_encoder) + print(cfg.MODEL.weights_decoder) + + assert os.path.exists(cfg.MODEL.weights_encoder) and \ + os.path.exists(cfg.MODEL.weights_decoder), "checkpoint does not exist!" + + # generate testing image list + if os.path.isdir(args.imgs): + imgs = find_recursive(args.imgs) + else: + imgs = [args.imgs] + assert len(imgs), "imgs should be a path to image (.jpg) or directory." + cfg.list_test = [{'fpath_img': x} for x in imgs] + + if not os.path.isdir(cfg.TEST.result): + os.makedirs(cfg.TEST.result) + + main(cfg) From 954592b5df0c6cea6f2ae44d8a35e333efbd4a83 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 06:24:48 +0330 Subject: [PATCH 02/12] Update requirements.txt --- requirements.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 154a2c40..e3702738 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ +--extra-index-url https://download.pytorch.org/whl/cpu numpy scipy -pytorch==0.4.1 -torchvision +torch==1.12.1+cpu +torchvision==0.13.1+cpu opencv3 yacs tqdm From b9f15e6f1a9acd640beb21bcaaccf04afa493123 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 06:26:50 +0330 Subject: [PATCH 03/12] Update th.py to works with python 3.10 --- mit_semseg/lib/utils/th.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mit_semseg/lib/utils/th.py b/mit_semseg/lib/utils/th.py index ca6ef938..9e952a99 100644 --- a/mit_semseg/lib/utils/th.py +++ b/mit_semseg/lib/utils/th.py @@ -8,17 +8,17 @@ def as_variable(obj): if isinstance(obj, Variable): return obj - if isinstance(obj, collections.Sequence): + if isinstance(obj, collections.abc.Sequence): return [as_variable(v) for v in obj] - elif isinstance(obj, collections.Mapping): + elif isinstance(obj, collections.abc.Mapping): return {k: as_variable(v) for k, v in obj.items()} else: return Variable(obj) def as_numpy(obj): - if isinstance(obj, collections.Sequence): + if isinstance(obj, collections.abc.Sequence): return [as_numpy(v) for v in obj] - elif isinstance(obj, collections.Mapping): + elif isinstance(obj, collections.abc.Mapping): return {k: as_numpy(v) for k, v in obj.items()} elif isinstance(obj, Variable): return obj.data.cpu().numpy() @@ -33,9 +33,9 @@ def mark_volatile(obj): if isinstance(obj, Variable): obj.no_grad = True return obj - elif isinstance(obj, collections.Mapping): + elif isinstance(obj, collections.abc.Mapping): return {k: mark_volatile(o) for k, o in obj.items()} - elif isinstance(obj, collections.Sequence): + elif isinstance(obj, collections.abc.Sequence): return [mark_volatile(o) for o in obj] else: return obj From 397f59cd36f135f10ef05daf3c6d42d80381afe1 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 06:42:50 +0330 Subject: [PATCH 04/12] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e95c24d0..3ebcc21e 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,8 @@ The code is developed under the following configurations. - Hardware: >=4 GPUs for training, >=1 GPU for testing (set ```[--gpus GPUS]``` accordingly) - Software: Ubuntu 16.04.3 LTS, ***CUDA>=8.0, Python>=3.5, PyTorch>=0.4.0*** - Dependencies: numpy, scipy, opencv, yacs, tqdm +- gdown https://drive.google.com/file/d/1Il1Pcb13syeHi9LA9KjXz8KqMFN9izgo +- unzip -j ckpt.zip ## Quick start: Test on an image using our trained model 1. Here is a simple demo to do inference on a single image: From fafb27a00833c677ab6708a6b2192f35d0c51c39 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 06:47:12 +0330 Subject: [PATCH 05/12] Update requirements.txt --- requirements.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/requirements.txt b/requirements.txt index e3702738..46f8de21 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,8 @@ torchvision==0.13.1+cpu opencv3 yacs tqdm +aiohttp +aiofiles +aiohttp_cors +scipy==1.9.1 +pillow From 2544e089289aa0571d65fb2fc8f07290f10a63c2 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:02:05 +0330 Subject: [PATCH 06/12] Update requirements.txt --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 46f8de21..2f76552f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,4 @@ tqdm aiohttp aiofiles aiohttp_cors -scipy==1.9.1 pillow From 6f325db6fb650c3c66ce38db5a96b1959cf992d0 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:04:34 +0330 Subject: [PATCH 07/12] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2f76552f..cd9b4a51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ numpy scipy torch==1.12.1+cpu torchvision==0.13.1+cpu -opencv3 +opencv-python yacs tqdm aiohttp From fb96f6a7d5e2eee2ac0b3fe02d5130708ff72906 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:14:29 +0330 Subject: [PATCH 08/12] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index cd9b4a51..ca63653c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ aiohttp aiofiles aiohttp_cors pillow +gdown From 4cf2fe417d84a123584cdec2d8c94c42156f0a58 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:19:39 +0330 Subject: [PATCH 09/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ebcc21e..0244e504 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ The code is developed under the following configurations. - Hardware: >=4 GPUs for training, >=1 GPU for testing (set ```[--gpus GPUS]``` accordingly) - Software: Ubuntu 16.04.3 LTS, ***CUDA>=8.0, Python>=3.5, PyTorch>=0.4.0*** - Dependencies: numpy, scipy, opencv, yacs, tqdm -- gdown https://drive.google.com/file/d/1Il1Pcb13syeHi9LA9KjXz8KqMFN9izgo +- gdown https://drive.google.com/file/d/1Il1Pcb13syeHi9LA9KjXz8KqMFN9izgo -O ckpt.zip - unzip -j ckpt.zip ## Quick start: Test on an image using our trained model From 24b0ec644e35b07baad7663adb594ce82a1416d0 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:56:34 +0330 Subject: [PATCH 10/12] Update requirements.txt --- requirements.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements.txt b/requirements.txt index ca63653c..cd611a4d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,6 @@ aiofiles aiohttp_cors pillow gdown +uvicorn +fastapi +python-multipart From 43cd6eb09399abde0239fb3d36fdcaca7fc9d2c2 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:58:50 +0330 Subject: [PATCH 11/12] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cd611a4d..8e448121 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,6 @@ aiofiles aiohttp_cors pillow gdown -uvicorn +uvicorn[standard] fastapi python-multipart From 08a234a4580db752819f88b0fa6cd797a33e5c93 Mon Sep 17 00:00:00 2001 From: pythoscorpion <48407814+pythoscorpion@users.noreply.github.com> Date: Sun, 10 Sep 2023 03:07:04 +0330 Subject: [PATCH 12/12] Update demo_test.sh --- demo_test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/demo_test.sh b/demo_test.sh index 2af79c0c..1c4dc8df 100755 --- a/demo_test.sh +++ b/demo_test.sh @@ -35,3 +35,5 @@ python3 -u test.py \ TEST.checkpoint epoch_20.pth fi +# MODEL_NAME=ade20k-hrnetv2-c1 +# python3 -u test_cpu.py --imgs ADE_val_00001519.jpg --cfg config/ade20k-hrnetv2.yaml