├── imgs ├── dog.jpg ├── fig5.png ├── sample.png ├── title.png └── pointrend.png ├── tests ├── dog.jpg ├── check_indexing.ipynb └── test_cityscapes.ipynb ├── model ├── __init__.py ├── deeplab.py ├── resnet.py ├── pointrend.py └── sampling_points.py ├── configs ├── default.yaml └── parser.py ├── infer.py ├── utils ├── metrics.py └── gpus.py ├── readme.md ├── train.py ├── datas ├── __init__.py └── transforms.py ├── .gitignore └── main.py /imgs/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsef123/PointRend-PyTorch/HEAD/imgs/dog.jpg -------------------------------------------------------------------------------- /imgs/fig5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsef123/PointRend-PyTorch/HEAD/imgs/fig5.png -------------------------------------------------------------------------------- /tests/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsef123/PointRend-PyTorch/HEAD/tests/dog.jpg -------------------------------------------------------------------------------- /imgs/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsef123/PointRend-PyTorch/HEAD/imgs/sample.png -------------------------------------------------------------------------------- /imgs/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsef123/PointRend-PyTorch/HEAD/imgs/title.png -------------------------------------------------------------------------------- /imgs/pointrend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsef123/PointRend-PyTorch/HEAD/imgs/pointrend.png -------------------------------------------------------------------------------- /model/__init__.py: -------------------------------------------------------------------------------- 1 | from .sampling_points import sampling_points, point_sample 2 | from torchvision.models.resnet import resnet50, resnet101 3 | from .deeplab import deeplabv3 4 | from .pointrend import PointRend, PointHead 5 | -------------------------------------------------------------------------------- /configs/default.yaml: -------------------------------------------------------------------------------- 1 | data: 2 | name: "cityscapes" 3 | dataset: 4 | root: "./cityscapes" 5 | mode: "fine" 6 | target_type: "semantic" 7 | loader: 8 | batch_size: 6 9 | num_workers: 8 10 | 11 | net: 12 | deeplab: 13 | pretrained: False 14 | resnet: "res101" 15 | head_in_ch: 2048 16 | num_classes: 19 17 | pointhead: 18 | in_c: 531 # 512 + num_classes 19 | num_classes: 19 20 | k: 3 21 | beta: 0.75 22 | 23 | run: 24 | epochs: 200 25 | 26 | train: 27 | lr: 0.01 28 | momentum: 0.9 29 | weight_decay: 0.0001 30 | 31 | apex: 32 | opt: "O0" 33 | -------------------------------------------------------------------------------- /infer.py: -------------------------------------------------------------------------------- 1 | import time 2 | import logging 3 | 4 | import torch 5 | 6 | from utils.metrics import ConfusionMatrix 7 | 8 | 9 | @torch.no_grad() 10 | def infer(loader, net, device): 11 | net.eval() 12 | num_classes = 19 # Hard coding for Cityscapes 13 | metric = ConfusionMatrix(num_classes) 14 | for i, (x, gt) in enumerate(loader): 15 | x = x.to(device, non_blocking=True) 16 | gt = gt.squeeze(1).to(device, dtype=torch.long, non_blocking=True) 17 | 18 | pred = net(x)["fine"].argmax(1) 19 | 20 | metric.update(pred, gt) 21 | 22 | mIoU = metric.mIoU() 23 | logging.info(f"[Infer] mIOU : {mIoU}") 24 | return mIoU 25 | -------------------------------------------------------------------------------- /utils/metrics.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from utils.gpus import reduce_tensor 4 | 5 | 6 | class ConfusionMatrix: 7 | def __init__(self, num_classes, ignore_index=255): 8 | self.N = num_classes 9 | self.ignore_index = ignore_index 10 | self.cm = torch.zeros(self.N, self.N, dtype=torch.float) 11 | 12 | def update(self, pred, gt): 13 | idx = (gt != self.ignore_index) 14 | indices = self.N * gt[idx] + pred[idx] 15 | # cpu version is faster 16 | self.cm += torch.bincount(indices.cpu(), minlength=self.N**2).reshape(self.N, self.N) 17 | 18 | def mIoU(self): 19 | cm = reduce_tensor(self.cm.cuda(), False) 20 | iou = cm.diag() / (cm.sum(dim=1) + cm.sum(dim=0) - cm.diag() + 1e-15) 21 | return iou.mean().cpu().item() 22 | -------------------------------------------------------------------------------- /model/deeplab.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | 3 | from torchvision.models._utils import IntermediateLayerGetter 4 | from torchvision.models.utils import load_state_dict_from_url 5 | from torchvision.models.segmentation._utils import _SimpleSegmentationModel 6 | from torchvision.models.segmentation.deeplabv3 import DeepLabHead 7 | from torchvision.models.segmentation.fcn import FCNHead 8 | from .resnet import resnet103, resnet53 9 | from torchvision.models import resnet50, resnet101 10 | 11 | 12 | class SmallDeepLab(_SimpleSegmentationModel): 13 | def forward(self, input_): 14 | result = self.backbone(input_) 15 | result["coarse"] = self.classifier(result["out"]) 16 | return result 17 | 18 | 19 | def deeplabv3(pretrained=False, resnet="res103", head_in_ch=2048, num_classes=21): 20 | resnet = { 21 | "res53": resnet53, 22 | "res103": resnet103, 23 | "res50": resnet50, 24 | "res101": resnet101 25 | }[resnet] 26 | 27 | net = SmallDeepLab( 28 | backbone=IntermediateLayerGetter( 29 | resnet(pretrained=True, replace_stride_with_dilation=[False, True, True]), 30 | return_layers={'layer2': 'res2', 'layer4': 'out'} 31 | ), 32 | classifier=DeepLabHead(head_in_ch, num_classes) 33 | ) 34 | return net 35 | 36 | 37 | if __name__ == "__main__": 38 | import torch 39 | x = torch.randn(3, 3, 512, 1024).cuda() 40 | net = deeplabv3(False).cuda() 41 | result = net(x) 42 | for k, v in result.items(): 43 | print(k, v.shape) 44 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # PointRend 2 | 3 | A PyTorch implementation of `PointRend: Image Segmentation as Rendering` 4 | 5 | ![title](imgs/title.png) 6 | 7 | ### [[arxiv]](https://arxiv.org/pdf/1912.08193.pdf) [[Official Implementation: Detectron2]](https://github.com/facebookresearch/detectron2/tree/master/projects/PointRend) 8 | 9 |
10 | 11 | This repo for Only Semantic Segmentation on the PascalVOC dataset. 12 | 13 | Many details differ from the paper for feasibilty check. 14 | 15 |
16 | 17 | ## Reproduce Fig 5. 18 | 19 | Sampled Points showing from different strategies on A Dog image. 20 | 21 | See [test_point_sampling.ipynb](tests/test_point_sampling.ipynb) 22 | 23 | Original Figure 24 | 25 | ![fig5](imgs/fig5.png) 26 | 27 | Reference : [Pytorch Deeplab Tutorial](https://pytorch.org/hub/pytorch_vision_deeplabv3_resnet101/) 28 | 29 |
30 | 31 | ## How to use: 32 | 33 | First, fix data path in [default.yaml](config/default.yaml) 34 | 35 | Multi GPU Training 36 | See details in `Single GPU Training` 37 | 38 | ``` 39 | ➜ python3 -m torch.distributed.launch --nproc_per_node={your_gpus} main.py -h 40 | ``` 41 | 42 | Sinle GPU Training 43 | 44 | ``` 45 | ➜ python3 main.py -h 46 | usage: main.py [-h] config save 47 | 48 | PyTorch Object Detection Training 49 | 50 | positional arguments: 51 | config It must be config/*.yaml 52 | save Save path in out directory 53 | 54 | optional arguments: 55 | -h, --help show this help message and exit 56 | ``` 57 | 58 | e.g.) 59 | ``` 60 | python3 main.py config/default.yaml test_codes 61 | ``` 62 | 63 |
64 | -------------------------------------------------------------------------------- /model/resnet.py: -------------------------------------------------------------------------------- 1 | import torch.nn as nn 2 | from torchvision.models.resnet import ResNet, Bottleneck 3 | 4 | 5 | class ResNetXX3(ResNet): 6 | def __init__(self, block, layers, num_classes=1000, zero_init_residual=False, 7 | groups=1, width_per_group=64, replace_stride_with_dilation=None, 8 | norm_layer=None): 9 | super().__init__(block, layers, num_classes, zero_init_residual, 10 | groups, width_per_group, replace_stride_with_dilation, 11 | norm_layer) 12 | self.conv1 = nn.Conv2d(3, 64, 3, 1, 1, bias=False) 13 | nn.init.kaiming_normal_(self.conv1.weight, mode='fan_out', nonlinearity='relu') 14 | 15 | 16 | def resnet53(pretrained=False, progress=True, **kwargs): 17 | r"""ResNet-50 model from 18 | `"Deep Residual Learning for Image Recognition" `_ 19 | Args: 20 | pretrained (bool): If True, returns a model pre-trained on ImageNet 21 | progress (bool): If True, displays a progress bar of the download to stderr 22 | """ 23 | return ResNetXX3(Bottleneck, [3, 4, 6, 3], **kwargs) 24 | 25 | 26 | def resnet103(pretrained=False, progress=True, **kwargs): 27 | r"""ResNet-101 model from 28 | `"Deep Residual Learning for Image Recognition" `_ 29 | Args: 30 | pretrained (bool): If True, returns a model pre-trained on ImageNet 31 | progress (bool): If True, displays a progress bar of the download to stderr 32 | """ 33 | return ResNetXX3(Bottleneck, [3, 4, 23, 3], **kwargs) 34 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import torch 4 | import torch.nn.functional as F 5 | 6 | from model import point_sample 7 | 8 | from infer import infer 9 | 10 | from apex import amp 11 | from utils.gpus import is_main_process, reduce_tensor 12 | 13 | 14 | def step(epoch, loader, net, optim, device): 15 | net.train() 16 | loss_sum = 0 17 | for i, (x, gt) in enumerate(loader): 18 | x = x.to(device, non_blocking=True) 19 | gt = gt.squeeze_(1).to(device, dtype=torch.long, non_blocking=True) 20 | 21 | result = net(x) 22 | 23 | pred = F.interpolate(result["coarse"], x.shape[-2:], mode="bilinear", align_corners=True) 24 | seg_loss = F.cross_entropy(pred, gt, ignore_index=255) 25 | 26 | gt_points = point_sample( 27 | gt.float().unsqueeze(1), 28 | result["points"], 29 | mode="nearest", 30 | align_corners=False 31 | ).squeeze_(1).long() 32 | points_loss = F.cross_entropy(result["rend"], gt_points, ignore_index=255) 33 | 34 | loss = seg_loss + points_loss 35 | 36 | reduce_seg = reduce_tensor(seg_loss) 37 | reduce_point = reduce_tensor(points_loss) 38 | reduce_loss = reduce_seg + reduce_point 39 | 40 | if (i % 10) == 0: 41 | logging.info(f"[Train] Epoch[{epoch:04d}:{i:03d}/{len(loader):03d}] loss : {reduce_loss.item():.5f} seg : {reduce_seg.item():.5f} points : {reduce_point.item():.5f}") 42 | 43 | optim.zero_grad() 44 | with amp.scale_loss(loss, optim) as scaled_loss: 45 | scaled_loss.backward() 46 | optim.step() 47 | 48 | loss_sum += reduce_loss.item() 49 | return loss_sum / len(loader) 50 | 51 | 52 | def train(C, save_dir, loader, val_loader, net, optim, device): 53 | for e in range(C.epochs): 54 | loss = step(e, loader, net, optim, device) 55 | if is_main_process() and (e % 10) == 0: 56 | torch.save(net.state_dict(), 57 | f"{save_dir}/epoch_{e:04d}_loss_{loss:.5f}.pth") 58 | infer(val_loader, net, device) 59 | -------------------------------------------------------------------------------- /datas/__init__.py: -------------------------------------------------------------------------------- 1 | from torch.utils.data import DataLoader, DistributedSampler 2 | from torchvision.datasets.voc import VOCSegmentation 3 | from torchvision.datasets.cityscapes import Cityscapes 4 | 5 | from .transforms import Compose, Resize, ToTensor, Normalize, RandomCrop, RandomFlip, ConvertMaskID 6 | 7 | 8 | def get_voc(C, split="train"): 9 | if split == "train": 10 | transforms = Compose([ 11 | ToTensor(), 12 | RandomCrop((256, 256)), 13 | Resize((256, 256)), 14 | Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), 15 | ]) 16 | else: 17 | transforms = Compose([ 18 | ToTensor(), 19 | Resize((256, 256)), 20 | Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) 21 | ]) 22 | 23 | return VOCSegmentation(C['root'], download=True, image_set=split, transforms=transforms) 24 | 25 | 26 | def get_cityscapes(C, split="train"): 27 | if split == "train": 28 | # Appendix B. Semantic Segmentation Details 29 | transforms = Compose([ 30 | ToTensor(), 31 | RandomCrop(768), 32 | ConvertMaskID(Cityscapes.classes), 33 | RandomFlip(), 34 | Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) 35 | ]) 36 | else: 37 | transforms = Compose([ 38 | ToTensor(), 39 | Resize(768), 40 | ConvertMaskID(Cityscapes.classes), 41 | Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) 42 | ]) 43 | return Cityscapes(**C, split=split, transforms=transforms) 44 | 45 | 46 | def get_loader(C, split, distributed): 47 | """ 48 | Args: 49 | C (Config): C.data 50 | split (str): args of dataset, 51 | The image split to use, ``train``, ``test`` or ``val`` if split="gtFine" 52 | otherwise ``train``, ``train_extra`` or ``val` 53 | """ 54 | print(C.name, C.dataset, split) 55 | if C.name == "cityscapes": 56 | dset = get_cityscapes(C.dataset, split) 57 | elif C.name == "pascalvoc": 58 | dset = get_voc(C.dataset, split) 59 | 60 | if split == "train": 61 | shuffle = True 62 | drop_last = False 63 | else: 64 | shuffle = False 65 | drop_last = False 66 | 67 | sampler = None 68 | if distributed: 69 | sampler = DistributedSampler(dset, shuffle=shuffle) 70 | shuffle = None 71 | 72 | return DataLoader(dset, **C.loader, sampler=sampler, 73 | shuffle=shuffle, drop_last=drop_last, 74 | pin_memory=True) 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .idea/ 3 | 4 | cityscapes 5 | cityscapes/* 6 | 7 | pascalvoc 8 | pascalvoc/* 9 | 10 | outs 11 | outs/* 12 | 13 | .DS_Store 14 | *.npy 15 | *.mat 16 | *.pyc 17 | *.ubuntu 18 | 19 | ################################################################## 20 | # github python ignore 21 | # https://github.com/github/gitignore/blob/master/Python.gitignore 22 | 23 | # Byte-compiled / optimized / DLL files 24 | __pycache__/ 25 | *.py[cod] 26 | *$py.class 27 | 28 | # C extensions 29 | *.so 30 | 31 | # Distribution / packaging 32 | .Python 33 | build/ 34 | develop-eggs/ 35 | dist/ 36 | downloads/ 37 | eggs/ 38 | .eggs/ 39 | lib/ 40 | lib64/ 41 | parts/ 42 | sdist/ 43 | var/ 44 | wheels/ 45 | pip-wheel-metadata/ 46 | share/python-wheels/ 47 | *.egg-info/ 48 | .installed.cfg 49 | *.egg 50 | MANIFEST 51 | 52 | # PyInstaller 53 | # Usually these files are written by a python script from a template 54 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 55 | *.manifest 56 | *.spec 57 | 58 | # Installer logs 59 | pip-log.txt 60 | pip-delete-this-directory.txt 61 | 62 | # Unit test / coverage reports 63 | htmlcov/ 64 | .tox/ 65 | .nox/ 66 | .coverage 67 | .coverage.* 68 | .cache 69 | nosetests.xml 70 | coverage.xml 71 | *.cover 72 | .hypothesis/ 73 | .pytest_cache/ 74 | 75 | # Translations 76 | *.mo 77 | *.pot 78 | 79 | # Django stuff: 80 | *.log 81 | local_settings.py 82 | db.sqlite3 83 | 84 | # Flask stuff: 85 | instance/ 86 | .webassets-cache 87 | 88 | # Scrapy stuff: 89 | .scrapy 90 | 91 | # Sphinx documentation 92 | docs/_build/ 93 | 94 | # PyBuilder 95 | target/ 96 | 97 | # Jupyter Notebook 98 | .ipynb_checkpoints 99 | 100 | # IPython 101 | profile_default/ 102 | ipython_config.py 103 | 104 | # pyenv 105 | .python-version 106 | 107 | # pipenv 108 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 109 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 110 | # having no cross-platform support, pipenv may install dependencies that don’t work, or not 111 | # install all needed dependencies. 112 | #Pipfile.lock 113 | 114 | # celery beat schedule file 115 | celerybeat-schedule 116 | 117 | # SageMath parsed files 118 | *.sage.py 119 | 120 | # Environments 121 | .env 122 | .venv 123 | env/ 124 | venv/ 125 | ENV/ 126 | env.bak/ 127 | venv.bak/ 128 | 129 | # Spyder project settings 130 | .spyderproject 131 | .spyproject 132 | 133 | # Rope project settings 134 | .ropeproject 135 | 136 | # mkdocs documentation 137 | /site 138 | 139 | # mypy 140 | .mypy_cache/ 141 | .dmypy.json 142 | dmypy.json 143 | 144 | # Pyre type checker 145 | .pyre/ 146 | ################################################################ 147 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import argparse 4 | import logging 5 | from configs.parser import Parser 6 | 7 | import torch 8 | 9 | from apex import amp 10 | from apex.parallel import DistributedDataParallel as ApexDDP 11 | 12 | from model import deeplabv3, PointHead, PointRend 13 | from datas import get_loader 14 | from train import train 15 | from utils.gpus import synchronize, is_main_process 16 | 17 | 18 | def parse_args(): 19 | parser = argparse.ArgumentParser(description="PyTorch Object Detection Training") 20 | parser.add_argument("config", type=str, help="It must be config/*.yaml") 21 | parser.add_argument("save", type=str, help="Save path in out directory") 22 | parser.add_argument("--local_rank", type=int, default=0, help="Using for Apex DDP") 23 | return parser.parse_args() 24 | 25 | 26 | def amp_init(args): 27 | # Apex Initialize 28 | args.distributed = False 29 | if 'WORLD_SIZE' in os.environ: 30 | args.distributed = int(os.environ['WORLD_SIZE']) > 1 31 | 32 | if args.distributed: 33 | torch.cuda.set_device(args.local_rank) 34 | torch.distributed.init_process_group(backend="nccl", init_method="env://") 35 | synchronize() 36 | 37 | torch.backends.cudnn.benchmark = True 38 | 39 | 40 | def set_loggging(save_dir): 41 | if not os.path.exists(save_dir): 42 | os.makedirs(save_dir) 43 | 44 | log_format = '%(asctime)s %(message)s' 45 | logging.basicConfig(stream=sys.stdout, level=logging.INFO, 46 | format=log_format, datefmt='[%y/%m/%d %H:%M:%S]') 47 | 48 | fh = logging.FileHandler(f"{save_dir}/log.txt") 49 | fh.setFormatter(logging.Formatter(log_format)) 50 | logging.getLogger().addHandler(fh) 51 | 52 | 53 | if __name__ == "__main__": 54 | args = parse_args() 55 | amp_init(args) 56 | 57 | parser = Parser(args.config) 58 | C = parser.C 59 | save_dir = f"{os.getcwd()}/outs/{args.save}" 60 | 61 | if is_main_process(): 62 | if not os.path.exists(save_dir): 63 | os.makedirs(save_dir, mode=0o775) 64 | 65 | parser.dump(f"{save_dir}/config.yaml") 66 | 67 | set_loggging(save_dir) 68 | 69 | device = torch.device("cuda") 70 | train_loader = get_loader(C.data, "train", distributed=args.distributed) 71 | valid_loader = get_loader(C.data, "val", distributed=args.distributed) 72 | 73 | net = PointRend( 74 | deeplabv3(**C.net.deeplab), 75 | PointHead(**C.net.pointhead) 76 | ).to(device) 77 | 78 | params = [{"params": net.backbone.backbone.parameters(), "lr": C.train.lr}, 79 | {"params": net.head.parameters(), "lr": C.train.lr}, 80 | {"params": net.backbone.classifier.parameters(), "lr": C.train.lr * 10}] 81 | 82 | optim = torch.optim.SGD(params, momentum=C.train.momentum, weight_decay=C.train.weight_decay) 83 | 84 | net, optim = amp.initialize(net, optim, opt_level=C.apex.opt) 85 | if args.distributed: 86 | net = ApexDDP(net, delay_allreduce=True) 87 | 88 | train(C.run, save_dir, train_loader, valid_loader, net, optim, device) 89 | -------------------------------------------------------------------------------- /model/pointrend.py: -------------------------------------------------------------------------------- 1 | 2 | import torch 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | 6 | from . import sampling_points, point_sample 7 | 8 | 9 | class PointHead(nn.Module): 10 | def __init__(self, in_c=532, num_classes=21, k=3, beta=0.75): 11 | super().__init__() 12 | self.mlp = nn.Conv1d(in_c, num_classes, 1) 13 | self.k = k 14 | self.beta = beta 15 | 16 | def forward(self, x, res2, out): 17 | """ 18 | 1. Fine-grained features are interpolated from res2 for DeeplabV3 19 | 2. During training we sample as many points as there are on a stride 16 feature map of the input 20 | 3. To measure prediction uncertainty 21 | we use the same strategy during training and inference: the difference between the most 22 | confident and second most confident class probabilities. 23 | """ 24 | if not self.training: 25 | return self.inference(x, res2, out) 26 | 27 | points = sampling_points(out, x.shape[-1] // 16, self.k, self.beta) 28 | 29 | coarse = point_sample(out, points, align_corners=False) 30 | fine = point_sample(res2, points, align_corners=False) 31 | 32 | feature_representation = torch.cat([coarse, fine], dim=1) 33 | 34 | rend = self.mlp(feature_representation) 35 | 36 | return {"rend": rend, "points": points} 37 | 38 | @torch.no_grad() 39 | def inference(self, x, res2, out): 40 | """ 41 | During inference, subdivision uses N=8096 42 | (i.e., the number of points in the stride 16 map of a 1024×2048 image) 43 | """ 44 | num_points = 8096 45 | 46 | while out.shape[-1] != x.shape[-1]: 47 | out = F.interpolate(out, scale_factor=2, mode="bilinear", align_corners=True) 48 | 49 | points_idx, points = sampling_points(out, num_points, training=self.training) 50 | 51 | coarse = point_sample(out, points, align_corners=False) 52 | fine = point_sample(res2, points, align_corners=False) 53 | 54 | feature_representation = torch.cat([coarse, fine], dim=1) 55 | 56 | rend = self.mlp(feature_representation) 57 | 58 | B, C, H, W = out.shape 59 | points_idx = points_idx.unsqueeze(1).expand(-1, C, -1) 60 | out = (out.reshape(B, C, -1) 61 | .scatter_(2, points_idx, rend) 62 | .view(B, C, H, W)) 63 | 64 | return {"fine": out} 65 | 66 | 67 | class PointRend(nn.Module): 68 | def __init__(self, backbone, head): 69 | super().__init__() 70 | self.backbone = backbone 71 | self.head = head 72 | 73 | def forward(self, x): 74 | result = self.backbone(x) 75 | result.update(self.head(x, result["res2"], result["coarse"])) 76 | return result 77 | 78 | 79 | if __name__ == "__main__": 80 | x = torch.randn(3, 3, 256, 512).cuda() 81 | from deeplab import deeplabv3 82 | net = PointRend(deeplabv3(False), PointHead()).cuda() 83 | out = net(x) 84 | for k, v in out.items(): 85 | print(k, v.shape) 86 | -------------------------------------------------------------------------------- /datas/transforms.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import numpy as np 4 | 5 | import torch 6 | import torch.nn.functional as F 7 | from torchvision import transforms 8 | from torchvision.transforms.functional import normalize 9 | 10 | 11 | class Resize: 12 | def __init__(self, shape): 13 | self.shape = [shape, shape] if isinstance(shape, int) else shape 14 | 15 | def __call__(self, img, mask): 16 | img, mask = img.unsqueeze(0), mask.unsqueeze(0).float() 17 | img = F.interpolate(img, size=self.shape, mode="bilinear", align_corners=False) 18 | mask = F.interpolate(mask, size=self.shape, mode="nearest") 19 | return img[0], mask[0].byte() 20 | 21 | 22 | class RandomCrop: 23 | def __init__(self, shape): 24 | self.shape = [shape, shape] if isinstance(shape, int) else shape 25 | self.fill = 0 26 | self.padding_mode = 'constant' 27 | 28 | def _get_range(self, shape, crop_shape): 29 | if shape == crop_shape: 30 | start = 0 31 | else: 32 | start = random.randint(0, shape - crop_shape) 33 | end = start + crop_shape 34 | return start, end 35 | 36 | def __call__(self, img, mask): 37 | _, h, w = img.shape 38 | sh, eh = self._get_range(h, self.shape[0]) 39 | sw, ew = self._get_range(w, self.shape[1]) 40 | return img[:, sh:eh, sw:ew], mask[:, sh:eh, sw:ew] 41 | 42 | 43 | class RandomFlip: 44 | def __init__(self, prob=0.5, side=(False, True)): 45 | self.prob = prob 46 | self.side = side 47 | 48 | def _flip(self, img, prob): 49 | if self.side[0] and prob[0] <= self.prob: 50 | img = img.flip(1) 51 | if self.side[1] and prob[1] <= self.prob: 52 | img = img.flip(2) 53 | return img 54 | 55 | def __call__(self, img, mask): 56 | prob = (random.uniform(0, 1), random.uniform(0, 1)) 57 | return self._flip(img, prob), self._flip(mask, prob) 58 | 59 | 60 | class ToTensor: 61 | def __init__(self): 62 | self.to_tensor = transforms.ToTensor() 63 | 64 | def __call__(self, img, mask): 65 | img = self.to_tensor(img) 66 | mask = torch.from_numpy(np.array(mask)) 67 | return img, mask[None] 68 | 69 | 70 | class Normalize: 71 | def __init__(self, mean, std): 72 | self.mean = mean 73 | self.std = std 74 | 75 | def __call__(self, img, mask): 76 | return normalize(img, self.mean, self.std, False), mask 77 | 78 | 79 | class Compose: 80 | def __init__(self, transforms): 81 | self.transforms = transforms 82 | 83 | def __call__(self, img, mask): 84 | for t in self.transforms: 85 | img, mask = t(img, mask) 86 | return img, mask 87 | 88 | 89 | class ConvertMaskID: 90 | """ 91 | Convert 34 classes to 19 classes 92 | 93 | Change the `id` value of CityscapesClass to `train_id` 94 | """ 95 | def __init__(self, classes): 96 | self.classes = classes 97 | 98 | def __call__(self, img, mask): 99 | mask_train_id = mask.clone() 100 | for c in self.classes: 101 | mask_train_id[mask == c.id] = c.train_id 102 | 103 | return img, mask_train_id 104 | -------------------------------------------------------------------------------- /configs/parser.py: -------------------------------------------------------------------------------- 1 | import os 2 | import yaml 3 | import logging 4 | import argparse 5 | 6 | 7 | class YamlStructure(dict): 8 | def __init__(self, data): 9 | super().__init__() 10 | assert isinstance(data, dict), "Check Data Type" 11 | self.update(data) 12 | 13 | def __getattr__(self, name): 14 | if name in self.keys(): 15 | return self[name] 16 | 17 | def __repr__(self, path=None): 18 | tmp = {} 19 | 20 | def update(src, dst): 21 | for k, v in src.items(): 22 | if isinstance(v, dict): 23 | dst[k] = {} 24 | update(v, dst[k]) 25 | else: 26 | dst[k] = v 27 | 28 | update(self, tmp) 29 | 30 | if path is not None: 31 | with open(path, 'w') as f: 32 | yaml.dump(tmp, f) 33 | return f"Yaml Dump in {path}" 34 | else: 35 | return yaml.dump(tmp) 36 | 37 | 38 | class Parser: 39 | @staticmethod 40 | def load(path): 41 | with open(path, 'r') as f: 42 | data = yaml.load(f, Loader=yaml.FullLoader) 43 | C = YamlStructure(data) 44 | 45 | def to_structure(d): 46 | for k, v in d.items(): 47 | if isinstance(v, (YamlStructure, dict)): 48 | d[k] = YamlStructure(v) 49 | to_structure(v) 50 | 51 | to_structure(C) 52 | return C 53 | 54 | def __init__(self, path, args=None): 55 | if args is not None: 56 | raise NotImplementedError("Don't use args") 57 | assert isinstance(args, argparse.Namespace), "Check args" 58 | 59 | full_path = f"{os.getcwd()}/{path}" 60 | default_path = full_path.replace(path, "configs/default.yaml") 61 | self.init_yaml(default_path) 62 | self.update_yaml(full_path) 63 | 64 | def init_yaml(self, path): 65 | with open(path, 'r') as f: 66 | data = yaml.load(f, Loader=yaml.FullLoader) 67 | self.C = YamlStructure(data) 68 | 69 | def to_structure(d): 70 | for k, v in d.items(): 71 | if isinstance(v, (YamlStructure, dict)): 72 | d[k] = YamlStructure(v) 73 | to_structure(v) 74 | 75 | to_structure(self.C) 76 | 77 | def update_yaml(self, path): 78 | with open(path, 'r') as f: 79 | data = yaml.load(f, Loader=yaml.FullLoader) 80 | 81 | def update(src, dst): 82 | for k, v in src.items(): 83 | if isinstance(v, dict): 84 | update(v, dst[k]) 85 | elif k in dst.keys(): 86 | dst[k] = v 87 | else: 88 | raise EnvironmentError(f"key({k}) must be in default.yaml") 89 | 90 | update(data, self.C) 91 | 92 | def dump(self, path=None): 93 | self.C.__repr__(path) 94 | 95 | 96 | def arg_parse(): 97 | # projects description 98 | desc = "Test Parser" 99 | parser = argparse.ArgumentParser(description=desc) 100 | parser.add_argument('--save_dir', type=str, default="asdf") 101 | parser.add_argument('--gpu', type=int, default=0, help="Only single gpu") 102 | parser.add_argument('--const_top_k', type=float, default=0.01) 103 | return parser.parse_args() 104 | 105 | 106 | if __name__ == "__main__": 107 | path = "/data2/DW/automl/auto-dip/config/default.yaml" 108 | a = {"b": 1} 109 | args = arg_parse() 110 | p = Parser(path) 111 | print(p.C) 112 | print(p.C.data.name) 113 | print(p.C.search) 114 | p.dump() 115 | -------------------------------------------------------------------------------- /model/sampling_points.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn.functional as F 3 | 4 | 5 | def point_sample(input, point_coords, **kwargs): 6 | """ 7 | From Detectron2, point_features.py#19 8 | 9 | A wrapper around :function:`torch.nn.functional.grid_sample` to support 3D point_coords tensors. 10 | Unlike :function:`torch.nn.functional.grid_sample` it assumes `point_coords` to lie inside 11 | [0, 1] x [0, 1] square. 12 | 13 | Args: 14 | input (Tensor): A tensor of shape (N, C, H, W) that contains features map on a H x W grid. 15 | point_coords (Tensor): A tensor of shape (N, P, 2) or (N, Hgrid, Wgrid, 2) that contains 16 | [0, 1] x [0, 1] normalized point coordinates. 17 | 18 | Returns: 19 | output (Tensor): A tensor of shape (N, C, P) or (N, C, Hgrid, Wgrid) that contains 20 | features for points in `point_coords`. The features are obtained via bilinear 21 | interplation from `input` the same way as :function:`torch.nn.functional.grid_sample`. 22 | """ 23 | add_dim = False 24 | if point_coords.dim() == 3: 25 | add_dim = True 26 | point_coords = point_coords.unsqueeze(2) 27 | output = F.grid_sample(input, 2.0 * point_coords - 1.0, **kwargs) 28 | if add_dim: 29 | output = output.squeeze(3) 30 | return output 31 | 32 | 33 | @torch.no_grad() 34 | def sampling_points(mask, N, k=3, beta=0.75, training=True): 35 | """ 36 | Follows 3.1. Point Selection for Inference and Training 37 | 38 | In Train:, `The sampling strategy selects N points on a feature map to train on.` 39 | 40 | In Inference, `then selects the N most uncertain points` 41 | 42 | Args: 43 | mask(Tensor): [B, C, H, W] 44 | N(int): `During training we sample as many points as there are on a stride 16 feature map of the input` 45 | k(int): Over generation multiplier 46 | beta(float): ratio of importance points 47 | training(bool): flag 48 | 49 | Return: 50 | selected_point(Tensor) : flattened indexing points [B, num_points, 2] 51 | """ 52 | assert mask.dim() == 4, "Dim must be N(Batch)CHW" 53 | device = mask.device 54 | B, _, H, W = mask.shape 55 | mask, _ = mask.sort(1, descending=True) 56 | 57 | if not training: 58 | H_step, W_step = 1 / H, 1 / W 59 | N = min(H * W, N) 60 | uncertainty_map = -1 * (mask[:, 0] - mask[:, 1]) 61 | _, idx = uncertainty_map.view(B, -1).topk(N, dim=1) 62 | 63 | points = torch.zeros(B, N, 2, dtype=torch.float, device=device) 64 | points[:, :, 0] = W_step / 2.0 + (idx % W).to(torch.float) * W_step 65 | points[:, :, 1] = H_step / 2.0 + (idx // W).to(torch.float) * H_step 66 | return idx, points 67 | 68 | # Official Comment : point_features.py#92 69 | # It is crucial to calculate uncertanty based on the sampled prediction value for the points. 70 | # Calculating uncertainties of the coarse predictions first and sampling them for points leads 71 | # to worse results. To illustrate the difference: a sampled point between two coarse predictions 72 | # with -1 and 1 logits has 0 logit prediction and therefore 0 uncertainty value, however, if one 73 | # calculates uncertainties for the coarse predictions first (-1 and -1) and sampe it for the 74 | # center point, they will get -1 unceratinty. 75 | 76 | over_generation = torch.rand(B, k * N, 2, device=device) 77 | over_generation_map = point_sample(mask, over_generation, align_corners=False) 78 | 79 | uncertainty_map = -1 * (over_generation_map[:, 0] - over_generation_map[:, 1]) 80 | _, idx = uncertainty_map.topk(int(beta * N), -1) 81 | 82 | shift = (k * N) * torch.arange(B, dtype=torch.long, device=device) 83 | 84 | idx += shift[:, None] 85 | 86 | importance = over_generation.view(-1, 2)[idx.view(-1), :].view(B, int(beta * N), 2) 87 | coverage = torch.rand(B, N - int(beta * N), 2, device=device) 88 | return torch.cat([importance, coverage], 1).to(device) 89 | -------------------------------------------------------------------------------- /utils/gpus.py: -------------------------------------------------------------------------------- 1 | 2 | import pickle 3 | import time 4 | 5 | import torch 6 | import torch.distributed as dist 7 | 8 | 9 | def get_world_size(): 10 | if not dist.is_available(): 11 | return 1 12 | if not dist.is_initialized(): 13 | return 1 14 | return dist.get_world_size() 15 | 16 | 17 | def get_rank(): 18 | if not dist.is_available(): 19 | return 0 20 | if not dist.is_initialized(): 21 | return 0 22 | return dist.get_rank() 23 | 24 | 25 | def is_main_process(): 26 | return get_rank() == 0 27 | 28 | 29 | def synchronize(): 30 | """ 31 | Helper function to synchronize (barrier) among all processes when 32 | using distributed training 33 | """ 34 | if not dist.is_available(): 35 | return 36 | if not dist.is_initialized(): 37 | return 38 | world_size = dist.get_world_size() 39 | if world_size == 1: 40 | return 41 | dist.barrier() 42 | 43 | 44 | def all_gather(data): 45 | """ 46 | Run all_gather on arbitrary picklable data (not necessarily tensors) 47 | Args: 48 | data: any picklable object 49 | Returns: 50 | list[data]: list of data gathered from each rank 51 | """ 52 | world_size = get_world_size() 53 | if world_size == 1: 54 | return [data] 55 | 56 | # serialized to a Tensor 57 | buffer = pickle.dumps(data) 58 | storage = torch.ByteStorage.from_buffer(buffer) 59 | tensor = torch.ByteTensor(storage).to("cuda") 60 | 61 | # obtain Tensor size of each rank 62 | local_size = torch.LongTensor([tensor.numel()]).to("cuda") 63 | size_list = [torch.LongTensor([0]).to("cuda") for _ in range(world_size)] 64 | dist.all_gather(size_list, local_size) 65 | size_list = [int(size.item()) for size in size_list] 66 | max_size = max(size_list) 67 | 68 | # receiving Tensor from all ranks 69 | # we pad the tensor because torch all_gather does not support 70 | # gathering tensors of different shapes 71 | tensor_list = [] 72 | for _ in size_list: 73 | tensor_list.append(torch.ByteTensor(size=(max_size,)).to("cuda")) 74 | if local_size != max_size: 75 | padding = torch.ByteTensor(size=(max_size - local_size,)).to("cuda") 76 | tensor = torch.cat((tensor, padding), dim=0) 77 | dist.all_gather(tensor_list, tensor) 78 | 79 | data_list = [] 80 | for size, tensor in zip(size_list, tensor_list): 81 | buffer = tensor.cpu().numpy().tobytes()[:size] 82 | data_list.append(pickle.loads(buffer)) 83 | 84 | return data_list 85 | 86 | 87 | @torch.no_grad() 88 | def reduce_tensor(tensor, average=True): 89 | world_size = get_world_size() 90 | if world_size < 2: 91 | return tensor 92 | 93 | dist.reduce(tensor, dst=0) 94 | if dist.get_rank() == 0 and average: 95 | # only main process gets accumulated, so only divide by 96 | # world_size in this case 97 | tensor /= world_size 98 | return tensor 99 | 100 | 101 | @torch.no_grad() 102 | def reduce_dict(input_dict, average=True): 103 | """ 104 | Args: 105 | input_dict (dict): all the values will be reduced 106 | average (bool): whether to do average or sum 107 | Reduce the values in the dictionary from all processes so that process with rank 108 | 0 has the averaged results. Returns a dict with the same fields as 109 | input_dict, after reduction. 110 | """ 111 | world_size = get_world_size() 112 | if world_size < 2: 113 | return input_dict 114 | names = [] 115 | values = [] 116 | # sort the keys so that they are consistent across processes 117 | for k in sorted(input_dict.keys()): 118 | names.append(k) 119 | values.append(input_dict[k]) 120 | values = torch.stack(values, dim=0) 121 | dist.reduce(values, dst=0) 122 | if dist.get_rank() == 0 and average: 123 | # only main process gets accumulated, so only divide by 124 | # world_size in this case 125 | values /= world_size 126 | return {k: v for k, v in zip(names, values)} 127 | -------------------------------------------------------------------------------- /tests/check_indexing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import torch" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "data": { 19 | "text/plain": [ 20 | "tensor([[[ 0, 2, 4, 6, 8],\n", 21 | " [10, 12, 14, 16, 18],\n", 22 | " [20, 22, 24, 26, 28],\n", 23 | " [30, 32, 34, 36, 38],\n", 24 | " [40, 42, 44, 46, 48]],\n", 25 | "\n", 26 | " [[50, 52, 54, 56, 58],\n", 27 | " [60, 62, 64, 66, 68],\n", 28 | " [70, 72, 74, 76, 78],\n", 29 | " [80, 82, 84, 86, 88],\n", 30 | " [90, 92, 94, 96, 98]]])" 31 | ] 32 | }, 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "output_type": "execute_result" 36 | } 37 | ], 38 | "source": [ 39 | "N = 2\n", 40 | "C = 3\n", 41 | "H = 5\n", 42 | "W = 5\n", 43 | "x = torch.arange(N*H*W).reshape(N, H, W)*2\n", 44 | "x" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 3, 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "data": { 54 | "text/plain": [ 55 | "(tensor([[20, 6, 11, 14, 11, 12, 15, 19],\n", 56 | " [ 4, 6, 8, 14, 15, 3, 16, 18]]), torch.Size([2, 8]))" 57 | ] 58 | }, 59 | "execution_count": 3, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "indices = torch.randint(H * W, (N, 8), dtype=torch.long)\n", 66 | "indices, indices.shape" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 4, 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/plain": [ 77 | "(tensor([[40, 12, 22, 28, 22, 24, 30, 38],\n", 78 | " [58, 62, 66, 78, 80, 56, 82, 86]]), torch.Size([2, 8]))" 79 | ] 80 | }, 81 | "execution_count": 4, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "ga = torch.gather(x.view(N, H * W), 1, indices).view(N, -1)\n", 88 | "ga, ga.shape" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 5, 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "(tensor([[0, 0, 0, 0, 0, 0, 0, 0],\n", 100 | " [0, 0, 0, 0, 0, 0, 0, 0]]), tensor([[[ 0, 2, 4, 6, 8],\n", 101 | " [10, 12, 14, 16, 18],\n", 102 | " [20, 22, 24, 26, 28],\n", 103 | " [30, 32, 34, 36, 38],\n", 104 | " [40, 42, 44, 46, 48]],\n", 105 | " \n", 106 | " [[50, 52, 54, 56, 58],\n", 107 | " [60, 62, 64, 66, 68],\n", 108 | " [70, 72, 74, 76, 78],\n", 109 | " [80, 82, 84, 86, 88],\n", 110 | " [90, 92, 94, 96, 98]]]))" 111 | ] 112 | }, 113 | "execution_count": 5, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "ga = ga / 100\n", 120 | "ga, x " 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 6, 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "(tensor([[ 0, 2, 4, 6, 8],\n", 132 | " [10, 12, 14, 16, 18],\n", 133 | " [20, 22, 24, 26, 28],\n", 134 | " [30, 32, 34, 36, 38],\n", 135 | " [40, 42, 44, 46, 48]]), tensor([[50, 52, 54, 56, 58],\n", 136 | " [60, 62, 64, 66, 68],\n", 137 | " [70, 72, 74, 76, 78],\n", 138 | " [80, 82, 84, 86, 88],\n", 139 | " [90, 92, 94, 96, 98]]))" 140 | ] 141 | }, 142 | "execution_count": 6, 143 | "metadata": {}, 144 | "output_type": "execute_result" 145 | } 146 | ], 147 | "source": [ 148 | "x2 = torch.arange(N*C*H*W).reshape(N, C, H, W)*2\n", 149 | "x2[0][0], x2[0][1]" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 7, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "data": { 159 | "text/plain": [ 160 | "torch.Size([2, 3, 8])" 161 | ] 162 | }, 163 | "execution_count": 7, 164 | "metadata": {}, 165 | "output_type": "execute_result" 166 | } 167 | ], 168 | "source": [ 169 | "indices.unsqueeze(1).expand(-1, C, -1).shape" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 8, 175 | "metadata": {}, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "(tensor([[[ 40, 12, 22, 28, 22, 24, 30, 38],\n", 181 | " [ 90, 62, 72, 78, 72, 74, 80, 88],\n", 182 | " [140, 112, 122, 128, 122, 124, 130, 138]],\n", 183 | " \n", 184 | " [[158, 162, 166, 178, 180, 156, 182, 186],\n", 185 | " [208, 212, 216, 228, 230, 206, 232, 236],\n", 186 | " [258, 262, 266, 278, 280, 256, 282, 286]]]), torch.Size([2, 3, 8]))" 187 | ] 188 | }, 189 | "execution_count": 8, 190 | "metadata": {}, 191 | "output_type": "execute_result" 192 | } 193 | ], 194 | "source": [ 195 | "ga = torch.gather(x2.view(N, C, -1), 2, indices.unsqueeze(1).expand(-1, C, -1))\n", 196 | "ga, ga.shape" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 9, 202 | "metadata": {}, 203 | "outputs": [ 204 | { 205 | "data": { 206 | "text/plain": [ 207 | "(tensor([[ 40, 12, 22, 28, 22, 24, 30, 38],\n", 208 | " [158, 162, 166, 178, 180, 156, 182, 186]]),\n", 209 | " tensor([[ 90, 62, 72, 78, 72, 74, 80, 88],\n", 210 | " [208, 212, 216, 228, 230, 206, 232, 236]]))" 211 | ] 212 | }, 213 | "execution_count": 9, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "ga[:, 0, :], ga[:, 1, :]" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": {}, 225 | "source": [ 226 | "# Gather Backward" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 10, 232 | "metadata": {}, 233 | "outputs": [], 234 | "source": [ 235 | "x3 = x2.float().requires_grad_(True)\n", 236 | "ga = torch.gather(x3.view(N, C, -1), 2, indices.unsqueeze(1).expand(-1, C, -1))\n", 237 | "x3.sum().backward()" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 11, 243 | "metadata": {}, 244 | "outputs": [ 245 | { 246 | "data": { 247 | "text/plain": [ 248 | "tensor([[[ 40., 12., 22., 28., 22., 24., 30., 38.],\n", 249 | " [ 90., 62., 72., 78., 72., 74., 80., 88.],\n", 250 | " [140., 112., 122., 128., 122., 124., 130., 138.]],\n", 251 | "\n", 252 | " [[158., 162., 166., 178., 180., 156., 182., 186.],\n", 253 | " [208., 212., 216., 228., 230., 206., 232., 236.],\n", 254 | " [258., 262., 266., 278., 280., 256., 282., 286.]]],\n", 255 | " grad_fn=)" 256 | ] 257 | }, 258 | "execution_count": 11, 259 | "metadata": {}, 260 | "output_type": "execute_result" 261 | } 262 | ], 263 | "source": [ 264 | "ga" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 12, 270 | "metadata": {}, 271 | "outputs": [ 272 | { 273 | "data": { 274 | "text/plain": [ 275 | "(tensor([[16, 5, 6, 8, 13, 3, 22, 16, 24, 16, 20, 18, 22, 11, 2, 3, 2, 12,\n", 276 | " 4, 8, 23, 15, 12, 3, 2, 13, 10, 7, 0, 11],\n", 277 | " [ 5, 13, 7, 20, 6, 1, 19, 18, 17, 8, 11, 3, 10, 7, 9, 19, 19, 11,\n", 278 | " 24, 7, 21, 10, 7, 1, 12, 21, 0, 17, 8, 12]]),\n", 279 | " tensor([[32, 10, 12, 16, 26, 6, 44, 32, 48, 32, 40, 36, 44, 22, 4, 6, 4, 24,\n", 280 | " 8, 16, 46, 30, 24, 6, 4, 26, 20, 14, 0, 22],\n", 281 | " [60, 76, 64, 90, 62, 52, 88, 86, 84, 66, 72, 56, 70, 64, 68, 88, 88, 72,\n", 282 | " 98, 64, 92, 70, 64, 52, 74, 92, 50, 84, 66, 74]]))" 283 | ] 284 | }, 285 | "execution_count": 12, 286 | "metadata": {}, 287 | "output_type": "execute_result" 288 | } 289 | ], 290 | "source": [ 291 | "N = 2\n", 292 | "C = 3\n", 293 | "H = 5\n", 294 | "W = 5\n", 295 | "x = torch.arange(N*H*W).reshape(N, H, W)*2\n", 296 | "indices = torch.randint(H * W, (N, 30), dtype=torch.long)\n", 297 | "ga = torch.gather(x.view(N, H * W), 1, indices).view(N, -1)\n", 298 | "indices, ga" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 13, 304 | "metadata": {}, 305 | "outputs": [ 306 | { 307 | "name": "stdout", 308 | "output_type": "stream", 309 | "text": [ 310 | "Value ; tensor([[48, 46, 44, 44, 40],\n", 311 | " [98, 92, 92, 90, 88]]) torch.Size([2, 5])\n", 312 | "Idx ; tensor([[ 8, 20, 6, 12, 10],\n", 313 | " [18, 25, 20, 3, 15]]) torch.Size([2, 5])\n" 314 | ] 315 | } 316 | ], 317 | "source": [ 318 | "v, i = ga.topk(5)\n", 319 | "print(\"Value ;\", v, v.shape)\n", 320 | "print(\"Idx ;\",i, i.shape)" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 14, 326 | "metadata": {}, 327 | "outputs": [ 328 | { 329 | "data": { 330 | "text/plain": [ 331 | "tensor([[24, 23, 22, 22, 20],\n", 332 | " [24, 21, 21, 20, 19]])" 333 | ] 334 | }, 335 | "execution_count": 14, 336 | "metadata": {}, 337 | "output_type": "execute_result" 338 | } 339 | ], 340 | "source": [ 341 | "reverse_indices = torch.gather(indices, 1, i)\n", 342 | "reverse_indices" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 15, 348 | "metadata": {}, 349 | "outputs": [ 350 | { 351 | "data": { 352 | "text/plain": [ 353 | "tensor([[48, 46, 44, 44, 40],\n", 354 | " [98, 92, 92, 90, 88]])" 355 | ] 356 | }, 357 | "execution_count": 15, 358 | "metadata": {}, 359 | "output_type": "execute_result" 360 | } 361 | ], 362 | "source": [ 363 | "torch.gather(x.view(N, H * W), 1, reverse_indices).view(N, -1)" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 16, 369 | "metadata": {}, 370 | "outputs": [ 371 | { 372 | "data": { 373 | "text/plain": [ 374 | "(tensor([[[ 0, 1, 2, 3],\n", 375 | " [ 4, 5, 6, 7],\n", 376 | " [ 8, 9, 10, 11],\n", 377 | " [12, 13, 14, 15]],\n", 378 | " \n", 379 | " [[16, 17, 18, 19],\n", 380 | " [20, 21, 22, 23],\n", 381 | " [24, 25, 26, 27],\n", 382 | " [28, 29, 30, 31]]]),\n", 383 | " tensor([[[ 0, 1, 2, 3, 4, 5, 6, 7],\n", 384 | " [ 8, 9, 10, 11, 12, 13, 14, 15],\n", 385 | " [ 16, 17, 18, 19, 20, 21, 22, 23],\n", 386 | " [ 24, 25, 26, 27, 28, 29, 30, 31],\n", 387 | " [ 32, 33, 34, 35, 36, 37, 38, 39],\n", 388 | " [ 40, 41, 42, 43, 44, 45, 46, 47],\n", 389 | " [ 48, 49, 50, 51, 52, 53, 54, 55],\n", 390 | " [ 56, 57, 58, 59, 60, 61, 62, 63]],\n", 391 | " \n", 392 | " [[ 64, 65, 66, 67, 68, 69, 70, 71],\n", 393 | " [ 72, 73, 74, 75, 76, 77, 78, 79],\n", 394 | " [ 80, 81, 82, 83, 84, 85, 86, 87],\n", 395 | " [ 88, 89, 90, 91, 92, 93, 94, 95],\n", 396 | " [ 96, 97, 98, 99, 100, 101, 102, 103],\n", 397 | " [104, 105, 106, 107, 108, 109, 110, 111],\n", 398 | " [112, 113, 114, 115, 116, 117, 118, 119],\n", 399 | " [120, 121, 122, 123, 124, 125, 126, 127]]]),\n", 400 | " tensor([[10, 6, 5, 8, 1],\n", 401 | " [10, 2, 9, 9, 10]]))" 402 | ] 403 | }, 404 | "execution_count": 16, 405 | "metadata": {}, 406 | "output_type": "execute_result" 407 | } 408 | ], 409 | "source": [ 410 | "N = 2\n", 411 | "C = 1\n", 412 | "H = 4\n", 413 | "W = 4\n", 414 | "x = torch.arange(N*H*W).reshape(N, H, W)\n", 415 | "indices = torch.randint(H * W, (N, 5), dtype=torch.long)\n", 416 | "\n", 417 | "s = [2, 2]\n", 418 | "x2 = torch.arange(N*H*W*s[0]*s[1]).reshape(N, H*s[0], W*s[1])\n", 419 | "x, x2, indices" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": 17, 425 | "metadata": {}, 426 | "outputs": [ 427 | { 428 | "name": "stdout", 429 | "output_type": "stream", 430 | "text": [ 431 | "tensor([[10, 6, 5, 8, 1],\n", 432 | " [10, 2, 9, 9, 10]]) \n", 433 | " tensor([[36, 20, 18, 32, 2],\n", 434 | " [36, 4, 34, 34, 36]])\n" 435 | ] 436 | } 437 | ], 438 | "source": [ 439 | "ys = (indices // W) * s[0]\n", 440 | "xs = (indices % W) * s[1]\n", 441 | "\n", 442 | "W *= s[1]\n", 443 | "\n", 444 | "new_ind = (ys * W) + xs\n", 445 | "print(indices, \"\\n\", new_ind)" 446 | ] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": 17, 451 | "metadata": {}, 452 | "outputs": [], 453 | "source": [ 454 | "# Infer, Issues #5\n", 455 | "import torch\n", 456 | "N = 2\n", 457 | "C = 3\n", 458 | "H = 4\n", 459 | "W = 4\n", 460 | "x = torch.arange(N*C*H*W).reshape(N, C, H, W).float()\n", 461 | "indices = torch.randint(H * W, (N, 5), dtype=torch.long)" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": 19, 467 | "metadata": {}, 468 | "outputs": [ 469 | { 470 | "data": { 471 | "text/plain": [ 472 | "tensor([[[ -6., -15., -12., -11., -2.],\n", 473 | " [-22., -31., -28., -27., -18.],\n", 474 | " [-38., -47., -44., -43., -34.]],\n", 475 | "\n", 476 | " [[-57., -58., -49., -50., -57.],\n", 477 | " [-73., -74., -65., -66., -73.],\n", 478 | " [-89., -90., -81., -82., -89.]]])" 479 | ] 480 | }, 481 | "execution_count": 19, 482 | "metadata": {}, 483 | "output_type": "execute_result" 484 | } 485 | ], 486 | "source": [ 487 | "ga = torch.gather(x.view(N, C, -1), 2,\n", 488 | " indices.unsqueeze(1).expand(-1, C, -1)) * -1\n", 489 | "ga" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 21, 495 | "metadata": {}, 496 | "outputs": [ 497 | { 498 | "data": { 499 | "text/plain": [ 500 | "tensor([[[ 0., 1., -2., 3., 4., 5., -6., 7., 8., 9., 10.,\n", 501 | " -11., -12., 13., 14., -15.],\n", 502 | " [ 16., 17., -18., 19., 20., 21., -22., 23., 24., 25., 26.,\n", 503 | " -27., -28., 29., 30., -31.],\n", 504 | " [ 32., 33., -34., 35., 36., 37., -38., 39., 40., 41., 42.,\n", 505 | " -43., -44., 45., 46., -47.]],\n", 506 | "\n", 507 | " [[ 48., -49., -50., 51., 52., 53., 54., 55., 56., -57., -58.,\n", 508 | " 59., 60., 61., 62., 63.],\n", 509 | " [ 64., -65., -66., 67., 68., 69., 70., 71., 72., -73., -74.,\n", 510 | " 75., 76., 77., 78., 79.],\n", 511 | " [ 80., -81., -82., 83., 84., 85., 86., 87., 88., -89., -90.,\n", 512 | " 91., 92., 93., 94., 95.]]])" 513 | ] 514 | }, 515 | "execution_count": 21, 516 | "metadata": {}, 517 | "output_type": "execute_result" 518 | } 519 | ], 520 | "source": [ 521 | "rend_pred = x.view(N, C, -1).scatter_(2, indices.unsqueeze(1).expand(-1, C, -1), ga)\n", 522 | "# rend_pred = rend_pred.reshape((N, C, H, W))\n", 523 | "rend_pred" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": null, 529 | "metadata": {}, 530 | "outputs": [], 531 | "source": [] 532 | } 533 | ], 534 | "metadata": { 535 | "kernelspec": { 536 | "display_name": "Python 3", 537 | "language": "python", 538 | "name": "python3" 539 | }, 540 | "language_info": { 541 | "codemirror_mode": { 542 | "name": "ipython", 543 | "version": 3 544 | }, 545 | "file_extension": ".py", 546 | "mimetype": "text/x-python", 547 | "name": "python", 548 | "nbconvert_exporter": "python", 549 | "pygments_lexer": "ipython3", 550 | "version": "3.7.2" 551 | } 552 | }, 553 | "nbformat": 4, 554 | "nbformat_minor": 4 555 | } 556 | -------------------------------------------------------------------------------- /tests/test_cityscapes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "os.chdir(\"..\")" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "metadata": {}, 17 | "outputs": [ 18 | { 19 | "data": { 20 | "text/plain": [ 21 | "dataset:\n", 22 | " mode: fine\n", 23 | " root: ./cityscapes\n", 24 | " target_type: semantic\n", 25 | "loader:\n", 26 | " batch_size: 6\n", 27 | "name: cityscapes" 28 | ] 29 | }, 30 | "execution_count": 2, 31 | "metadata": {}, 32 | "output_type": "execute_result" 33 | } 34 | ], 35 | "source": [ 36 | "from configs.parser import Parser\n", 37 | "\n", 38 | "C = Parser(\"configs/default.yaml\").C.data\n", 39 | "C" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "cityscapes {'root': './cityscapes', 'mode': 'fine', 'target_type': 'semantic'} train\n", 52 | "cityscapes {'root': './cityscapes', 'mode': 'fine', 'target_type': 'semantic'} val\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "from datas import get_loader\n", 58 | "\n", 59 | "train_loader = get_loader(C, \"train\", distributed=False)\n", 60 | "valid_loader = get_loader(C, \"val\", distributed=False)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 29, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "import matplotlib.pyplot as plt\n", 70 | "from torchvision import transforms\n", 71 | "\n", 72 | "\n", 73 | "to_pil = transforms.ToPILImage()\n", 74 | "\n", 75 | "\n", 76 | "def plot(img, mask):\n", 77 | " img = to_pil(img)#.convert(\"RGB\")\n", 78 | " mask = mask.numpy()[0]\n", 79 | " mask[mask == 255] = 0\n", 80 | " \n", 81 | " fig, ax = plt.subplots(1, 2)\n", 82 | " ax[0].set_title(\"Image\")\n", 83 | " ax[0].imshow(img)\n", 84 | " ax[1].set_title(f\"Mask : {np.unique(mask)}\")\n", 85 | " ax[1].imshow(mask)\n", 86 | " plt.show()" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 30, 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "image/png": "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\n", 97 | "text/plain": [ 98 | "
" 99 | ] 100 | }, 101 | "metadata": { 102 | "needs_background": "light" 103 | }, 104 | "output_type": "display_data" 105 | } 106 | ], 107 | "source": [ 108 | "for img, mask in train_loader.dataset:\n", 109 | " plot(img, mask)\n", 110 | " break" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [] 119 | } 120 | ], 121 | "metadata": { 122 | "kernelspec": { 123 | "display_name": "Python 3", 124 | "language": "python", 125 | "name": "python3" 126 | }, 127 | "language_info": { 128 | "codemirror_mode": { 129 | "name": "ipython", 130 | "version": 3 131 | }, 132 | "file_extension": ".py", 133 | "mimetype": "text/x-python", 134 | "name": "python", 135 | "nbconvert_exporter": "python", 136 | "pygments_lexer": "ipython3", 137 | "version": "3.7.2" 138 | } 139 | }, 140 | "nbformat": 4, 141 | "nbformat_minor": 4 142 | } 143 | --------------------------------------------------------------------------------