From 93ba611215e356a744f3b1396042436d4e3c05f2 Mon Sep 17 00:00:00 2001 From: vapaunic <15053814+vapaunic@users.noreply.github.com> Date: Thu, 7 Nov 2019 15:01:11 +0000 Subject: [PATCH] added cela copyright headers to all non-empty .py files (#3) --- cv_lib/cv_lib/__version__.py | 6 +- cv_lib/cv_lib/event_handlers/__init__.py | 23 +- .../cv_lib/event_handlers/logging_handlers.py | 11 +- .../event_handlers/tensorboard_handlers.py | 30 ++- cv_lib/cv_lib/segmentation/__init__.py | 6 +- .../segmentation/dutchf3/augmentations.py | 86 ++++-- cv_lib/cv_lib/segmentation/dutchf3/engine.py | 11 +- .../segmentation/dutchf3/metrics/__init__.py | 28 +- .../segmentation/dutchf3/metrics/apex.py | 3 + cv_lib/cv_lib/segmentation/dutchf3/utils.py | 19 +- cv_lib/cv_lib/segmentation/models/__init__.py | 2 + .../segmentation/models/patch_deconvnet.py | 134 +++++----- .../models/patch_deconvnet_skip.py | 142 +++++----- .../cv_lib/segmentation/models/resnet_unet.py | 248 +++++++++++------- .../segmentation/models/section_deconvnet.py | 156 ++++++----- .../models/section_deconvnet_skip.py | 149 +++++------ cv_lib/cv_lib/segmentation/models/unet.py | 26 +- cv_lib/cv_lib/segmentation/models/utils.py | 101 +++++-- .../cv_lib/segmentation/penobscot/engine.py | 3 + cv_lib/cv_lib/segmentation/utils.py | 29 +- cv_lib/setup.py | 34 +-- deepseismic/__init__.py | 3 + deepseismic/cli/__init__.py | 3 + deepseismic/cli/forward.py | 35 +-- deepseismic/cli/velocity.py | 20 +- deepseismic/forward/__init__.py | 3 + deepseismic/forward/models.py | 26 +- deepseismic/forward/sources.py | 17 +- deepseismic/forward/subdomains.py | 3 + deepseismic/forward/time.py | 3 + deepseismic/forward/types.py | 3 + deepseismic/velocity/__init__.py | 3 + deepseismic/velocity/generator.py | 3 + deepseismic/velocity/roeth_tarantola.py | 9 +- .../interpretation/notebooks/utilities.py | 3 + .../dutchf3_patch/distributed/train.py | 44 +--- imaging/deepseismic_imaging/__init__.py | 3 + imaging/deepseismic_imaging/cli/__init__.py | 3 + imaging/deepseismic_imaging/cli/forward.py | 35 +-- imaging/deepseismic_imaging/cli/velocity.py | 20 +- .../deepseismic_imaging/forward/__init__.py | 3 + imaging/deepseismic_imaging/forward/models.py | 26 +- .../deepseismic_imaging/forward/sources.py | 17 +- .../deepseismic_imaging/forward/subdomains.py | 3 + imaging/deepseismic_imaging/forward/time.py | 3 + imaging/deepseismic_imaging/forward/types.py | 3 + .../deepseismic_imaging/velocity/__init__.py | 3 + .../deepseismic_imaging/velocity/generator.py | 3 + .../velocity/roeth_tarantola.py | 9 +- imaging/setup.py | 5 +- .../dutchf3/data.py | 3 + .../dutchf3/utils/batch.py | 3 + .../penobscot/data.py | 3 + .../penobscot/metrics.py | 11 +- interpretation/setup.py | 6 +- setup.py | 7 +- 56 files changed, 871 insertions(+), 723 deletions(-) diff --git a/cv_lib/cv_lib/__version__.py b/cv_lib/cv_lib/__version__.py index 99c4176c..04ecc805 100644 --- a/cv_lib/cv_lib/__version__.py +++ b/cv_lib/cv_lib/__version__.py @@ -1 +1,5 @@ -__version__ = '0.0.1' \ No newline at end of file +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +__version__ = "0.0.1" + diff --git a/cv_lib/cv_lib/event_handlers/__init__.py b/cv_lib/cv_lib/event_handlers/__init__.py index 589c131c..a2dab4ca 100644 --- a/cv_lib/cv_lib/event_handlers/__init__.py +++ b/cv_lib/cv_lib/event_handlers/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from ignite.handlers import ModelCheckpoint import glob import os @@ -5,12 +8,10 @@ class SnapshotHandler: - def __init__( - self, dir_name, filename_prefix, score_function, snapshot_function - ): + def __init__(self, dir_name, filename_prefix, score_function, snapshot_function): self._model_save_location = dir_name - self._running_model_prefix = filename_prefix+"_running" - self._snapshot_prefix = filename_prefix+"_snapshot" + self._running_model_prefix = filename_prefix + "_running" + self._snapshot_prefix = filename_prefix + "_snapshot" self._snapshot_function = snapshot_function self._snapshot_num = 1 self._score_function = score_function @@ -20,18 +21,20 @@ def _create_checkpoint_handler(self): return ModelCheckpoint( self._model_save_location, self._running_model_prefix, - score_function=self._score_function, + score_function=self._score_function, n_saved=1, create_dir=True, save_as_state_dict=True, - require_empty=False + require_empty=False, ) def __call__(self, engine, to_save): self._checkpoint_handler(engine, to_save) if self._snapshot_function(): files = glob.glob( - os.path.join(self._model_save_location, self._running_model_prefix + "*") + os.path.join( + self._model_save_location, self._running_model_prefix + "*" + ) ) print(files) name_postfix = os.path.basename(files[0]).lstrip(self._running_model_prefix) @@ -42,5 +45,7 @@ def __call__(self, engine, to_save): f"{self._snapshot_prefix}{self._snapshot_num}{name_postfix}", ), ) - self._checkpoint_handler = self._create_checkpoint_handler() # Reset the checkpoint handler + self._checkpoint_handler = ( + self._create_checkpoint_handler() + ) # Reset the checkpoint handler self._snapshot_num += 1 diff --git a/cv_lib/cv_lib/event_handlers/logging_handlers.py b/cv_lib/cv_lib/event_handlers/logging_handlers.py index a6d8f97c..29ea6e76 100644 --- a/cv_lib/cv_lib/event_handlers/logging_handlers.py +++ b/cv_lib/cv_lib/event_handlers/logging_handlers.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import logging import logging.config from toolz import curry @@ -8,7 +11,9 @@ def log_training_output(engine, log_interval=100): logger = logging.getLogger(__name__) if engine.state.iteration % log_interval == 0: - logger.info(f"Epoch: {engine.state.epoch} Iter: {engine.state.iteration} loss {engine.state.output['loss']}") + logger.info( + f"Epoch: {engine.state.epoch} Iter: {engine.state.iteration} loss {engine.state.output['loss']}" + ) @curry @@ -25,7 +30,9 @@ def log_lr(optimizer, engine): def log_metrics(log_msg, engine, metrics_dict=_DEFAULT_METRICS): logger = logging.getLogger(__name__) metrics = engine.state.metrics - metrics_msg = " ".join([f"{metrics_dict[k]} {metrics[k]:.2f}" for k in metrics_dict]) + metrics_msg = " ".join( + [f"{metrics_dict[k]} {metrics[k]:.2f}" for k in metrics_dict] + ) logger.info( f"{log_msg} - Epoch {engine.state.epoch} [{engine.state.max_epochs}] " + metrics_msg diff --git a/cv_lib/cv_lib/event_handlers/tensorboard_handlers.py b/cv_lib/cv_lib/event_handlers/tensorboard_handlers.py index 30e12abd..1c3a574a 100644 --- a/cv_lib/cv_lib/event_handlers/tensorboard_handlers.py +++ b/cv_lib/cv_lib/event_handlers/tensorboard_handlers.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from toolz import curry import torchvision import logging @@ -17,7 +20,9 @@ def create_summary_writer(log_dir): def _log_model_output(log_label, summary_writer, engine): - summary_writer.add_scalar(log_label, engine.state.output["loss"], engine.state.iteration) + summary_writer.add_scalar( + log_label, engine.state.output["loss"], engine.state.iteration + ) @curry @@ -43,17 +48,26 @@ def log_lr(summary_writer, optimizer, log_interval, engine): lr = [param_group["lr"] for param_group in optimizer.param_groups] summary_writer.add_scalar("lr", lr[0], getattr(engine.state, log_interval)) + _DEFAULT_METRICS = {"accuracy": "Avg accuracy :", "nll": "Avg loss :"} + @curry -def log_metrics(summary_writer, train_engine, log_interval, engine, metrics_dict=_DEFAULT_METRICS): +def log_metrics( + summary_writer, train_engine, log_interval, engine, metrics_dict=_DEFAULT_METRICS +): metrics = engine.state.metrics for m in metrics_dict: - summary_writer.add_scalar(metrics_dict[m], metrics[m], getattr(train_engine.state, log_interval)) + summary_writer.add_scalar( + metrics_dict[m], metrics[m], getattr(train_engine.state, log_interval) + ) -def create_image_writer(summary_writer, label, output_variable, normalize=False, transform_func=lambda x: x): +def create_image_writer( + summary_writer, label, output_variable, normalize=False, transform_func=lambda x: x +): logger = logging.getLogger(__name__) + def write_to(engine): try: data_tensor = transform_func(engine.state.output[output_variable]) @@ -62,6 +76,8 @@ def write_to(engine): ) summary_writer.add_image(label, image_grid, engine.state.epoch) except KeyError: - logger.warning("Predictions and or ground truth labels not available to report") - - return write_to \ No newline at end of file + logger.warning( + "Predictions and or ground truth labels not available to report" + ) + + return write_to diff --git a/cv_lib/cv_lib/segmentation/__init__.py b/cv_lib/cv_lib/segmentation/__init__.py index e48edba2..4473ef65 100644 --- a/cv_lib/cv_lib/segmentation/__init__.py +++ b/cv_lib/cv_lib/segmentation/__init__.py @@ -1,6 +1,10 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from toolz import curry import torch.nn.functional as F + @curry def extract_metric_from(metric, engine): metrics = engine.state.metrics @@ -12,4 +16,4 @@ def padded_val_transform(pad_left, fine_size, x, y, y_pred): y_pred = y_pred[ :, :, pad_left : pad_left + fine_size, pad_left : pad_left + fine_size ].contiguous() - return {"image":x, "y_pred": F.sigmoid(y_pred).detach(), "mask":y.detach()} + return {"image": x, "y_pred": F.sigmoid(y_pred).detach(), "mask": y.detach()} diff --git a/cv_lib/cv_lib/segmentation/dutchf3/augmentations.py b/cv_lib/cv_lib/segmentation/dutchf3/augmentations.py index ba9c86ae..d14cc8c8 100644 --- a/cv_lib/cv_lib/segmentation/dutchf3/augmentations.py +++ b/cv_lib/cv_lib/segmentation/dutchf3/augmentations.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import math import numbers import random @@ -5,24 +8,27 @@ from PIL import Image, ImageOps, ImageChops + class Compose(object): def __init__(self, augmentations): self.augmentations = augmentations def __call__(self, img, mask): - img, mask = Image.fromarray(img, mode=None), Image.fromarray(mask, mode='L') + img, mask = Image.fromarray(img, mode=None), Image.fromarray(mask, mode="L") assert img.size == mask.size for a in self.augmentations: img, mask = a(img, mask) return np.array(img), np.array(mask, dtype=np.uint8) + class AddNoise(object): def __call__(self, img, mask): - noise = np.random.normal(loc=0,scale=0.02,size=(img.size[1], img.size[0])) + noise = np.random.normal(loc=0, scale=0.02, size=(img.size[1], img.size[0])) return img + noise, mask + class RandomCrop(object): def __init__(self, size, padding=0): if isinstance(size, numbers.Number): @@ -42,11 +48,17 @@ def __call__(self, img, mask): if w == tw and h == th: return img, mask if w < tw or h < th: - return img.resize((tw, th), Image.BILINEAR), mask.resize((tw, th), Image.NEAREST) + return ( + img.resize((tw, th), Image.BILINEAR), + mask.resize((tw, th), Image.NEAREST), + ) x1 = random.randint(0, w - tw) y1 = random.randint(0, h - th) - return img.crop((x1, y1, x1 + tw, y1 + th)), mask.crop((x1, y1, x1 + tw, y1 + th)) + return ( + img.crop((x1, y1, x1 + tw, y1 + th)), + mask.crop((x1, y1, x1 + tw, y1 + th)), + ) class CenterCrop(object): @@ -60,32 +72,46 @@ def __call__(self, img, mask): assert img.size == mask.size w, h = img.size th, tw = self.size - x1 = int(round((w - tw) / 2.)) - y1 = int(round((h - th) / 2.)) - return img.crop((x1, y1, x1 + tw, y1 + th)), mask.crop((x1, y1, x1 + tw, y1 + th)) + x1 = int(round((w - tw) / 2.0)) + y1 = int(round((h - th) / 2.0)) + return ( + img.crop((x1, y1, x1 + tw, y1 + th)), + mask.crop((x1, y1, x1 + tw, y1 + th)), + ) class RandomHorizontallyFlip(object): def __call__(self, img, mask): if random.random() < 0.5: - #Note: we use FLIP_TOP_BOTTOM here intentionaly. Due to the dimensions of the image, + # Note: we use FLIP_TOP_BOTTOM here intentionaly. Due to the dimensions of the image, # it ends up being a horizontal flip. - return img.transpose(Image.FLIP_TOP_BOTTOM), mask.transpose(Image.FLIP_TOP_BOTTOM) + return ( + img.transpose(Image.FLIP_TOP_BOTTOM), + mask.transpose(Image.FLIP_TOP_BOTTOM), + ) return img, mask - + + class RandomVerticallyFlip(object): def __call__(self, img, mask): if random.random() < 0.5: - return img.transpose(Image.FLIP_LEFT_RIGHT), mask.transpose(Image.FLIP_LEFT_RIGHT) + return ( + img.transpose(Image.FLIP_LEFT_RIGHT), + mask.transpose(Image.FLIP_LEFT_RIGHT), + ) return img, mask - + + class FreeScale(object): def __init__(self, size): self.size = tuple(reversed(size)) # size: (h, w) def __call__(self, img, mask): assert img.size == mask.size - return img.resize(self.size, Image.BILINEAR), mask.resize(self.size, Image.NEAREST) + return ( + img.resize(self.size, Image.BILINEAR), + mask.resize(self.size, Image.NEAREST), + ) class Scale(object): @@ -100,11 +126,17 @@ def __call__(self, img, mask): if w > h: ow = self.size oh = int(self.size * h / w) - return img.resize((ow, oh), Image.BILINEAR), mask.resize((ow, oh), Image.NEAREST) + return ( + img.resize((ow, oh), Image.BILINEAR), + mask.resize((ow, oh), Image.NEAREST), + ) else: oh = self.size ow = int(self.size * w / h) - return img.resize((ow, oh), Image.BILINEAR), mask.resize((ow, oh), Image.NEAREST) + return ( + img.resize((ow, oh), Image.BILINEAR), + mask.resize((ow, oh), Image.NEAREST), + ) class RandomSizedCrop(object): @@ -130,10 +162,12 @@ def __call__(self, img, mask): img = img.crop((x1, y1, x1 + w, y1 + h)) mask = mask.crop((x1, y1, x1 + w, y1 + h)) - assert (img.size == (w, h)) + assert img.size == (w, h) - return img.resize((self.size, self.size), Image.BILINEAR), mask.resize((self.size, self.size), - Image.NEAREST) + return ( + img.resize((self.size, self.size), Image.BILINEAR), + mask.resize((self.size, self.size), Image.NEAREST), + ) # Fallback scale = Scale(self.size) @@ -146,26 +180,27 @@ def __init__(self, degree): self.degree = degree def __call__(self, img, mask): - ''' + """ PIL automatically adds zeros to the borders of images that rotated. To fix this issue, the code in the botton sets anywhere in the labels (mask) that is zero to 255 (the value used for ignore_index). - ''' + """ rotate_degree = random.random() * 2 * self.degree - self.degree img = img.rotate(rotate_degree, Image.BILINEAR) - mask = mask.rotate(rotate_degree, Image.NEAREST) + mask = mask.rotate(rotate_degree, Image.NEAREST) binary_mask = Image.fromarray(np.ones([mask.size[1], mask.size[0]])) binary_mask = binary_mask.rotate(rotate_degree, Image.NEAREST) binary_mask = np.array(binary_mask) mask_arr = np.array(mask) - mask_arr[binary_mask==0] = 255 + mask_arr[binary_mask == 0] = 255 mask = Image.fromarray(mask_arr) return img, mask + class RandomSized(object): def __init__(self, size): self.size = size @@ -178,6 +213,9 @@ def __call__(self, img, mask): w = int(random.uniform(0.5, 2) * img.size[0]) h = int(random.uniform(0.5, 2) * img.size[1]) - img, mask = img.resize((w, h), Image.BILINEAR), mask.resize((w, h), Image.NEAREST) + img, mask = ( + img.resize((w, h), Image.BILINEAR), + mask.resize((w, h), Image.NEAREST), + ) - return self.crop(*self.scale(img, mask)) \ No newline at end of file + return self.crop(*self.scale(img, mask)) diff --git a/cv_lib/cv_lib/segmentation/dutchf3/engine.py b/cv_lib/cv_lib/segmentation/dutchf3/engine.py index 1bb8aa39..5d3afbbf 100644 --- a/cv_lib/cv_lib/segmentation/dutchf3/engine.py +++ b/cv_lib/cv_lib/segmentation/dutchf3/engine.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch from ignite.engine.engine import Engine, State, Events @@ -7,13 +10,15 @@ from torch.nn import functional as F import numpy as np + def _upscale_model_output(y_pred, y): ph, pw = y_pred.size(2), y_pred.size(3) h, w = y.size(2), y.size(3) if ph != h or pw != w: - y_pred = F.upsample(input=y_pred, size=(h, w), mode='bilinear') + y_pred = F.upsample(input=y_pred, size=(h, w), mode="bilinear") return y_pred - + + def create_supervised_trainer( model, optimizer, @@ -42,7 +47,7 @@ def _update(engine, batch): @curry def val_transform(x, y, y_pred): - return {"image":x, "y_pred": y_pred.detach(), "mask":y.detach()} + return {"image": x, "y_pred": y_pred.detach(), "mask": y.detach()} def create_supervised_evaluator( diff --git a/cv_lib/cv_lib/segmentation/dutchf3/metrics/__init__.py b/cv_lib/cv_lib/segmentation/dutchf3/metrics/__init__.py index 2e50423e..3c4d5540 100644 --- a/cv_lib/cv_lib/segmentation/dutchf3/metrics/__init__.py +++ b/cv_lib/cv_lib/segmentation/dutchf3/metrics/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import numpy as np import warnings @@ -43,15 +46,17 @@ def __init__(self, num_classes, device, output_transform=lambda x: x): super(ConfusionMatrix, self).__init__(output_transform=output_transform) def reset(self): - self._confusion_matrix = torch.zeros((self._num_classes, self._num_classes),dtype=torch.long).to(self._device) + self._confusion_matrix = torch.zeros( + (self._num_classes, self._num_classes), dtype=torch.long + ).to(self._device) def update(self, output): y_pred, y = output - #TODO: Make assertion exception - assert y.shape==y_pred.max(1)[1].squeeze().shape, "Shape not the same" + # TODO: Make assertion exception + assert y.shape == y_pred.max(1)[1].squeeze().shape, "Shape not the same" self._confusion_matrix += _torch_hist( torch.flatten(y), - torch.flatten(y_pred.max(1)[1].squeeze()), # Get the maximum index + torch.flatten(y_pred.max(1)[1].squeeze()), # Get the maximum index self._num_classes, ) @@ -62,9 +67,7 @@ def compute(self): class MeanIoU(ConfusionMatrix): def compute(self): hist = self._confusion_matrix.cpu().numpy() - iu = np.diag(hist) / ( - hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist) - ) + iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist)) mean_iu = np.nanmean(iu) return mean_iu @@ -75,13 +78,14 @@ def compute(self): acc = np.diag(hist).sum() / hist.sum() return acc + class FrequencyWeightedIoU(ConfusionMatrix): def compute(self): hist = self._confusion_matrix.cpu().numpy() - iu = np.diag(hist) / ( - hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist) - ) - freq = hist.sum(axis=1) / hist.sum() # fraction of the pixels that come from each class + iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist)) + freq = ( + hist.sum(axis=1) / hist.sum() + ) # fraction of the pixels that come from each class fwiou = (freq[freq > 0] * iu[freq > 0]).sum() return fwiou @@ -92,4 +96,4 @@ def compute(self): acc = np.diag(hist).sum() / hist.sum() acc_cls = np.diag(hist) / hist.sum(axis=1) mean_acc_cls = np.nanmean(acc_cls) - return mean_acc_cls \ No newline at end of file + return mean_acc_cls diff --git a/cv_lib/cv_lib/segmentation/dutchf3/metrics/apex.py b/cv_lib/cv_lib/segmentation/dutchf3/metrics/apex.py index 10967f09..400bacca 100644 --- a/cv_lib/cv_lib/segmentation/dutchf3/metrics/apex.py +++ b/cv_lib/cv_lib/segmentation/dutchf3/metrics/apex.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import numpy as np import torch import torch.distributed as dist diff --git a/cv_lib/cv_lib/segmentation/dutchf3/utils.py b/cv_lib/cv_lib/segmentation/dutchf3/utils.py index 52bfa0bc..1d509b95 100644 --- a/cv_lib/cv_lib/segmentation/dutchf3/utils.py +++ b/cv_lib/cv_lib/segmentation/dutchf3/utils.py @@ -1,30 +1,34 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import numpy as np -import torch +import torch import torchvision.utils as vutils from git import Repo from datetime import datetime import os + def np_to_tb(array): # if 2D : if array.ndim == 2: # HW => CHW - array = np.expand_dims(array,axis=0) + array = np.expand_dims(array, axis=0) # CHW => NCHW - array = np.expand_dims(array,axis=0) + array = np.expand_dims(array, axis=0) elif array.ndim == 3: # HWC => CHW array = array.transpose(2, 0, 1) # CHW => NCHW - array = np.expand_dims(array,axis=0) - + array = np.expand_dims(array, axis=0) + array = torch.from_numpy(array) # array = vutils.make_grid(array, normalize=True, scale_each=True) return array def current_datetime(): - return datetime.now().strftime('%b%d_%H%M%S') + return datetime.now().strftime("%b%d_%H%M%S") def git_branch(): @@ -36,8 +40,9 @@ def git_hash(): repo = Repo(search_parent_directories=True) return repo.active_branch.commit.hexsha + def generate_path(base_path, *directories): path = os.path.join(base_path, *directories) if not os.path.exists(path): os.makedirs(path) - return path \ No newline at end of file + return path diff --git a/cv_lib/cv_lib/segmentation/models/__init__.py b/cv_lib/cv_lib/segmentation/models/__init__.py index 93967f4e..499803f5 100644 --- a/cv_lib/cv_lib/segmentation/models/__init__.py +++ b/cv_lib/cv_lib/segmentation/models/__init__.py @@ -1,3 +1,5 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. import cv_lib.segmentation.models.seg_hrnet import cv_lib.segmentation.models.resnet_unet diff --git a/cv_lib/cv_lib/segmentation/models/patch_deconvnet.py b/cv_lib/cv_lib/segmentation/models/patch_deconvnet.py index b45f6fc4..1d274446 100644 --- a/cv_lib/cv_lib/segmentation/models/patch_deconvnet.py +++ b/cv_lib/cv_lib/segmentation/models/patch_deconvnet.py @@ -1,259 +1,241 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch.nn as nn -class patch_deconvnet(nn.Module): +class patch_deconvnet(nn.Module): def __init__(self, n_classes=4, learned_billinear=False): super(patch_deconvnet, self).__init__() self.learned_billinear = learned_billinear self.n_classes = n_classes self.unpool = nn.MaxUnpool2d(2, stride=2) self.conv_block1 = nn.Sequential( - # conv1_1 nn.Conv2d(1, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv1_2 nn.Conv2d(64, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool1 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_1 # 48*48 self.conv_block2 = nn.Sequential( - # conv2_1 nn.Conv2d(64, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv2_2 nn.Conv2d(128, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool2 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_2 # 24*24 self.conv_block3 = nn.Sequential( - # conv3_1 nn.Conv2d(128, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_2 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_3 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool3 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_3 # 12*12 self.conv_block4 = nn.Sequential( - # conv4_1 nn.Conv2d(256, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool4 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_4 # 6*6 self.conv_block5 = nn.Sequential( - # conv5_1 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool5 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_5 # 3*3 self.conv_block6 = nn.Sequential( - # fc6 nn.Conv2d(512, 4096, 3), # set the filter size and nor padding to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 1*1 self.conv_block7 = nn.Sequential( - # fc7 nn.Conv2d(4096, 4096, 1), # set the filter size to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.deconv_block8 = nn.Sequential( - # fc6-deconv nn.ConvTranspose2d(4096, 512, 3, stride=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 3*3 self.unpool_block9 = nn.Sequential( - # unpool5 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # usage unpool(output, indices) # 6*6 self.deconv_block10 = nn.Sequential( - # deconv5_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_3 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block11 = nn.Sequential( - # unpool4 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 12*12 self.deconv_block12 = nn.Sequential( - # deconv4_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_3 nn.ConvTranspose2d(512, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block13 = nn.Sequential( - # unpool3 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 24*24 self.deconv_block14 = nn.Sequential( - # deconv3_1 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_2 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_3 nn.ConvTranspose2d(256, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block15 = nn.Sequential( - # unpool2 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 48*48 self.deconv_block16 = nn.Sequential( - # deconv2_1 nn.ConvTranspose2d(128, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv2_2 nn.ConvTranspose2d(128, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block17 = nn.Sequential( - # unpool1 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 96*96 self.deconv_block18 = nn.Sequential( - # deconv1_1 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv1_2 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.seg_score19 = nn.Sequential( - # seg-score - nn.Conv2d(64, self.n_classes, 1), ) + nn.Conv2d(64, self.n_classes, 1), + ) if self.learned_billinear: raise NotImplementedError @@ -288,24 +270,30 @@ def forward(self, x): return out def init_vgg16_params(self, vgg16, copy_fc8=True): - blocks = [self.conv_block1, - self.conv_block2, - self.conv_block3, - self.conv_block4, - self.conv_block5] + blocks = [ + self.conv_block1, + self.conv_block2, + self.conv_block3, + self.conv_block4, + self.conv_block5, + ] ranges = [[0, 4], [5, 9], [10, 16], [17, 23], [24, 29]] features = list(vgg16.features.children()) - i_layer = 0; + i_layer = 0 # copy convolutional filters from vgg16 for idx, conv_block in enumerate(blocks): - for l1, l2 in zip(features[ranges[idx][0]:ranges[idx][1]], conv_block): + for l1, l2 in zip(features[ranges[idx][0] : ranges[idx][1]], conv_block): if isinstance(l1, nn.Conv2d) and isinstance(l2, nn.Conv2d): if i_layer == 0: - l2.weight.data = ((l1.weight.data[:, 0, :, :] + l1.weight.data[:, 1, :, :] + l1.weight.data[:, - 2, :, - :]) / 3.0).view( - l2.weight.size()) + l2.weight.data = ( + ( + l1.weight.data[:, 0, :, :] + + l1.weight.data[:, 1, :, :] + + l1.weight.data[:, 2, :, :] + ) + / 3.0 + ).view(l2.weight.size()) l2.bias.data = l1.bias.data i_layer = i_layer + 1 else: @@ -317,7 +305,9 @@ def init_vgg16_params(self, vgg16, copy_fc8=True): def get_seg_model(cfg, **kwargs): - assert cfg.MODEL.IN_CHANNELS==1, f"Patch deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" + assert ( + cfg.MODEL.IN_CHANNELS == 1 + ), f"Patch deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" model = patch_deconvnet(n_classes=cfg.DATASET.NUM_CLASSES) return model diff --git a/cv_lib/cv_lib/segmentation/models/patch_deconvnet_skip.py b/cv_lib/cv_lib/segmentation/models/patch_deconvnet_skip.py index 52b8eda2..1b42a19d 100644 --- a/cv_lib/cv_lib/segmentation/models/patch_deconvnet_skip.py +++ b/cv_lib/cv_lib/segmentation/models/patch_deconvnet_skip.py @@ -1,259 +1,241 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch.nn as nn -class patch_deconvnet_skip(nn.Module): +class patch_deconvnet_skip(nn.Module): def __init__(self, n_classes=4, learned_billinear=False): super(patch_deconvnet_skip, self).__init__() self.learned_billinear = learned_billinear self.n_classes = n_classes self.unpool = nn.MaxUnpool2d(2, stride=2) self.conv_block1 = nn.Sequential( - # conv1_1 nn.Conv2d(1, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv1_2 nn.Conv2d(64, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool1 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_1 # 48*48 self.conv_block2 = nn.Sequential( - # conv2_1 nn.Conv2d(64, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv2_2 nn.Conv2d(128, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool2 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_2 # 24*24 self.conv_block3 = nn.Sequential( - # conv3_1 nn.Conv2d(128, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_2 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_3 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool3 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_3 # 12*12 self.conv_block4 = nn.Sequential( - # conv4_1 nn.Conv2d(256, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool4 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_4 # 6*6 self.conv_block5 = nn.Sequential( - # conv5_1 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool5 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_5 # 3*3 self.conv_block6 = nn.Sequential( - # fc6 nn.Conv2d(512, 4096, 3), # set the filter size and nor padding to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 1*1 self.conv_block7 = nn.Sequential( - # fc7 nn.Conv2d(4096, 4096, 1), # set the filter size to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.deconv_block8 = nn.Sequential( - # fc6-deconv nn.ConvTranspose2d(4096, 512, 3, stride=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 3*3 self.unpool_block9 = nn.Sequential( - # unpool5 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # usage unpool(output, indices) # 6*6 self.deconv_block10 = nn.Sequential( - # deconv5_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_3 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block11 = nn.Sequential( - # unpool4 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 12*12 self.deconv_block12 = nn.Sequential( - # deconv4_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_3 nn.ConvTranspose2d(512, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block13 = nn.Sequential( - # unpool3 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 24*24 self.deconv_block14 = nn.Sequential( - # deconv3_1 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_2 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_3 nn.ConvTranspose2d(256, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block15 = nn.Sequential( - # unpool2 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 48*48 self.deconv_block16 = nn.Sequential( - # deconv2_1 nn.ConvTranspose2d(128, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv2_2 nn.ConvTranspose2d(128, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block17 = nn.Sequential( - # unpool1 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 96*96 self.deconv_block18 = nn.Sequential( - # deconv1_1 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv1_2 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.seg_score19 = nn.Sequential( - # seg-score - nn.Conv2d(64, self.n_classes, 1), ) + nn.Conv2d(64, self.n_classes, 1), + ) if self.learned_billinear: raise NotImplementedError @@ -273,39 +255,45 @@ def forward(self, x): conv6 = self.conv_block6(conv5) conv7 = self.conv_block7(conv6) conv8 = self.deconv_block8(conv7) + conv5 - conv9 = self.unpool(conv8,indices5, output_size=size4) + conv9 = self.unpool(conv8, indices5, output_size=size4) conv10 = self.deconv_block10(conv9) + conv4 - conv11 = self.unpool(conv10,indices4, output_size=size3) + conv11 = self.unpool(conv10, indices4, output_size=size3) conv12 = self.deconv_block12(conv11) + conv3 - conv13 = self.unpool(conv12,indices3, output_size=size2) + conv13 = self.unpool(conv12, indices3, output_size=size2) conv14 = self.deconv_block14(conv13) + conv2 - conv15 = self.unpool(conv14,indices2, output_size=size1) + conv15 = self.unpool(conv14, indices2, output_size=size1) conv16 = self.deconv_block16(conv15) + conv1 - conv17 = self.unpool(conv16,indices1, output_size=size0) + conv17 = self.unpool(conv16, indices1, output_size=size0) conv18 = self.deconv_block18(conv17) out = self.seg_score19(conv18) return out def init_vgg16_params(self, vgg16, copy_fc8=True): - blocks = [self.conv_block1, - self.conv_block2, - self.conv_block3, - self.conv_block4, - self.conv_block5] + blocks = [ + self.conv_block1, + self.conv_block2, + self.conv_block3, + self.conv_block4, + self.conv_block5, + ] ranges = [[0, 4], [5, 9], [10, 16], [17, 23], [24, 29]] features = list(vgg16.features.children()) i_layer = 0 # copy convolutional filters from vgg16 for idx, conv_block in enumerate(blocks): - for l1, l2 in zip(features[ranges[idx][0]:ranges[idx][1]], conv_block): + for l1, l2 in zip(features[ranges[idx][0] : ranges[idx][1]], conv_block): if isinstance(l1, nn.Conv2d) and isinstance(l2, nn.Conv2d): if i_layer == 0: - l2.weight.data = ((l1.weight.data[:, 0, :, :] + l1.weight.data[:, 1, :, :] + l1.weight.data[:, - 2, :, - :]) / 3.0).view( - l2.weight.size()) + l2.weight.data = ( + ( + l1.weight.data[:, 0, :, :] + + l1.weight.data[:, 1, :, :] + + l1.weight.data[:, 2, :, :] + ) + / 3.0 + ).view(l2.weight.size()) l2.bias.data = l1.bias.data i_layer = i_layer + 1 else: @@ -317,7 +305,9 @@ def init_vgg16_params(self, vgg16, copy_fc8=True): def get_seg_model(cfg, **kwargs): - assert cfg.MODEL.IN_CHANNELS==1, f"Patch deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" + assert ( + cfg.MODEL.IN_CHANNELS == 1 + ), f"Patch deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" model = patch_deconvnet_skip(n_classes=cfg.DATASET.NUM_CLASSES) return model diff --git a/cv_lib/cv_lib/segmentation/models/resnet_unet.py b/cv_lib/cv_lib/segmentation/models/resnet_unet.py index f226125f..dbf6eb13 100644 --- a/cv_lib/cv_lib/segmentation/models/resnet_unet.py +++ b/cv_lib/cv_lib/segmentation/models/resnet_unet.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch import torch.nn as nn import torch.nn.functional as F @@ -7,31 +10,49 @@ class FPAv2(nn.Module): def __init__(self, input_dim, output_dim): super(FPAv2, self).__init__() - self.glob = nn.Sequential(nn.AdaptiveAvgPool2d(1), - nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False)) - - self.down2_1 = nn.Sequential(nn.Conv2d(input_dim, input_dim, kernel_size=5, stride=2, padding=2, bias=False), - nn.BatchNorm2d(input_dim), - nn.ELU(True)) - self.down2_2 = nn.Sequential(nn.Conv2d(input_dim, output_dim, kernel_size=5, padding=2, bias=False), - nn.BatchNorm2d(output_dim), - nn.ELU(True)) - - self.down3_1 = nn.Sequential(nn.Conv2d(input_dim, input_dim, kernel_size=3, stride=2, padding=1, bias=False), - nn.BatchNorm2d(input_dim), - nn.ELU(True)) - self.down3_2 = nn.Sequential(nn.Conv2d(input_dim, output_dim, kernel_size=3, padding=1, bias=False), - nn.BatchNorm2d(output_dim), - nn.ELU(True)) - - self.conv1 = nn.Sequential(nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False), - nn.BatchNorm2d(output_dim), - nn.ELU(True)) + self.glob = nn.Sequential( + nn.AdaptiveAvgPool2d(1), + nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False), + ) + + self.down2_1 = nn.Sequential( + nn.Conv2d( + input_dim, input_dim, kernel_size=5, stride=2, padding=2, bias=False + ), + nn.BatchNorm2d(input_dim), + nn.ELU(True), + ) + self.down2_2 = nn.Sequential( + nn.Conv2d(input_dim, output_dim, kernel_size=5, padding=2, bias=False), + nn.BatchNorm2d(output_dim), + nn.ELU(True), + ) + + self.down3_1 = nn.Sequential( + nn.Conv2d( + input_dim, input_dim, kernel_size=3, stride=2, padding=1, bias=False + ), + nn.BatchNorm2d(input_dim), + nn.ELU(True), + ) + self.down3_2 = nn.Sequential( + nn.Conv2d(input_dim, output_dim, kernel_size=3, padding=1, bias=False), + nn.BatchNorm2d(output_dim), + nn.ELU(True), + ) + + self.conv1 = nn.Sequential( + nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False), + nn.BatchNorm2d(output_dim), + nn.ELU(True), + ) def forward(self, x): # x shape: 512, 16, 16 x_glob = self.glob(x) # 256, 1, 1 - x_glob = F.upsample(x_glob, scale_factor=16, mode='bilinear', align_corners=True) # 256, 16, 16 + x_glob = F.upsample( + x_glob, scale_factor=16, mode="bilinear", align_corners=True + ) # 256, 16, 16 d2 = self.down2_1(x) # 512, 8, 8 d3 = self.down3_1(d2) # 512, 4, 4 @@ -39,10 +60,14 @@ def forward(self, x): d2 = self.down2_2(d2) # 256, 8, 8 d3 = self.down3_2(d3) # 256, 4, 4 - d3 = F.upsample(d3, scale_factor=2, mode='bilinear', align_corners=True) # 256, 8, 8 + d3 = F.upsample( + d3, scale_factor=2, mode="bilinear", align_corners=True + ) # 256, 8, 8 d2 = d2 + d3 - d2 = F.upsample(d2, scale_factor=2, mode='bilinear', align_corners=True) # 256, 16, 16 + d2 = F.upsample( + d2, scale_factor=2, mode="bilinear", align_corners=True + ) # 256, 16, 16 x = self.conv1(x) # 256, 16, 16 x = x * d2 @@ -52,9 +77,18 @@ def forward(self, x): def conv3x3(input_dim, output_dim, rate=1): - return nn.Sequential(nn.Conv2d(input_dim, output_dim, kernel_size=3, dilation=rate, padding=rate, bias=False), - nn.BatchNorm2d(output_dim), - nn.ELU(True)) + return nn.Sequential( + nn.Conv2d( + input_dim, + output_dim, + kernel_size=3, + dilation=rate, + padding=rate, + bias=False, + ), + nn.BatchNorm2d(output_dim), + nn.ELU(True), + ) class SpatialAttention2d(nn.Module): @@ -73,8 +107,12 @@ class GAB(nn.Module): def __init__(self, input_dim, reduction=4): super(GAB, self).__init__() self.global_avgpool = nn.AdaptiveAvgPool2d(1) - self.conv1 = nn.Conv2d(input_dim, input_dim // reduction, kernel_size=1, stride=1) - self.conv2 = nn.Conv2d(input_dim // reduction, input_dim, kernel_size=1, stride=1) + self.conv1 = nn.Conv2d( + input_dim, input_dim // reduction, kernel_size=1, stride=1 + ) + self.conv2 = nn.Conv2d( + input_dim // reduction, input_dim, kernel_size=1, stride=1 + ) self.relu = nn.ReLU(inplace=True) self.sigmoid = nn.Sigmoid() @@ -94,7 +132,7 @@ def __init__(self, in_channels, channels, out_channels): self.c_att = GAB(out_channels, 16) def forward(self, x, e=None): - x = F.upsample(input=x, scale_factor=2, mode='bilinear', align_corners=True) + x = F.upsample(input=x, scale_factor=2, mode="bilinear", align_corners=True) if e is not None: x = torch.cat([x, e], 1) x = self.conv1(x) @@ -143,22 +181,14 @@ def __init__(self, n_classes=1): super(Res34Unetv4, self).__init__() self.resnet = torchvision.models.resnet34(True) - self.conv1 = nn.Sequential( - self.resnet.conv1, - self.resnet.bn1, - self.resnet.relu) + self.conv1 = nn.Sequential(self.resnet.conv1, self.resnet.bn1, self.resnet.relu) - self.encode2 = nn.Sequential(self.resnet.layer1, - SCse(64)) - self.encode3 = nn.Sequential(self.resnet.layer2, - SCse(128)) - self.encode4 = nn.Sequential(self.resnet.layer3, - SCse(256)) - self.encode5 = nn.Sequential(self.resnet.layer4, - SCse(512)) + self.encode2 = nn.Sequential(self.resnet.layer1, SCse(64)) + self.encode3 = nn.Sequential(self.resnet.layer2, SCse(128)) + self.encode4 = nn.Sequential(self.resnet.layer3, SCse(256)) + self.encode5 = nn.Sequential(self.resnet.layer4, SCse(512)) - self.center = nn.Sequential(FPAv2(512, 256), - nn.MaxPool2d(2, 2)) + self.center = nn.Sequential(FPAv2(512, 256), nn.MaxPool2d(2, 2)) self.decode5 = Decoderv2(256, 512, 64) self.decode4 = Decoderv2(64, 256, 64) @@ -166,9 +196,11 @@ def __init__(self, n_classes=1): self.decode2 = Decoderv2(64, 64, 64) self.decode1 = Decoder(64, 32, 64) - self.logit = nn.Sequential(nn.Conv2d(320, 64, kernel_size=3, padding=1), - nn.ELU(True), - nn.Conv2d(64, n_classes, kernel_size=1, bias=False)) + self.logit = nn.Sequential( + nn.Conv2d(320, 64, kernel_size=3, padding=1), + nn.ELU(True), + nn.Conv2d(64, n_classes, kernel_size=1, bias=False), + ) def forward(self, x): # x: (batch_size, 3, 256, 256) @@ -187,11 +219,16 @@ def forward(self, x): d2 = self.decode2(d3, e2) # 64, 128, 128 d1 = self.decode1(d2) # 64, 256, 256 - f = torch.cat((d1, - F.upsample(d2, scale_factor=2, mode='bilinear', align_corners=True), - F.upsample(d3, scale_factor=4, mode='bilinear', align_corners=True), - F.upsample(d4, scale_factor=8, mode='bilinear', align_corners=True), - F.upsample(d5, scale_factor=16, mode='bilinear', align_corners=True)), 1) # 320, 256, 256 + f = torch.cat( + ( + d1, + F.upsample(d2, scale_factor=2, mode="bilinear", align_corners=True), + F.upsample(d3, scale_factor=4, mode="bilinear", align_corners=True), + F.upsample(d4, scale_factor=8, mode="bilinear", align_corners=True), + F.upsample(d5, scale_factor=16, mode="bilinear", align_corners=True), + ), + 1, + ) # 320, 256, 256 logit = self.logit(f) # 1, 256, 256 @@ -204,22 +241,14 @@ def __init__(self): super(Res34Unetv3, self).__init__() self.resnet = torchvision.models.resnet34(True) - self.conv1 = nn.Sequential( - self.resnet.conv1, - self.resnet.bn1, - self.resnet.relu) + self.conv1 = nn.Sequential(self.resnet.conv1, self.resnet.bn1, self.resnet.relu) - self.encode2 = nn.Sequential(self.resnet.layer1, - SCse(64)) - self.encode3 = nn.Sequential(self.resnet.layer2, - SCse(128)) - self.encode4 = nn.Sequential(self.resnet.layer3, - SCse(256)) - self.encode5 = nn.Sequential(self.resnet.layer4, - SCse(512)) + self.encode2 = nn.Sequential(self.resnet.layer1, SCse(64)) + self.encode3 = nn.Sequential(self.resnet.layer2, SCse(128)) + self.encode4 = nn.Sequential(self.resnet.layer3, SCse(256)) + self.encode5 = nn.Sequential(self.resnet.layer4, SCse(512)) - self.center = nn.Sequential(FPAv2(512, 256), - nn.MaxPool2d(2, 2)) + self.center = nn.Sequential(FPAv2(512, 256), nn.MaxPool2d(2, 2)) self.decode5 = Decoderv2(256, 512, 64) self.decode4 = Decoderv2(64, 256, 64) @@ -233,13 +262,13 @@ def __init__(self): self.fuse_pixel = conv3x3(320, 64) self.logit_pixel = nn.Conv2d(64, 1, kernel_size=1, bias=False) - self.fuse_image = nn.Sequential(nn.Linear(512, 64), - nn.ELU(True)) - self.logit_image = nn.Sequential(nn.Linear(64, 1), - nn.Sigmoid()) - self.logit = nn.Sequential(nn.Conv2d(128, 64, kernel_size=3, padding=1, bias=False), - nn.ELU(True), - nn.Conv2d(64, 1, kernel_size=1, bias=False)) + self.fuse_image = nn.Sequential(nn.Linear(512, 64), nn.ELU(True)) + self.logit_image = nn.Sequential(nn.Linear(64, 1), nn.Sigmoid()) + self.logit = nn.Sequential( + nn.Conv2d(128, 64, kernel_size=3, padding=1, bias=False), + nn.ELU(True), + nn.Conv2d(64, 1, kernel_size=1, bias=False), + ) def forward(self, x): # x: (batch_size, 3, 256, 256) @@ -262,11 +291,16 @@ def forward(self, x): d2 = self.decode2(d3, e2) # 64, 128, 128 d1 = self.decode1(d2) # 64, 256, 256 - f = torch.cat((d1, - F.upsample(d2, scale_factor=2, mode='bilinear', align_corners=True), - F.upsample(d3, scale_factor=4, mode='bilinear', align_corners=True), - F.upsample(d4, scale_factor=8, mode='bilinear', align_corners=True), - F.upsample(d5, scale_factor=16, mode='bilinear', align_corners=True)), 1) # 320, 256, 256 + f = torch.cat( + ( + d1, + F.upsample(d2, scale_factor=2, mode="bilinear", align_corners=True), + F.upsample(d3, scale_factor=4, mode="bilinear", align_corners=True), + F.upsample(d4, scale_factor=8, mode="bilinear", align_corners=True), + F.upsample(d5, scale_factor=16, mode="bilinear", align_corners=True), + ), + 1, + ) # 320, 256, 256 f = self.dropout2d(f) # segmentation process @@ -278,9 +312,18 @@ def forward(self, x): logit_image = self.logit_image(fuse_image) # 1 # combine segmentation and classification - fuse = torch.cat([fuse_pixel, - F.upsample(fuse_image.view(batch_size, -1, 1, 1), scale_factor=256, mode='bilinear', - align_corners=True)], 1) # 128, 256, 256 + fuse = torch.cat( + [ + fuse_pixel, + F.upsample( + fuse_image.view(batch_size, -1, 1, 1), + scale_factor=256, + mode="bilinear", + align_corners=True, + ), + ], + 1, + ) # 128, 256, 256 logit = self.logit(fuse) # 1, 256, 256 return logit, logit_pixel, logit_image.view(-1) @@ -295,28 +338,26 @@ def __init__(self): self.conv1 = nn.Sequential( nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False), self.resnet.bn1, - self.resnet.relu) + self.resnet.relu, + ) - self.encode2 = nn.Sequential(self.resnet.layer1, - SCse(64)) - self.encode3 = nn.Sequential(self.resnet.layer2, - SCse(128)) - self.encode4 = nn.Sequential(self.resnet.layer3, - SCse(256)) - self.encode5 = nn.Sequential(self.resnet.layer4, - SCse(512)) + self.encode2 = nn.Sequential(self.resnet.layer1, SCse(64)) + self.encode3 = nn.Sequential(self.resnet.layer2, SCse(128)) + self.encode4 = nn.Sequential(self.resnet.layer3, SCse(256)) + self.encode5 = nn.Sequential(self.resnet.layer4, SCse(512)) - self.center = nn.Sequential(FPAv2(512, 256), - nn.MaxPool2d(2, 2)) + self.center = nn.Sequential(FPAv2(512, 256), nn.MaxPool2d(2, 2)) self.decode5 = Decoderv2(256, 512, 64) self.decode4 = Decoderv2(64, 256, 64) self.decode3 = Decoderv2(64, 128, 64) self.decode2 = Decoderv2(64, 64, 64) - self.logit = nn.Sequential(nn.Conv2d(256, 32, kernel_size=3, padding=1), - nn.ELU(True), - nn.Conv2d(32, 1, kernel_size=1, bias=False)) + self.logit = nn.Sequential( + nn.Conv2d(256, 32, kernel_size=3, padding=1), + nn.ELU(True), + nn.Conv2d(32, 1, kernel_size=1, bias=False), + ) def forward(self, x): # x: batch_size, 3, 128, 128 @@ -333,10 +374,15 @@ def forward(self, x): d3 = self.decode3(d4, e3) # 64, 64, 64 d2 = self.decode2(d3, e2) # 64, 128, 128 - f = torch.cat((d2, - F.upsample(d3, scale_factor=2, mode='bilinear', align_corners=True), - F.upsample(d4, scale_factor=4, mode='bilinear', align_corners=True), - F.upsample(d5, scale_factor=8, mode='bilinear', align_corners=True)), 1) # 256, 128, 128 + f = torch.cat( + ( + d2, + F.upsample(d3, scale_factor=2, mode="bilinear", align_corners=True), + F.upsample(d4, scale_factor=4, mode="bilinear", align_corners=True), + F.upsample(d5, scale_factor=8, mode="bilinear", align_corners=True), + ), + 1, + ) # 256, 128, 128 f = F.dropout2d(f, p=0.4) logit = self.logit(f) # 1, 128, 128 @@ -345,6 +391,8 @@ def forward(self, x): def get_seg_model(cfg, **kwargs): - assert cfg.MODEL.IN_CHANNELS==3, f"SEResnet Unet deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 3 for cfg.MODEL.IN_CHANNELS" + assert ( + cfg.MODEL.IN_CHANNELS == 3 + ), f"SEResnet Unet deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 3 for cfg.MODEL.IN_CHANNELS" model = Res34Unetv4(n_classes=cfg.DATASET.NUM_CLASSES) - return model \ No newline at end of file + return model diff --git a/cv_lib/cv_lib/segmentation/models/section_deconvnet.py b/cv_lib/cv_lib/segmentation/models/section_deconvnet.py index d4edfd45..b8cf73e8 100644 --- a/cv_lib/cv_lib/segmentation/models/section_deconvnet.py +++ b/cv_lib/cv_lib/segmentation/models/section_deconvnet.py @@ -1,259 +1,241 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch.nn as nn -class section_deconvnet(nn.Module): +class section_deconvnet(nn.Module): def __init__(self, n_classes=4, learned_billinear=False): super(section_deconvnet, self).__init__() self.learned_billinear = learned_billinear self.n_classes = n_classes self.unpool = nn.MaxUnpool2d(2, stride=2) self.conv_block1 = nn.Sequential( - # conv1_1 nn.Conv2d(1, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv1_2 nn.Conv2d(64, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool1 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_1 # 48*48 self.conv_block2 = nn.Sequential( - # conv2_1 nn.Conv2d(64, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv2_2 nn.Conv2d(128, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool2 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_2 # 24*24 self.conv_block3 = nn.Sequential( - # conv3_1 nn.Conv2d(128, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_2 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_3 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool3 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_3 # 12*12 self.conv_block4 = nn.Sequential( - # conv4_1 nn.Conv2d(256, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool4 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_4 # 6*6 self.conv_block5 = nn.Sequential( - # conv5_1 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool5 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_5 # 3*3 self.conv_block6 = nn.Sequential( - # fc6 nn.Conv2d(512, 4096, 3), # set the filter size and nor padding to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 1*1 self.conv_block7 = nn.Sequential( - # fc7 nn.Conv2d(4096, 4096, 1), # set the filter size to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.deconv_block8 = nn.Sequential( - # fc6-deconv nn.ConvTranspose2d(4096, 512, 3, stride=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 3*3 self.unpool_block9 = nn.Sequential( - # unpool5 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # usage unpool(output, indices) # 6*6 self.deconv_block10 = nn.Sequential( - # deconv5_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_3 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block11 = nn.Sequential( - # unpool4 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 12*12 self.deconv_block12 = nn.Sequential( - # deconv4_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_3 nn.ConvTranspose2d(512, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block13 = nn.Sequential( - # unpool3 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 24*24 self.deconv_block14 = nn.Sequential( - # deconv3_1 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_2 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_3 nn.ConvTranspose2d(256, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block15 = nn.Sequential( - # unpool2 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 48*48 self.deconv_block16 = nn.Sequential( - # deconv2_1 nn.ConvTranspose2d(128, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv2_2 nn.ConvTranspose2d(128, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block17 = nn.Sequential( - # unpool1 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 96*96 self.deconv_block18 = nn.Sequential( - # deconv1_1 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv1_2 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.seg_score19 = nn.Sequential( - # seg-score - nn.Conv2d(64, self.n_classes, 1), ) + nn.Conv2d(64, self.n_classes, 1), + ) if self.learned_billinear: raise NotImplementedError @@ -272,40 +254,46 @@ def forward(self, x): conv6 = self.conv_block6(conv5) conv7 = self.conv_block7(conv6) - conv8 = self.deconv_block8(conv7) - conv9 = self.unpool(conv8,indices5, output_size=size4) - conv10 = self.deconv_block10(conv9) - conv11 = self.unpool(conv10,indices4, output_size=size3) - conv12 = self.deconv_block12(conv11) - conv13 = self.unpool(conv12,indices3, output_size=size2) - conv14 = self.deconv_block14(conv13) - conv15 = self.unpool(conv14,indices2, output_size=size1) - conv16 = self.deconv_block16(conv15) - conv17 = self.unpool(conv16,indices1, output_size=size0) + conv8 = self.deconv_block8(conv7) + conv9 = self.unpool(conv8, indices5, output_size=size4) + conv10 = self.deconv_block10(conv9) + conv11 = self.unpool(conv10, indices4, output_size=size3) + conv12 = self.deconv_block12(conv11) + conv13 = self.unpool(conv12, indices3, output_size=size2) + conv14 = self.deconv_block14(conv13) + conv15 = self.unpool(conv14, indices2, output_size=size1) + conv16 = self.deconv_block16(conv15) + conv17 = self.unpool(conv16, indices1, output_size=size0) conv18 = self.deconv_block18(conv17) out = self.seg_score19(conv18) return out def init_vgg16_params(self, vgg16, copy_fc8=True): - blocks = [self.conv_block1, - self.conv_block2, - self.conv_block3, - self.conv_block4, - self.conv_block5] + blocks = [ + self.conv_block1, + self.conv_block2, + self.conv_block3, + self.conv_block4, + self.conv_block5, + ] ranges = [[0, 4], [5, 9], [10, 16], [17, 23], [24, 29]] features = list(vgg16.features.children()) - i_layer = 0; + i_layer = 0 # copy convolutional filters from vgg16 for idx, conv_block in enumerate(blocks): - for l1, l2 in zip(features[ranges[idx][0]:ranges[idx][1]], conv_block): + for l1, l2 in zip(features[ranges[idx][0] : ranges[idx][1]], conv_block): if isinstance(l1, nn.Conv2d) and isinstance(l2, nn.Conv2d): if i_layer == 0: - l2.weight.data = ((l1.weight.data[:, 0, :, :] + l1.weight.data[:, 1, :, :] + l1.weight.data[:, - 2, :, - :]) / 3.0).view( - l2.weight.size()) + l2.weight.data = ( + ( + l1.weight.data[:, 0, :, :] + + l1.weight.data[:, 1, :, :] + + l1.weight.data[:, 2, :, :] + ) + / 3.0 + ).view(l2.weight.size()) l2.bias.data = l1.bias.data i_layer = i_layer + 1 else: @@ -317,6 +305,8 @@ def init_vgg16_params(self, vgg16, copy_fc8=True): def get_seg_model(cfg, **kwargs): - assert cfg.MODEL.IN_CHANNELS==1, f"Section deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" + assert ( + cfg.MODEL.IN_CHANNELS == 1 + ), f"Section deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" model = section_deconvnet(n_classes=cfg.DATASET.NUM_CLASSES) - return model \ No newline at end of file + return model diff --git a/cv_lib/cv_lib/segmentation/models/section_deconvnet_skip.py b/cv_lib/cv_lib/segmentation/models/section_deconvnet_skip.py index 602d1f4a..cfcfbcd1 100644 --- a/cv_lib/cv_lib/segmentation/models/section_deconvnet_skip.py +++ b/cv_lib/cv_lib/segmentation/models/section_deconvnet_skip.py @@ -1,259 +1,241 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch.nn as nn -class section_deconvnet_skip(nn.Module): +class section_deconvnet_skip(nn.Module): def __init__(self, n_classes=4, learned_billinear=False): super(section_deconvnet_skip, self).__init__() self.learned_billinear = learned_billinear self.n_classes = n_classes self.unpool = nn.MaxUnpool2d(2, stride=2) self.conv_block1 = nn.Sequential( - # conv1_1 nn.Conv2d(1, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv1_2 nn.Conv2d(64, 64, 3, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool1 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_1 # 48*48 self.conv_block2 = nn.Sequential( - # conv2_1 nn.Conv2d(64, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv2_2 nn.Conv2d(128, 128, 3, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool2 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_2 # 24*24 self.conv_block3 = nn.Sequential( - # conv3_1 nn.Conv2d(128, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_2 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv3_3 nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool3 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_3 # 12*12 self.conv_block4 = nn.Sequential( - # conv4_1 nn.Conv2d(256, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv4_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool4 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_4 # 6*6 self.conv_block5 = nn.Sequential( - # conv5_1 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_2 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # conv5_3 nn.Conv2d(512, 512, 3, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # pool5 - nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), ) + nn.MaxPool2d(2, stride=2, return_indices=True, ceil_mode=True), + ) # it returns outputs and pool_indices_5 # 3*3 self.conv_block6 = nn.Sequential( - # fc6 nn.Conv2d(512, 4096, 3), # set the filter size and nor padding to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 1*1 self.conv_block7 = nn.Sequential( - # fc7 nn.Conv2d(4096, 4096, 1), # set the filter size to make output into 1*1 nn.BatchNorm2d(4096, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.deconv_block8 = nn.Sequential( - # fc6-deconv nn.ConvTranspose2d(4096, 512, 3, stride=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) # 3*3 self.unpool_block9 = nn.Sequential( - # unpool5 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # usage unpool(output, indices) # 6*6 self.deconv_block10 = nn.Sequential( - # deconv5_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv5_3 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block11 = nn.Sequential( - # unpool4 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 12*12 self.deconv_block12 = nn.Sequential( - # deconv4_1 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_2 nn.ConvTranspose2d(512, 512, 3, stride=1, padding=1), nn.BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv4_3 nn.ConvTranspose2d(512, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block13 = nn.Sequential( - # unpool3 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 24*24 self.deconv_block14 = nn.Sequential( - # deconv3_1 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_2 nn.ConvTranspose2d(256, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv3_3 nn.ConvTranspose2d(256, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block15 = nn.Sequential( - # unpool2 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 48*48 self.deconv_block16 = nn.Sequential( - # deconv2_1 nn.ConvTranspose2d(128, 128, 3, stride=1, padding=1), nn.BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv2_2 nn.ConvTranspose2d(128, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.unpool_block17 = nn.Sequential( - # unpool1 - nn.MaxUnpool2d(2, stride=2), ) + nn.MaxUnpool2d(2, stride=2), + ) # 96*96 self.deconv_block18 = nn.Sequential( - # deconv1_1 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), nn.ReLU(inplace=True), - # deconv1_2 nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True), - nn.ReLU(inplace=True), ) + nn.ReLU(inplace=True), + ) self.seg_score19 = nn.Sequential( - # seg-score - nn.Conv2d(64, self.n_classes, 1), ) + nn.Conv2d(64, self.n_classes, 1), + ) if self.learned_billinear: raise NotImplementedError @@ -273,39 +255,45 @@ def forward(self, x): conv6 = self.conv_block6(conv5) conv7 = self.conv_block7(conv6) conv8 = self.deconv_block8(conv7) + conv5 - conv9 = self.unpool(conv8,indices5, output_size=size4) + conv9 = self.unpool(conv8, indices5, output_size=size4) conv10 = self.deconv_block10(conv9) + conv4 - conv11 = self.unpool(conv10,indices4, output_size=size3) + conv11 = self.unpool(conv10, indices4, output_size=size3) conv12 = self.deconv_block12(conv11) + conv3 - conv13 = self.unpool(conv12,indices3, output_size=size2) + conv13 = self.unpool(conv12, indices3, output_size=size2) conv14 = self.deconv_block14(conv13) + conv2 - conv15 = self.unpool(conv14,indices2, output_size=size1) + conv15 = self.unpool(conv14, indices2, output_size=size1) conv16 = self.deconv_block16(conv15) + conv1 - conv17 = self.unpool(conv16,indices1, output_size=size0) + conv17 = self.unpool(conv16, indices1, output_size=size0) conv18 = self.deconv_block18(conv17) out = self.seg_score19(conv18) - + return out def init_vgg16_params(self, vgg16, copy_fc8=True): - blocks = [self.conv_block1, - self.conv_block2, - self.conv_block3, - self.conv_block4, - self.conv_block5] + blocks = [ + self.conv_block1, + self.conv_block2, + self.conv_block3, + self.conv_block4, + self.conv_block5, + ] ranges = [[0, 4], [5, 9], [10, 16], [17, 23], [24, 29]] features = list(vgg16.features.children()) - i_layer = 0; + i_layer = 0 # copy convolutional filters from vgg16 for idx, conv_block in enumerate(blocks): - for l1, l2 in zip(features[ranges[idx][0]:ranges[idx][1]], conv_block): + for l1, l2 in zip(features[ranges[idx][0] : ranges[idx][1]], conv_block): if isinstance(l1, nn.Conv2d) and isinstance(l2, nn.Conv2d): if i_layer == 0: - l2.weight.data = ((l1.weight.data[:, 0, :, :] + l1.weight.data[:, 1, :, :] + l1.weight.data[:, - 2, :, - :]) / 3.0).view( - l2.weight.size()) + l2.weight.data = ( + ( + l1.weight.data[:, 0, :, :] + + l1.weight.data[:, 1, :, :] + + l1.weight.data[:, 2, :, :] + ) + / 3.0 + ).view(l2.weight.size()) l2.bias.data = l1.bias.data i_layer = i_layer + 1 else: @@ -315,7 +303,10 @@ def init_vgg16_params(self, vgg16, copy_fc8=True): l2.bias.data = l1.bias.data i_layer = i_layer + 1 + def get_seg_model(cfg, **kwargs): - assert cfg.MODEL.IN_CHANNELS==1, f"Section deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" + assert ( + cfg.MODEL.IN_CHANNELS == 1 + ), f"Section deconvnet is not implemented to accept {cfg.MODEL.IN_CHANNELS} channels. Please only pass 1 for cfg.MODEL.IN_CHANNELS" model = section_deconvnet_skip(n_classes=cfg.DATASET.NUM_CLASSES) - return model \ No newline at end of file + return model diff --git a/cv_lib/cv_lib/segmentation/models/unet.py b/cv_lib/cv_lib/segmentation/models/unet.py index 3c37d983..95143856 100644 --- a/cv_lib/cv_lib/segmentation/models/unet.py +++ b/cv_lib/cv_lib/segmentation/models/unet.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + """ Taken from https://github.com/milesial/Pytorch-UNet """ @@ -9,10 +12,9 @@ from torch.nn import init - - class double_conv(nn.Module): - '''(conv => BN => ReLU) * 2''' + """(conv => BN => ReLU) * 2""" + def __init__(self, in_ch, out_ch): super(double_conv, self).__init__() self.conv = nn.Sequential( @@ -21,7 +23,7 @@ def __init__(self, in_ch, out_ch): nn.ReLU(inplace=True), nn.Conv2d(out_ch, out_ch, 3, padding=1), nn.BatchNorm2d(out_ch), - nn.ReLU(inplace=True) + nn.ReLU(inplace=True), ) def forward(self, x): @@ -42,10 +44,7 @@ def forward(self, x): class down(nn.Module): def __init__(self, in_ch, out_ch): super(down, self).__init__() - self.mpconv = nn.Sequential( - nn.MaxPool2d(2), - double_conv(in_ch, out_ch) - ) + self.mpconv = nn.Sequential(nn.MaxPool2d(2), double_conv(in_ch, out_ch)) def forward(self, x): x = self.mpconv(x) @@ -57,22 +56,21 @@ def __init__(self, in_ch, out_ch, bilinear=True): super(up, self).__init__() if bilinear: - self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True) + self.up = nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True) else: - self.up = nn.ConvTranspose2d(in_ch//2, in_ch//2, 2, stride=2) + self.up = nn.ConvTranspose2d(in_ch // 2, in_ch // 2, 2, stride=2) self.conv = double_conv(in_ch, out_ch) def forward(self, x1, x2): x1 = self.up(x1) - + # input is CHW diffY = x2.size()[2] - x1.size()[2] diffX = x2.size()[3] - x1.size()[3] - x1 = F.pad(x1, (diffX // 2, diffX - diffX//2, - diffY // 2, diffY - diffY//2)) - + x1 = F.pad(x1, (diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2)) + x = torch.cat([x2, x1], dim=1) x = self.conv(x) return x diff --git a/cv_lib/cv_lib/segmentation/models/utils.py b/cv_lib/cv_lib/segmentation/models/utils.py index 359544b9..591ddd60 100644 --- a/cv_lib/cv_lib/segmentation/models/utils.py +++ b/cv_lib/cv_lib/segmentation/models/utils.py @@ -1,23 +1,40 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch import torch.nn as nn import torch.nn.functional as F class conv2DBatchNorm(nn.Module): - def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True, dilation=1): + def __init__( + self, in_channels, n_filters, k_size, stride, padding, bias=True, dilation=1 + ): super(conv2DBatchNorm, self).__init__() if dilation > 1: - conv_mod = nn.Conv2d(int(in_channels), int(n_filters), kernel_size=k_size, - padding=padding, stride=stride, bias=bias, dilation=dilation) + conv_mod = nn.Conv2d( + int(in_channels), + int(n_filters), + kernel_size=k_size, + padding=padding, + stride=stride, + bias=bias, + dilation=dilation, + ) else: - conv_mod = nn.Conv2d(int(in_channels), int(n_filters), kernel_size=k_size, - padding=padding, stride=stride, bias=bias, dilation=1) - - - self.cb_unit = nn.Sequential(conv_mod, - nn.BatchNorm2d(int(n_filters)),) + conv_mod = nn.Conv2d( + int(in_channels), + int(n_filters), + kernel_size=k_size, + padding=padding, + stride=stride, + bias=bias, + dilation=1, + ) + + self.cb_unit = nn.Sequential(conv_mod, nn.BatchNorm2d(int(n_filters)),) def forward(self, inputs): outputs = self.cb_unit(inputs) @@ -25,12 +42,20 @@ def forward(self, inputs): class deconv2DBatchNorm(nn.Module): - def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True): + def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True): super(deconv2DBatchNorm, self).__init__() - self.dcb_unit = nn.Sequential(nn.ConvTranspose2d(int(in_channels), int(n_filters), kernel_size=k_size, - padding=padding, stride=stride, bias=bias), - nn.BatchNorm2d(int(n_filters)),) + self.dcb_unit = nn.Sequential( + nn.ConvTranspose2d( + int(in_channels), + int(n_filters), + kernel_size=k_size, + padding=padding, + stride=stride, + bias=bias, + ), + nn.BatchNorm2d(int(n_filters)), + ) def forward(self, inputs): outputs = self.dcb_unit(inputs) @@ -38,20 +63,36 @@ def forward(self, inputs): class conv2DBatchNormRelu(nn.Module): - def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True, dilation=1): + def __init__( + self, in_channels, n_filters, k_size, stride, padding, bias=True, dilation=1 + ): super(conv2DBatchNormRelu, self).__init__() if dilation > 1: - conv_mod = nn.Conv2d(int(in_channels), int(n_filters), kernel_size=k_size, - padding=padding, stride=stride, bias=bias, dilation=dilation) + conv_mod = nn.Conv2d( + int(in_channels), + int(n_filters), + kernel_size=k_size, + padding=padding, + stride=stride, + bias=bias, + dilation=dilation, + ) else: - conv_mod = nn.Conv2d(int(in_channels), int(n_filters), kernel_size=k_size, - padding=padding, stride=stride, bias=bias, dilation=1) - - self.cbr_unit = nn.Sequential(conv_mod, - nn.BatchNorm2d(int(n_filters)), - nn.ReLU(inplace=True),) + conv_mod = nn.Conv2d( + int(in_channels), + int(n_filters), + kernel_size=k_size, + padding=padding, + stride=stride, + bias=bias, + dilation=1, + ) + + self.cbr_unit = nn.Sequential( + conv_mod, nn.BatchNorm2d(int(n_filters)), nn.ReLU(inplace=True), + ) def forward(self, inputs): outputs = self.cbr_unit(inputs) @@ -62,10 +103,18 @@ class deconv2DBatchNormRelu(nn.Module): def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True): super(deconv2DBatchNormRelu, self).__init__() - self.dcbr_unit = nn.Sequential(nn.ConvTranspose2d(int(in_channels), int(n_filters), kernel_size=k_size, - padding=padding, stride=stride, bias=bias), - nn.BatchNorm2d(int(n_filters)), - nn.ReLU(inplace=True),) + self.dcbr_unit = nn.Sequential( + nn.ConvTranspose2d( + int(in_channels), + int(n_filters), + kernel_size=k_size, + padding=padding, + stride=stride, + bias=bias, + ), + nn.BatchNorm2d(int(n_filters)), + nn.ReLU(inplace=True), + ) def forward(self, inputs): outputs = self.dcbr_unit(inputs) diff --git a/cv_lib/cv_lib/segmentation/penobscot/engine.py b/cv_lib/cv_lib/segmentation/penobscot/engine.py index 2d733a45..634fd6ce 100644 --- a/cv_lib/cv_lib/segmentation/penobscot/engine.py +++ b/cv_lib/cv_lib/segmentation/penobscot/engine.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import torch from ignite.engine.engine import Engine diff --git a/cv_lib/cv_lib/segmentation/utils.py b/cv_lib/cv_lib/segmentation/utils.py index 2c31143a..2410fa9a 100644 --- a/cv_lib/cv_lib/segmentation/utils.py +++ b/cv_lib/cv_lib/segmentation/utils.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import numpy as np from deepseismic_interpretation.dutchf3.data import decode_segmap from os import path @@ -9,14 +12,20 @@ def _chw_to_hwc(image_array_numpy): return np.moveaxis(image_array_numpy, 0, -1) -def save_images( - pred_dict, output_dir, num_classes, colours, extra_identifier="" -): +def save_images(pred_dict, output_dir, num_classes, colours, extra_identifier=""): for id in pred_dict: - save_image(pred_dict[id].unsqueeze(0).cpu().numpy(), output_dir, num_classes, colours, extra_identifier=extra_identifier) + save_image( + pred_dict[id].unsqueeze(0).cpu().numpy(), + output_dir, + num_classes, + colours, + extra_identifier=extra_identifier, + ) -def save_image(image_numpy_array, output_dir, num_classes, colours, extra_identifier=""): +def save_image( + image_numpy_array, output_dir, num_classes, colours, extra_identifier="" +): """Save segmentation map as image Args: @@ -27,14 +36,10 @@ def save_image(image_numpy_array, output_dir, num_classes, colours, extra_identi extra_identifier (str, optional): [description]. Defaults to "". """ im_array = decode_segmap( - image_numpy_array, - n_classes=num_classes, - label_colours=colours, + image_numpy_array, n_classes=num_classes, label_colours=colours, ) im = pipe( - (im_array * 255).astype(np.uint8).squeeze(), - _chw_to_hwc, - Image.fromarray, + (im_array * 255).astype(np.uint8).squeeze(), _chw_to_hwc, Image.fromarray, ) filename = path.join(output_dir, f"{id}_{extra_identifier}.png") - im.save(filename) \ No newline at end of file + im.save(filename) diff --git a/cv_lib/setup.py b/cv_lib/setup.py index 9f170040..23353ae0 100644 --- a/cv_lib/setup.py +++ b/cv_lib/setup.py @@ -1,4 +1,8 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# /* spell-checker: disable */ import os + try: from setuptools import setup, find_packages except ImportError: @@ -6,16 +10,16 @@ # Package meta-data. -NAME = 'cv_lib' -DESCRIPTION = 'A library for computer vision' -URL = '' -EMAIL = 'msalvaris@users.noreply.github.com' -AUTHOR = 'AUTHORS.md' -LICENSE = '' +NAME = "cv_lib" +DESCRIPTION = "A library for computer vision" +URL = "" +EMAIL = "msalvaris@users.noreply.github.com" +AUTHOR = "AUTHORS.md" +LICENSE = "" LONG_DESCRIPTION = DESCRIPTION -with open('requirements.txt') as f: +with open("requirements.txt") as f: requirements = f.read().splitlines() @@ -23,13 +27,13 @@ # Load the package's __version__.py module as a dictionary. about = {} -with open(os.path.join(here, NAME, '__version__.py')) as f: +with open(os.path.join(here, NAME, "__version__.py")) as f: exec(f.read(), about) setup( name=NAME, - version=about['__version__'], + version=about["__version__"], url=URL, license=LICENSE, author=AUTHOR, @@ -41,10 +45,10 @@ include_package_data=True, install_requires=requirements, classifiers=[ - 'Development Status :: 1 - Alpha', - 'Intended Audience :: Data Scientists & Developers', - 'Operating System :: POSIX', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 3.6', - ] + "Development Status :: 1 - Alpha", + "Intended Audience :: Data Scientists & Developers", + "Operating System :: POSIX", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.6", + ], ) diff --git a/deepseismic/__init__.py b/deepseismic/__init__.py index 8dc07e06..0f06c3a5 100644 --- a/deepseismic/__init__.py +++ b/deepseismic/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from . import cli, forward, velocity __all__ = ["cli", "forward", "velocity"] diff --git a/deepseismic/cli/__init__.py b/deepseismic/cli/__init__.py index 1b0db11d..1497eac6 100644 --- a/deepseismic/cli/__init__.py +++ b/deepseismic/cli/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from functools import partial import click diff --git a/deepseismic/cli/forward.py b/deepseismic/cli/forward.py index 0ef69d39..77b94ef7 100644 --- a/deepseismic/cli/forward.py +++ b/deepseismic/cli/forward.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from functools import partial import click @@ -13,16 +16,10 @@ @click.argument("input", type=click.Path()) @click.argument("output", type=click.Path()) @click.option( - "-d", - "--duration", - default=1000.0, - type=float, - help="Simulation duration (in ms)", + "-d", "--duration", default=1000.0, type=float, help="Simulation duration (in ms)", ) @click.option("-dt", default=2.0, type=float, help="Time increment (in ms)") -@click.option( - "--n-pml", default=10, type=int, help="PML size (in grid points)" -) +@click.option("--n-pml", default=10, type=int, help="PML size (in grid points)") @click.option( "--n-receivers", default=11, @@ -30,9 +27,7 @@ help="Number of receivers per horizontal dimension", ) @click.option("--space-order", default=2, type=int, help="Space order") -@click.option( - "--spacing", default=10.0, type=float, help="Spacing between grid points" -) +@click.option("--spacing", default=10.0, type=float, help="Spacing between grid points") @click.pass_context def fwd( ctx, @@ -58,9 +53,7 @@ def fwd( @fwd.command() -@click.option( - "-f0", default=0.01, type=float, help="Source peak frequency (in kHz)" -) +@click.option("-f0", default=0.01, type=float, help="Source peak frequency (in kHz)") @click.pass_context def ricker(ctx, f0: float): """Ricker source""" @@ -84,11 +77,7 @@ def ricker(ctx, f0: float): start=0.0, stop=ctx.obj["duration"], step=ctx.obj["dt"] ) source = RickerSource( - name="source", - grid=model.grid, - f0=f0, - npoint=1, - time_range=time_range, + name="source", grid=model.grid, f0=f0, npoint=1, time_range=time_range, ) source.coordinates.data[0, :] = np.array(model.domain_size) * 0.5 source.coordinates.data[0, -1] = 0.0 @@ -107,9 +96,7 @@ def ricker(ctx, f0: float): ) ) for d in range(len(receivers_coords)): - receivers.coordinates.data[:, d] = receivers_coords[ - d - ].flatten() + receivers.coordinates.data[:, d] = receivers_coords[d].flatten() receivers.coordinates.data[:, -1] = 0.0 output_group = output_file.create_group(input_group_name) for input_dataset_name, vp in input_group.items(): @@ -117,7 +104,5 @@ def ricker(ctx, f0: float): seismograms = model.solve( source=source, receivers=receivers, time_range=time_range ) - output_group.create_dataset( - input_dataset_name, data=seismograms - ) + output_group.create_dataset(input_dataset_name, data=seismograms) bar.update(1) diff --git a/deepseismic/cli/velocity.py b/deepseismic/cli/velocity.py index 1c87c340..c340c7d9 100644 --- a/deepseismic/cli/velocity.py +++ b/deepseismic/cli/velocity.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from functools import partial from itertools import islice from typing import Tuple @@ -13,9 +16,7 @@ @click.group() @click.argument("output", type=click.Path()) @click.option( - "--append/--no-append", - default=False, - help="Whether to append to output file", + "--append/--no-append", default=False, help="Whether to append to output file", ) @click.option("-n", default=1, type=int, help="Number of simulations") @click.option( @@ -30,20 +31,11 @@ type=int, help="Number of grid points along the second dimension", ) -@click.option( - "-nz", type=int, help="Number of grid points along the third dimension" -) +@click.option("-nz", type=int, help="Number of grid points along the third dimension") @click.option("-s", "--seed", default=42, type=int, help="Random seed") @click.pass_context def vp( - ctx, - append: bool, - n: int, - nx: int, - ny: int, - nz: int, - output: str, - seed: int, + ctx, append: bool, n: int, nx: int, ny: int, nz: int, output: str, seed: int, ): """Vp simulation""" shape = (nx, ny) diff --git a/deepseismic/forward/__init__.py b/deepseismic/forward/__init__.py index f9a9083f..8aaed73e 100644 --- a/deepseismic/forward/__init__.py +++ b/deepseismic/forward/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from .models import Model, VelocityModel from .sources import Receiver, RickerSource, WaveletSource from .time import TimeAxis diff --git a/deepseismic/forward/models.py b/deepseismic/forward/models.py index f07b7a1c..eaa0e56d 100644 --- a/deepseismic/forward/models.py +++ b/deepseismic/forward/models.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional, Tuple, Union import numpy as np @@ -37,9 +40,7 @@ def __init__( subdomains = tuple(subdomains) + (PhysicalDomain(n_pml),) shape_pml = tuple(x + 2 * n_pml for x in shape) extent_pml = tuple(s * (d - 1) for s, d in zip(spacing, shape_pml)) - origin_pml = tuple( - dtype(o - s * n_pml) for o, s in zip(origin, spacing) - ) + origin_pml = tuple(dtype(o - s * n_pml) for o, s in zip(origin, spacing)) self.grid = Grid( shape=shape_pml, extent=extent_pml, @@ -62,14 +63,10 @@ def __init__( idx = [slice(0, x) for x in pml_data.shape] idx[d] = slice(i, i + 1) pml_data[tuple(idx)] += val / self.grid.spacing[d] - idx[d] = slice( - pml_data.shape[d] - i, pml_data.shape[d] - i + 1 - ) + idx[d] = slice(pml_data.shape[d] - i, pml_data.shape[d] - i + 1) pml_data[tuple(idx)] += val / self.grid.spacing[d] pml_data = np.pad( - pml_data, - [(i.left, i.right) for i in self.pml._size_halo], - mode="edge", + pml_data, [(i.left, i.right) for i in self.pml._size_halo], mode="edge", ) self.pml.data_with_halo[:] = pml_data self.shape = shape @@ -110,9 +107,7 @@ def __init__( super().__init__(shape, origin, spacing, n_pml, dtype, subdomains) if isinstance(vp, np.ndarray): assert space_order is not None - self.m = Function( - name="m", grid=self.grid, space_order=int(space_order) - ) + self.m = Function(name="m", grid=self.grid, space_order=int(space_order)) else: self.m = Constant(name="m", value=1.0 / float(vp) ** 2.0) self.vp = vp @@ -126,8 +121,7 @@ def vp(self, vp: Union[float, np.ndarray]) -> None: self._vp = vp if isinstance(vp, np.ndarray): pad_widths = [ - (self.n_pml + i.left, self.n_pml + i.right) - for i in self.m._size_halo + (self.n_pml + i.left, self.n_pml + i.right) for i in self.m._size_halo ] self.m.data_with_halo[:] = np.pad( 1.0 / self.vp ** 2.0, pad_widths, mode="edge" @@ -150,9 +144,7 @@ def solve( H = u.laplace if kernel is Kernel.OT4: H += self.time_spacing ** 2 / 12 * u.laplace2(1 / self.m) - eq = Eq( - u.forward, solve(self.m * u.dt2 - H + self.pml * u.dt, u.forward) - ) + eq = Eq(u.forward, solve(self.m * u.dt2 - H + self.pml * u.dt, u.forward)) src_term = source.inject( field=u.forward, expr=source * self.time_spacing ** 2 / self.m ) diff --git a/deepseismic/forward/sources.py b/deepseismic/forward/sources.py index 5a0470e2..576e3934 100644 --- a/deepseismic/forward/sources.py +++ b/deepseismic/forward/sources.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional import numpy as np @@ -22,9 +25,7 @@ def __new__(cls, *args, **kwargs): time_order = kwargs.pop("time_order", 2) p_dim = kwargs.pop("dimension", Dimension(name="p_%s" % name)) npoint = kwargs.pop("npoint", None) - coordinates = kwargs.pop( - "coordinates", kwargs.pop("coordinates_data", None) - ) + coordinates = kwargs.pop("coordinates", kwargs.pop("coordinates_data", None)) if npoint is None: assert ( coordinates is not None @@ -76,16 +77,12 @@ def resample( if np.isclose(dt0, dt, rtol=rtol): return self n_traces = self.data.shape[1] - new_traces = np.zeros( - (new_time_range.num, n_traces), dtype=self.data.dtype - ) + new_traces = np.zeros((new_time_range.num, n_traces), dtype=self.data.dtype) for j in range(n_traces): tck = interpolate.splrep( self._time_range.time_values, self.data[:, j], k=order ) - new_traces[:, j] = interpolate.splev( - new_time_range.time_values, tck - ) + new_traces[:, j] = interpolate.splev(new_time_range.time_values, tck) return PointSource( name=self.name, grid=self.grid, @@ -129,4 +126,4 @@ def wavelet(self, f0: float, t: np.ndarray) -> np.ndarray: class RickerSource(WaveletSource): def wavelet(self, f0: float, t: np.ndarray) -> np.ndarray: r = np.pi * f0 * (t - 1.0 / f0) - return (1.0 - 2.0 * r ** 2.0) * np.exp(-r ** 2.0) + return (1.0 - 2.0 * r ** 2.0) * np.exp(-(r ** 2.0)) diff --git a/deepseismic/forward/subdomains.py b/deepseismic/forward/subdomains.py index 2ed6cedb..fcabe59b 100644 --- a/deepseismic/forward/subdomains.py +++ b/deepseismic/forward/subdomains.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Dict, Iterable, Tuple from devito import Dimension, SubDomain diff --git a/deepseismic/forward/time.py b/deepseismic/forward/time.py index d3dfc00d..7ce51d5d 100644 --- a/deepseismic/forward/time.py +++ b/deepseismic/forward/time.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional import numpy as np diff --git a/deepseismic/forward/types.py b/deepseismic/forward/types.py index 772f67b7..3b4fe2ac 100644 --- a/deepseismic/forward/types.py +++ b/deepseismic/forward/types.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from enum import Enum, auto diff --git a/deepseismic/velocity/__init__.py b/deepseismic/velocity/__init__.py index 98225180..34ef3009 100644 --- a/deepseismic/velocity/__init__.py +++ b/deepseismic/velocity/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from .generator import Generator from .roeth_tarantola import RoethTarantolaGenerator diff --git a/deepseismic/velocity/generator.py b/deepseismic/velocity/generator.py index ddc2eb4a..5b28721c 100644 --- a/deepseismic/velocity/generator.py +++ b/deepseismic/velocity/generator.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional, Tuple import numpy as np diff --git a/deepseismic/velocity/roeth_tarantola.py b/deepseismic/velocity/roeth_tarantola.py index 6c3c0cc4..89f860ae 100644 --- a/deepseismic/velocity/roeth_tarantola.py +++ b/deepseismic/velocity/roeth_tarantola.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional, Tuple import numpy as np @@ -25,9 +28,9 @@ def __init__( def generate(self) -> np.ndarray: vp = np.zeros(self.shape, dtype=self.dtype) dim = self.depth_dim - layer_idx = np.round( - np.linspace(0, self.shape[dim], self.n_layers + 1) - ).astype(np.int) + layer_idx = np.round(np.linspace(0, self.shape[dim], self.n_layers + 1)).astype( + np.int + ) vp_idx = [slice(0, x) for x in vp.shape] layer_vp = None for i in range(self.n_layers): diff --git a/examples/interpretation/notebooks/utilities.py b/examples/interpretation/notebooks/utilities.py index 669de6c9..135273f3 100644 --- a/examples/interpretation/notebooks/utilities.py +++ b/examples/interpretation/notebooks/utilities.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import itertools import numpy as np import torch diff --git a/experiments/interpretation/dutchf3_patch/distributed/train.py b/experiments/interpretation/dutchf3_patch/distributed/train.py index 6c58c408..ae0c17f7 100644 --- a/experiments/interpretation/dutchf3_patch/distributed/train.py +++ b/experiments/interpretation/dutchf3_patch/distributed/train.py @@ -1,9 +1,11 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# /* spell-checker: disable */ """Train models on Dutch F3 salt dataset Trains models using PyTorch DistributedDataParallel Uses a warmup schedule that then goes into a cyclic learning rate """ -# /* spell-checker: disable */ import logging import logging.config @@ -102,9 +104,7 @@ def run(*options, cfg=None, local_rank=0): # FOR DISTRIBUTED: Initialize the backend. torch.distributed.launch will provide # environment variables, and requires that you use init_method=`env://`. - torch.distributed.init_process_group( - backend="nccl", init_method="env://" - ) + torch.distributed.init_process_group(backend="nccl", init_method="env://") scheduler_step = config.TRAIN.END_EPOCH // config.TRAIN.SNAPSHOTS torch.backends.cudnn.benchmark = config.CUDNN.BENCHMARK @@ -117,9 +117,7 @@ def run(*options, cfg=None, local_rank=0): basic_aug = Compose( [ Normalize( - mean=(config.TRAIN.MEAN,), - std=(config.TRAIN.STD,), - max_pixel_value=1, + mean=(config.TRAIN.MEAN,), std=(config.TRAIN.STD,), max_pixel_value=1, ), Resize( config.TRAIN.AUGMENTATIONS.RESIZE.HEIGHT, @@ -136,12 +134,7 @@ def run(*options, cfg=None, local_rank=0): ] ) if config.TRAIN.AUGMENTATION: - train_aug = Compose( - [ - basic_aug, - HorizontalFlip(p=0.5), - ] - ) + train_aug = Compose([basic_aug, HorizontalFlip(p=0.5),]) val_aug = basic_aug else: train_aug = val_aug = basic_aug @@ -164,7 +157,7 @@ def run(*options, cfg=None, local_rank=0): is_transform=True, stride=config.TRAIN.STRIDE, patch_size=config.TRAIN.PATCH_SIZE, - augmentations=val_aug + augmentations=val_aug, ) logger.info(f"Validation examples {len(val_set)}") n_classes = train_set.n_classes @@ -236,8 +229,7 @@ def run(*options, cfg=None, local_rank=0): ) scheduler = ConcatScheduler( - schedulers=[warmup_scheduler, cosine_scheduler], - durations=[warmup_duration], + schedulers=[warmup_scheduler, cosine_scheduler], durations=[warmup_duration], ) trainer = create_supervised_trainer( @@ -246,21 +238,17 @@ def run(*options, cfg=None, local_rank=0): trainer.add_event_handler(Events.ITERATION_STARTED, scheduler) # Set to update the epoch parameter of our distributed data sampler so that we get different shuffles - trainer.add_event_handler( - Events.EPOCH_STARTED, update_sampler_epoch(train_loader) - ) + trainer.add_event_handler(Events.EPOCH_STARTED, update_sampler_epoch(train_loader)) if silence_other_ranks & local_rank != 0: - logging.getLogger("ignite.engine.engine.Engine").setLevel( - logging.WARNING - ) + logging.getLogger("ignite.engine.engine.Engine").setLevel(logging.WARNING) def _select_pred_and_mask(model_out_dict): return ( model_out_dict["y_pred"].squeeze(), model_out_dict["mask"].squeeze(), ) - + evaluator = create_supervised_evaluator( model, prepare_batch, @@ -288,9 +276,7 @@ def _select_pred_and_mask(model_out_dict): ) # Set the validation run to start on the epoch completion of the training run - trainer.add_event_handler( - Events.EPOCH_COMPLETED, Evaluator(evaluator, val_loader) - ) + trainer.add_event_handler(Events.EPOCH_COMPLETED, Evaluator(evaluator, val_loader)) if local_rank == 0: # Run only on master process @@ -330,7 +316,7 @@ def _select_pred_and_mask(model_out_dict): "nll": "Avg loss :", "pixa": "Pixelwise Accuracy :", "mca": "Mean Class Accuracy :", - "fiou": "Freq Weighted IoU :", + "fiou": "Freq Weighted IoU :", }, ), ) @@ -354,7 +340,7 @@ def _select_max(pred_tensor): def _tensor_to_numpy(pred_tensor): return pred_tensor.squeeze().cpu().numpy() - + transform_func = compose( np_to_tb, decode_segmap(n_classes=n_classes), _tensor_to_numpy ) @@ -387,7 +373,6 @@ def _tensor_to_numpy(pred_tensor): def snapshot_function(): return (trainer.state.iteration % snapshot_duration) == 0 - checkpoint_handler = SnapshotHandler( path.join(output_dir, config.TRAIN.MODEL_DIR), config.MODEL.NAME, @@ -398,7 +383,6 @@ def snapshot_function(): Events.EPOCH_COMPLETED, checkpoint_handler, {"model": model} ) - logger.info("Starting training") trainer.run(train_loader, max_epochs=config.TRAIN.END_EPOCH) diff --git a/imaging/deepseismic_imaging/__init__.py b/imaging/deepseismic_imaging/__init__.py index 34749819..b063f14b 100644 --- a/imaging/deepseismic_imaging/__init__.py +++ b/imaging/deepseismic_imaging/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from deepseismic_imaging import velocity, forward, cli __all__ = ["cli", "forward", "velocity"] diff --git a/imaging/deepseismic_imaging/cli/__init__.py b/imaging/deepseismic_imaging/cli/__init__.py index 1b0db11d..1497eac6 100644 --- a/imaging/deepseismic_imaging/cli/__init__.py +++ b/imaging/deepseismic_imaging/cli/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from functools import partial import click diff --git a/imaging/deepseismic_imaging/cli/forward.py b/imaging/deepseismic_imaging/cli/forward.py index 2f924735..3e0658c5 100644 --- a/imaging/deepseismic_imaging/cli/forward.py +++ b/imaging/deepseismic_imaging/cli/forward.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from functools import partial import click @@ -13,16 +16,10 @@ @click.argument("input", type=click.Path()) @click.argument("output", type=click.Path()) @click.option( - "-d", - "--duration", - default=1000.0, - type=float, - help="Simulation duration (in ms)", + "-d", "--duration", default=1000.0, type=float, help="Simulation duration (in ms)", ) @click.option("-dt", default=2.0, type=float, help="Time increment (in ms)") -@click.option( - "--n-pml", default=10, type=int, help="PML size (in grid points)" -) +@click.option("--n-pml", default=10, type=int, help="PML size (in grid points)") @click.option( "--n-receivers", default=11, @@ -30,9 +27,7 @@ help="Number of receivers per horizontal dimension", ) @click.option("--space-order", default=2, type=int, help="Space order") -@click.option( - "--spacing", default=10.0, type=float, help="Spacing between grid points" -) +@click.option("--spacing", default=10.0, type=float, help="Spacing between grid points") @click.pass_context def fwd( ctx, @@ -58,9 +53,7 @@ def fwd( @fwd.command() -@click.option( - "-f0", default=0.01, type=float, help="Source peak frequency (in kHz)" -) +@click.option("-f0", default=0.01, type=float, help="Source peak frequency (in kHz)") @click.pass_context def ricker(ctx, f0: float): """Ricker source""" @@ -84,11 +77,7 @@ def ricker(ctx, f0: float): start=0.0, stop=ctx.obj["duration"], step=ctx.obj["dt"] ) source = RickerSource( - name="source", - grid=model.grid, - f0=f0, - npoint=1, - time_range=time_range, + name="source", grid=model.grid, f0=f0, npoint=1, time_range=time_range, ) source.coordinates.data[0, :] = np.array(model.domain_size) * 0.5 source.coordinates.data[0, -1] = 0.0 @@ -107,9 +96,7 @@ def ricker(ctx, f0: float): ) ) for d in range(len(receivers_coords)): - receivers.coordinates.data[:, d] = receivers_coords[ - d - ].flatten() + receivers.coordinates.data[:, d] = receivers_coords[d].flatten() receivers.coordinates.data[:, -1] = 0.0 output_group = output_file.create_group(input_group_name) for input_dataset_name, vp in input_group.items(): @@ -117,7 +104,5 @@ def ricker(ctx, f0: float): seismograms = model.solve( source=source, receivers=receivers, time_range=time_range ) - output_group.create_dataset( - input_dataset_name, data=seismograms - ) + output_group.create_dataset(input_dataset_name, data=seismograms) bar.update(1) diff --git a/imaging/deepseismic_imaging/cli/velocity.py b/imaging/deepseismic_imaging/cli/velocity.py index b8e51da5..c805d6af 100644 --- a/imaging/deepseismic_imaging/cli/velocity.py +++ b/imaging/deepseismic_imaging/cli/velocity.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from functools import partial from itertools import islice from typing import Tuple @@ -13,9 +16,7 @@ @click.group() @click.argument("output", type=click.Path()) @click.option( - "--append/--no-append", - default=False, - help="Whether to append to output file", + "--append/--no-append", default=False, help="Whether to append to output file", ) @click.option("-n", default=1, type=int, help="Number of simulations") @click.option( @@ -30,20 +31,11 @@ type=int, help="Number of grid points along the second dimension", ) -@click.option( - "-nz", type=int, help="Number of grid points along the third dimension" -) +@click.option("-nz", type=int, help="Number of grid points along the third dimension") @click.option("-s", "--seed", default=42, type=int, help="Random seed") @click.pass_context def vp( - ctx, - append: bool, - n: int, - nx: int, - ny: int, - nz: int, - output: str, - seed: int, + ctx, append: bool, n: int, nx: int, ny: int, nz: int, output: str, seed: int, ): """Vp simulation""" shape = (nx, ny) diff --git a/imaging/deepseismic_imaging/forward/__init__.py b/imaging/deepseismic_imaging/forward/__init__.py index f9a9083f..8aaed73e 100644 --- a/imaging/deepseismic_imaging/forward/__init__.py +++ b/imaging/deepseismic_imaging/forward/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from .models import Model, VelocityModel from .sources import Receiver, RickerSource, WaveletSource from .time import TimeAxis diff --git a/imaging/deepseismic_imaging/forward/models.py b/imaging/deepseismic_imaging/forward/models.py index f07b7a1c..eaa0e56d 100644 --- a/imaging/deepseismic_imaging/forward/models.py +++ b/imaging/deepseismic_imaging/forward/models.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional, Tuple, Union import numpy as np @@ -37,9 +40,7 @@ def __init__( subdomains = tuple(subdomains) + (PhysicalDomain(n_pml),) shape_pml = tuple(x + 2 * n_pml for x in shape) extent_pml = tuple(s * (d - 1) for s, d in zip(spacing, shape_pml)) - origin_pml = tuple( - dtype(o - s * n_pml) for o, s in zip(origin, spacing) - ) + origin_pml = tuple(dtype(o - s * n_pml) for o, s in zip(origin, spacing)) self.grid = Grid( shape=shape_pml, extent=extent_pml, @@ -62,14 +63,10 @@ def __init__( idx = [slice(0, x) for x in pml_data.shape] idx[d] = slice(i, i + 1) pml_data[tuple(idx)] += val / self.grid.spacing[d] - idx[d] = slice( - pml_data.shape[d] - i, pml_data.shape[d] - i + 1 - ) + idx[d] = slice(pml_data.shape[d] - i, pml_data.shape[d] - i + 1) pml_data[tuple(idx)] += val / self.grid.spacing[d] pml_data = np.pad( - pml_data, - [(i.left, i.right) for i in self.pml._size_halo], - mode="edge", + pml_data, [(i.left, i.right) for i in self.pml._size_halo], mode="edge", ) self.pml.data_with_halo[:] = pml_data self.shape = shape @@ -110,9 +107,7 @@ def __init__( super().__init__(shape, origin, spacing, n_pml, dtype, subdomains) if isinstance(vp, np.ndarray): assert space_order is not None - self.m = Function( - name="m", grid=self.grid, space_order=int(space_order) - ) + self.m = Function(name="m", grid=self.grid, space_order=int(space_order)) else: self.m = Constant(name="m", value=1.0 / float(vp) ** 2.0) self.vp = vp @@ -126,8 +121,7 @@ def vp(self, vp: Union[float, np.ndarray]) -> None: self._vp = vp if isinstance(vp, np.ndarray): pad_widths = [ - (self.n_pml + i.left, self.n_pml + i.right) - for i in self.m._size_halo + (self.n_pml + i.left, self.n_pml + i.right) for i in self.m._size_halo ] self.m.data_with_halo[:] = np.pad( 1.0 / self.vp ** 2.0, pad_widths, mode="edge" @@ -150,9 +144,7 @@ def solve( H = u.laplace if kernel is Kernel.OT4: H += self.time_spacing ** 2 / 12 * u.laplace2(1 / self.m) - eq = Eq( - u.forward, solve(self.m * u.dt2 - H + self.pml * u.dt, u.forward) - ) + eq = Eq(u.forward, solve(self.m * u.dt2 - H + self.pml * u.dt, u.forward)) src_term = source.inject( field=u.forward, expr=source * self.time_spacing ** 2 / self.m ) diff --git a/imaging/deepseismic_imaging/forward/sources.py b/imaging/deepseismic_imaging/forward/sources.py index 5a0470e2..576e3934 100644 --- a/imaging/deepseismic_imaging/forward/sources.py +++ b/imaging/deepseismic_imaging/forward/sources.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional import numpy as np @@ -22,9 +25,7 @@ def __new__(cls, *args, **kwargs): time_order = kwargs.pop("time_order", 2) p_dim = kwargs.pop("dimension", Dimension(name="p_%s" % name)) npoint = kwargs.pop("npoint", None) - coordinates = kwargs.pop( - "coordinates", kwargs.pop("coordinates_data", None) - ) + coordinates = kwargs.pop("coordinates", kwargs.pop("coordinates_data", None)) if npoint is None: assert ( coordinates is not None @@ -76,16 +77,12 @@ def resample( if np.isclose(dt0, dt, rtol=rtol): return self n_traces = self.data.shape[1] - new_traces = np.zeros( - (new_time_range.num, n_traces), dtype=self.data.dtype - ) + new_traces = np.zeros((new_time_range.num, n_traces), dtype=self.data.dtype) for j in range(n_traces): tck = interpolate.splrep( self._time_range.time_values, self.data[:, j], k=order ) - new_traces[:, j] = interpolate.splev( - new_time_range.time_values, tck - ) + new_traces[:, j] = interpolate.splev(new_time_range.time_values, tck) return PointSource( name=self.name, grid=self.grid, @@ -129,4 +126,4 @@ def wavelet(self, f0: float, t: np.ndarray) -> np.ndarray: class RickerSource(WaveletSource): def wavelet(self, f0: float, t: np.ndarray) -> np.ndarray: r = np.pi * f0 * (t - 1.0 / f0) - return (1.0 - 2.0 * r ** 2.0) * np.exp(-r ** 2.0) + return (1.0 - 2.0 * r ** 2.0) * np.exp(-(r ** 2.0)) diff --git a/imaging/deepseismic_imaging/forward/subdomains.py b/imaging/deepseismic_imaging/forward/subdomains.py index 2ed6cedb..fcabe59b 100644 --- a/imaging/deepseismic_imaging/forward/subdomains.py +++ b/imaging/deepseismic_imaging/forward/subdomains.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Dict, Iterable, Tuple from devito import Dimension, SubDomain diff --git a/imaging/deepseismic_imaging/forward/time.py b/imaging/deepseismic_imaging/forward/time.py index d3dfc00d..7ce51d5d 100644 --- a/imaging/deepseismic_imaging/forward/time.py +++ b/imaging/deepseismic_imaging/forward/time.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional import numpy as np diff --git a/imaging/deepseismic_imaging/forward/types.py b/imaging/deepseismic_imaging/forward/types.py index 772f67b7..3b4fe2ac 100644 --- a/imaging/deepseismic_imaging/forward/types.py +++ b/imaging/deepseismic_imaging/forward/types.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from enum import Enum, auto diff --git a/imaging/deepseismic_imaging/velocity/__init__.py b/imaging/deepseismic_imaging/velocity/__init__.py index 98225180..34ef3009 100644 --- a/imaging/deepseismic_imaging/velocity/__init__.py +++ b/imaging/deepseismic_imaging/velocity/__init__.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from .generator import Generator from .roeth_tarantola import RoethTarantolaGenerator diff --git a/imaging/deepseismic_imaging/velocity/generator.py b/imaging/deepseismic_imaging/velocity/generator.py index ddc2eb4a..5b28721c 100644 --- a/imaging/deepseismic_imaging/velocity/generator.py +++ b/imaging/deepseismic_imaging/velocity/generator.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional, Tuple import numpy as np diff --git a/imaging/deepseismic_imaging/velocity/roeth_tarantola.py b/imaging/deepseismic_imaging/velocity/roeth_tarantola.py index 6c3c0cc4..89f860ae 100644 --- a/imaging/deepseismic_imaging/velocity/roeth_tarantola.py +++ b/imaging/deepseismic_imaging/velocity/roeth_tarantola.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from typing import Optional, Tuple import numpy as np @@ -25,9 +28,9 @@ def __init__( def generate(self) -> np.ndarray: vp = np.zeros(self.shape, dtype=self.dtype) dim = self.depth_dim - layer_idx = np.round( - np.linspace(0, self.shape[dim], self.n_layers + 1) - ).astype(np.int) + layer_idx = np.round(np.linspace(0, self.shape[dim], self.n_layers + 1)).astype( + np.int + ) vp_idx = [slice(0, x) for x in vp.shape] layer_vp = None for i in range(self.n_layers): diff --git a/imaging/setup.py b/imaging/setup.py index 6b074193..5b67c692 100644 --- a/imaging/setup.py +++ b/imaging/setup.py @@ -1,9 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import setuptools with open("../README.md", "r") as f: long_description = f.read() -with open('requirements.txt') as f: +with open("requirements.txt") as f: requirements = f.read().splitlines() setuptools.setup( diff --git a/interpretation/deepseismic_interpretation/dutchf3/data.py b/interpretation/deepseismic_interpretation/dutchf3/data.py index f80f218d..a227c178 100644 --- a/interpretation/deepseismic_interpretation/dutchf3/data.py +++ b/interpretation/deepseismic_interpretation/dutchf3/data.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import itertools import warnings import segyio diff --git a/interpretation/deepseismic_interpretation/dutchf3/utils/batch.py b/interpretation/deepseismic_interpretation/dutchf3/utils/batch.py index f9a3a4ea..41048def 100644 --- a/interpretation/deepseismic_interpretation/dutchf3/utils/batch.py +++ b/interpretation/deepseismic_interpretation/dutchf3/utils/batch.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import numpy as np import scipy diff --git a/interpretation/deepseismic_interpretation/penobscot/data.py b/interpretation/deepseismic_interpretation/penobscot/data.py index f0b64dd4..ca25c0a3 100644 --- a/interpretation/deepseismic_interpretation/penobscot/data.py +++ b/interpretation/deepseismic_interpretation/penobscot/data.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import glob import itertools import os diff --git a/interpretation/deepseismic_interpretation/penobscot/metrics.py b/interpretation/deepseismic_interpretation/penobscot/metrics.py index 28502d00..1be9a5a5 100644 --- a/interpretation/deepseismic_interpretation/penobscot/metrics.py +++ b/interpretation/deepseismic_interpretation/penobscot/metrics.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + from collections import defaultdict from cv_lib.segmentation.dutchf3.metrics import _torch_hist from ignite.metrics import Metric @@ -74,9 +77,7 @@ def update(self, output): max_prediction = y_pred.max(1)[1].squeeze() assert y.shape == max_prediction.shape, "Shape not the same" - for pred, mask, id, patch_loc in zip( - max_prediction, y, ids, patch_locations - ): + for pred, mask, id, patch_loc in zip(max_prediction, y, ids, patch_locations): # ! With overlapping patches this does not aggregate the results it simply overwrites them # If patch is padded ingore padding pad = int(self._padding // 2) @@ -111,9 +112,7 @@ def iou_per_inline(self): self._num_classes, ) hist = confusion_matrix.cpu().numpy() - iu = np.diag(hist) / ( - hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist) - ) + iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist)) iou_per_inline[id] = np.nanmean(iu) return iou_per_inline diff --git a/interpretation/setup.py b/interpretation/setup.py index ebc40ba1..132d8044 100644 --- a/interpretation/setup.py +++ b/interpretation/setup.py @@ -1,9 +1,12 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import setuptools with open("../README.md", "r") as f: long_description = f.read() -with open('requirements.txt') as f: +with open("requirements.txt") as f: requirements = f.read().splitlines() @@ -21,7 +24,6 @@ "Topic :: Scientific/Engineering", "Topic :: Software Development", ], - description="DeepSeismic", install_requires=requirements, license="MIT", diff --git a/setup.py b/setup.py index 3d2cc7b3..8c3f73af 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + import setuptools with open("README.md", "r") as f: @@ -34,9 +37,7 @@ long_description=long_description, long_description_content_type="text/markdown", name="deepseismic", - packages=setuptools.find_packages( - include=["deepseismic", "deepseismic.*"] - ), + packages=setuptools.find_packages(include=["deepseismic", "deepseismic.*"]), platforms="any", python_requires=">= 3.5", scripts=["bin/ds"],