From 88528b27986a1c7e335f2501efa27014116903a4 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Tue, 6 Jul 2021 17:42:40 +0800 Subject: [PATCH 01/11] [DLMED] add decollate logic to DeepGrow Signed-off-by: Nic Ma --- monai/apps/deepgrow/interaction.py | 6 ++- monai/apps/deepgrow/transforms.py | 63 +++++++----------------------- tests/test_deepgrow_interaction.py | 32 +++++++++++---- tests/test_deepgrow_transforms.py | 34 +++++++--------- 4 files changed, 59 insertions(+), 76 deletions(-) diff --git a/monai/apps/deepgrow/interaction.py b/monai/apps/deepgrow/interaction.py index 473ad5bac2..6092c70d31 100644 --- a/monai/apps/deepgrow/interaction.py +++ b/monai/apps/deepgrow/interaction.py @@ -12,6 +12,7 @@ import torch +from monai.data import decollate_batch, list_data_collate from monai.engines import SupervisedEvaluator, SupervisedTrainer from monai.engines.utils import IterationEvents from monai.transforms import Compose @@ -74,6 +75,9 @@ def __call__(self, engine: Union[SupervisedTrainer, SupervisedEvaluator], batchd batchdata[self.key_probability] = torch.as_tensor( ([1.0 - ((1.0 / self.max_interactions) * j)] if self.train else [1.0]) * len(inputs) ) - batchdata = self.transforms(batchdata) + # decollate batch data to execute click transforms + batchdata = [self.transforms(i) for i in decollate_batch(batchdata, detach=True)] + # collate list into a batch for next round interaction + batchdata = list_data_collate(batchdata) return engine._iteration(engine, batchdata) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index cfdeb5c87f..86fe23ccd4 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -159,7 +159,7 @@ class AddGuidanceSignald(Transform): guidance: key to store guidance. sigma: standard deviation for Gaussian kernel. number_intensity_ch: channel index. - batched: whether input is batched or not. + """ def __init__( @@ -168,13 +168,11 @@ def __init__( guidance: str = "guidance", sigma: int = 2, number_intensity_ch: int = 1, - batched: bool = False, ): self.image = image self.guidance = guidance self.sigma = sigma self.number_intensity_ch = number_intensity_ch - self.batched = batched def _get_signal(self, image, guidance): dimensions = 3 if len(image.shape) > 3 else 2 @@ -210,16 +208,8 @@ def _get_signal(self, image, guidance): return signal def _apply(self, image, guidance): - if not self.batched: - signal = self._get_signal(image, guidance) - return np.concatenate([image, signal], axis=0) - - images = [] - for i, g in zip(image, guidance): - i = i[0 : 0 + self.number_intensity_ch, ...] - signal = self._get_signal(i, g) - images.append(np.concatenate([i, signal], axis=0)) - return images + signal = self._get_signal(image, guidance) + return np.concatenate([image, signal], axis=0) def __call__(self, data): d = dict(data) @@ -244,7 +234,7 @@ class FindDiscrepancyRegionsd(Transform): label: key to label source. pred: key to prediction source. discrepancy: key to store discrepancies found between label and prediction. - batched: whether input is batched or not. + """ def __init__( @@ -253,7 +243,6 @@ def __init__( self.label = label self.pred = pred self.discrepancy = discrepancy - self.batched = batched @staticmethod def disparity(label, pred): @@ -266,13 +255,7 @@ def disparity(label, pred): return [pos_disparity, neg_disparity] def _apply(self, label, pred): - if not self.batched: - return self.disparity(label, pred) - - disparity = [] - for la, pr in zip(label, pred): - disparity.append(self.disparity(la, pr)) - return disparity + return self.disparity(label, pred) def __call__(self, data): d = dict(data) @@ -309,7 +292,7 @@ class AddRandomGuidanced(Randomizable, Transform): guidance: key to guidance source. discrepancy: key that represents discrepancies found between label and prediction. probability: key that represents click/interaction probability. - batched: whether input is batched or not. + """ def __init__( @@ -317,22 +300,15 @@ def __init__( guidance: str = "guidance", discrepancy: str = "discrepancy", probability: str = "probability", - batched: bool = True, ): self.guidance = guidance self.discrepancy = discrepancy self.probability = probability - self.batched = batched self._will_interact = None def randomize(self, data=None): probability = data[self.probability] - if not self.batched: - self._will_interact = self.R.choice([True, False], p=[probability, 1.0 - probability]) - else: - self._will_interact = [] - for p in probability: - self._will_interact.append(self.R.choice([True, False], p=[p, 1.0 - p])) + self._will_interact = self.R.choice([True, False], p=[probability, 1.0 - probability]) def find_guidance(self, discrepancy): distance = distance_transform_cdt(discrepancy).flatten() @@ -368,23 +344,14 @@ def add_guidance(self, discrepancy, will_interact): def _apply(self, guidance, discrepancy): guidance = guidance.tolist() if isinstance(guidance, np.ndarray) else guidance - if not self.batched: - pos, neg = self.add_guidance(discrepancy, self._will_interact) - if pos: - guidance[0].append(pos) - guidance[1].append([-1] * len(pos)) - if neg: - guidance[0].append([-1] * len(neg)) - guidance[1].append(neg) - else: - for g, d, w in zip(guidance, discrepancy, self._will_interact): - pos, neg = self.add_guidance(d, w) - if pos: - g[0].append(pos) - g[1].append([-1] * len(pos)) - if neg: - g[0].append([-1] * len(neg)) - g[1].append(neg) + pos, neg = self.add_guidance(discrepancy, self._will_interact) + if pos: + guidance[0].append(pos) + guidance[1].append([-1] * len(pos)) + if neg: + guidance[0].append([-1] * len(neg)) + guidance[1].append(neg) + return np.asarray(guidance) def __call__(self, data): diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 77c37bf5f3..4e9547b0e1 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -12,16 +12,23 @@ import unittest import torch +import numpy as np from monai.apps.deepgrow.interaction import Interaction +from monai.apps.deepgrow.transforms import ( + AddInitialSeedPointd, + AddGuidanceSignald, + FindAllValidSlicesd, + FindDiscrepancyRegionsd, +) from monai.data import Dataset from monai.engines import SupervisedTrainer from monai.engines.utils import IterationEvents -from monai.transforms import Activationsd, Compose, ToNumpyd +from monai.transforms import Activationsd, Compose, ToNumpyd, ToTensord def add_one(engine): - if engine.state.best_metric is -1: + if engine.state.best_metric == -1: engine.state.best_metric = 0 else: engine.state.best_metric = engine.state.best_metric + 1 @@ -31,19 +38,30 @@ class TestInteractions(unittest.TestCase): def run_interaction(self, train, compose): data = [] for i in range(5): - data.append({"image": torch.tensor([float(i)]), "label": torch.tensor([float(i)])}) - network = torch.nn.Linear(1, 1) + data.append({"image": np.ones((1, 2, 2, 2)).astype(np.float32), "label": np.ones((1, 2, 2, 2))}) + network = torch.nn.PReLU() lr = 1e-3 opt = torch.optim.SGD(network.parameters(), lr) loss = torch.nn.L1Loss() - dataset = Dataset(data, transform=None) + train_transforms = Compose([ + FindAllValidSlicesd(label='label', sids='sids'), + AddInitialSeedPointd(label='label', guidance='guidance', sids='sids'), + AddGuidanceSignald(image='image', guidance='guidance'), + ToTensord(keys=('image', 'label')), + ]) + dataset = Dataset(data, transform=train_transforms) data_loader = torch.utils.data.DataLoader(dataset, batch_size=5) - iteration_transforms = [Activationsd(keys="pred", sigmoid=True), ToNumpyd(keys="pred")] + iteration_transforms = [ + Activationsd(keys="pred", sigmoid=True), + ToNumpyd(keys=['image', 'label', 'pred', 'guidance']), + FindDiscrepancyRegionsd(label='label', pred='pred', discrepancy='discrepancy'), + AddGuidanceSignald(image='image', guidance='guidance'), + ] iteration_transforms = Compose(iteration_transforms) if compose else iteration_transforms i = Interaction(transforms=iteration_transforms, train=train, max_interactions=5) - self.assertEqual(len(i.transforms.transforms), 2, "Mismatch in expected transforms") + self.assertEqual(len(i.transforms.transforms), 4, "Mismatch in expected transforms") # set up engine engine = SupervisedTrainer( diff --git a/tests/test_deepgrow_transforms.py b/tests/test_deepgrow_transforms.py index 83bb5ebaa4..eb1d5967d4 100644 --- a/tests/test_deepgrow_transforms.py +++ b/tests/test_deepgrow_transforms.py @@ -30,8 +30,6 @@ IMAGE = np.array([[[[1, 0, 2, 0, 1], [0, 1, 2, 1, 0], [2, 2, 3, 2, 2], [0, 1, 2, 1, 0], [1, 0, 2, 0, 1]]]]) LABEL = np.array([[[[0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0]]]]) -BATCH_IMAGE = np.array([[[[[1, 0, 2, 0, 1], [0, 1, 2, 1, 0], [2, 2, 3, 2, 2], [0, 1, 2, 1, 0], [1, 0, 2, 0, 1]]]]]) -BATCH_LABEL = np.array([[[[[0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0]]]]]) DATA_1 = { "image": IMAGE, @@ -61,24 +59,22 @@ } DATA_3 = { - "image": BATCH_IMAGE, - "label": BATCH_LABEL, - "pred": np.array([[[[[0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0]]]]]), + "image": IMAGE, + "label": LABEL, + "pred": np.array([[[[0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0]]]]), } DATA_4 = { - "image": BATCH_IMAGE, - "label": BATCH_LABEL, - "guidance": np.array([[[[1, 0, 2, 2]], [[-1, -1, -1, -1]]]]), + "image": IMAGE, + "label": LABEL, + "guidance": np.array([[[1, 0, 2, 2]], [[-1, -1, -1, -1]]]), "discrepancy": np.array( [ - [ - [[[[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], - [[[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], - ] + [[[[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], + [[[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], ] ), - "probability": [1.0], + "probability": 1.0, } DATA_5 = { @@ -196,7 +192,7 @@ ] ADD_GUIDANCE_TEST_CASE_1 = [ - {"image": "image", "guidance": "guidance", "batched": False}, + {"image": "image", "guidance": "guidance"}, DATA_2, np.array( [ @@ -233,18 +229,16 @@ DATA_3, np.array( [ - [ - [[[[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], - [[[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], - ] + [[[[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], + [[[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]], ] ), ] ADD_RANDOM_GUIDANCE_TEST_CASE_1 = [ - {"guidance": "guidance", "discrepancy": "discrepancy", "probability": "probability", "batched": True}, + {"guidance": "guidance", "discrepancy": "discrepancy", "probability": "probability"}, DATA_4, - np.array([[[[1, 0, 2, 2], [1, 0, 1, 3]], [[-1, -1, -1, -1], [-1, -1, -1, -1]]]]), + np.array([[[1, 0, 2, 2], [1, 0, 1, 3]], [[-1, -1, -1, -1], [-1, -1, -1, -1]]]), ] ADD_GUIDANCE_FROM_POINTS_TEST_CASE_1 = [ From 5cee4b8ec1bd94c615841e9c37b49483d9b92f11 Mon Sep 17 00:00:00 2001 From: monai-bot Date: Tue, 6 Jul 2021 09:58:25 +0000 Subject: [PATCH 02/11] [MONAI] python code formatting Signed-off-by: monai-bot --- tests/test_deepgrow_interaction.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 4e9547b0e1..95076253c1 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -11,13 +11,13 @@ import unittest -import torch import numpy as np +import torch from monai.apps.deepgrow.interaction import Interaction from monai.apps.deepgrow.transforms import ( - AddInitialSeedPointd, AddGuidanceSignald, + AddInitialSeedPointd, FindAllValidSlicesd, FindDiscrepancyRegionsd, ) @@ -43,20 +43,22 @@ def run_interaction(self, train, compose): lr = 1e-3 opt = torch.optim.SGD(network.parameters(), lr) loss = torch.nn.L1Loss() - train_transforms = Compose([ - FindAllValidSlicesd(label='label', sids='sids'), - AddInitialSeedPointd(label='label', guidance='guidance', sids='sids'), - AddGuidanceSignald(image='image', guidance='guidance'), - ToTensord(keys=('image', 'label')), - ]) + train_transforms = Compose( + [ + FindAllValidSlicesd(label="label", sids="sids"), + AddInitialSeedPointd(label="label", guidance="guidance", sids="sids"), + AddGuidanceSignald(image="image", guidance="guidance"), + ToTensord(keys=("image", "label")), + ] + ) dataset = Dataset(data, transform=train_transforms) data_loader = torch.utils.data.DataLoader(dataset, batch_size=5) iteration_transforms = [ Activationsd(keys="pred", sigmoid=True), - ToNumpyd(keys=['image', 'label', 'pred', 'guidance']), - FindDiscrepancyRegionsd(label='label', pred='pred', discrepancy='discrepancy'), - AddGuidanceSignald(image='image', guidance='guidance'), + ToNumpyd(keys=["image", "label", "pred", "guidance"]), + FindDiscrepancyRegionsd(label="label", pred="pred", discrepancy="discrepancy"), + AddGuidanceSignald(image="image", guidance="guidance"), ] iteration_transforms = Compose(iteration_transforms) if compose else iteration_transforms From 770db627f2c0464ef4d9ab4cb626f930a0c02b53 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Tue, 6 Jul 2021 21:47:44 +0800 Subject: [PATCH 03/11] [DLMED] fix flake8 issue Signed-off-by: Nic Ma --- tests/test_deepgrow_interaction.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 95076253c1..3d3c9fa01e 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -36,9 +36,7 @@ def add_one(engine): class TestInteractions(unittest.TestCase): def run_interaction(self, train, compose): - data = [] - for i in range(5): - data.append({"image": np.ones((1, 2, 2, 2)).astype(np.float32), "label": np.ones((1, 2, 2, 2))}) + data = [{"image": np.ones((1, 2, 2, 2)).astype(np.float32), "label": np.ones((1, 2, 2, 2))} for _ in range(5)] network = torch.nn.PReLU() lr = 1e-3 opt = torch.optim.SGD(network.parameters(), lr) From 98528603fe4d9b7055b7a531e7870d46cf8d3bd5 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Tue, 6 Jul 2021 23:35:33 +0800 Subject: [PATCH 04/11] [DLMED] add AddRandomGuidanced to test Signed-off-by: Nic Ma --- monai/apps/deepgrow/transforms.py | 22 +--------------------- tests/test_deepgrow_interaction.py | 4 +++- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 86fe23ccd4..790b4f8919 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -224,12 +224,6 @@ class FindDiscrepancyRegionsd(Transform): """ Find discrepancy between prediction and actual during click interactions during training. - If batched is true: - - label is in shape (B, C, D, H, W) or (B, C, H, W) - pred has same shape as label - discrepancy will have shape (B, 2, C, D, H, W) or (B, 2, C, H, W) - Args: label: key to label source. pred: key to prediction source. @@ -269,23 +263,9 @@ def __call__(self, data): class AddRandomGuidanced(Randomizable, Transform): """ Add random guidance based on discrepancies that were found between label and prediction. - - If batched is True, input shape is as below: - - Guidance is of shape (B, 2, N, # of dim) where B is batch size, 2 means positive and negative, - N means how many guidance points, # of dim is the total number of dimensions of the image - (for example if the image is CDHW, then # of dim would be 4). - - Discrepancy is of shape (B, 2, C, D, H, W) or (B, 2, C, H, W) - - Probability is of shape (B, 1) - - else: - + input shape is as below: Guidance is of shape (2, N, # of dim) - Discrepancy is of shape (2, C, D, H, W) or (2, C, H, W) - Probability is of shape (1) Args: diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 3d3c9fa01e..20aa7448a9 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -18,6 +18,7 @@ from monai.apps.deepgrow.transforms import ( AddGuidanceSignald, AddInitialSeedPointd, + AddRandomGuidanced, FindAllValidSlicesd, FindDiscrepancyRegionsd, ) @@ -56,12 +57,13 @@ def run_interaction(self, train, compose): Activationsd(keys="pred", sigmoid=True), ToNumpyd(keys=["image", "label", "pred", "guidance"]), FindDiscrepancyRegionsd(label="label", pred="pred", discrepancy="discrepancy"), + AddRandomGuidanced(guidance='guidance', discrepancy='discrepancy', probability='probability'), AddGuidanceSignald(image="image", guidance="guidance"), ] iteration_transforms = Compose(iteration_transforms) if compose else iteration_transforms i = Interaction(transforms=iteration_transforms, train=train, max_interactions=5) - self.assertEqual(len(i.transforms.transforms), 4, "Mismatch in expected transforms") + self.assertEqual(len(i.transforms.transforms), 5, "Mismatch in expected transforms") # set up engine engine = SupervisedTrainer( From 69018473e0f808417085639646442c50d12318e2 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 00:06:06 +0800 Subject: [PATCH 05/11] [DLMED] update network Signed-off-by: Nic Ma --- tests/test_deepgrow_interaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 20aa7448a9..83552f5e71 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -38,7 +38,7 @@ def add_one(engine): class TestInteractions(unittest.TestCase): def run_interaction(self, train, compose): data = [{"image": np.ones((1, 2, 2, 2)).astype(np.float32), "label": np.ones((1, 2, 2, 2))} for _ in range(5)] - network = torch.nn.PReLU() + network = torch.nn.Linear(2, 2) lr = 1e-3 opt = torch.optim.SGD(network.parameters(), lr) loss = torch.nn.L1Loss() From 4ce590349a5b078d601a27a3b8a2d4e395ae3405 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 00:25:22 +0800 Subject: [PATCH 06/11] [DLMED] fix typo Signed-off-by: Nic Ma --- monai/apps/deepgrow/transforms.py | 4 +--- tests/test_deepgrow_interaction.py | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 790b4f8919..0f042ca38c 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -231,9 +231,7 @@ class FindDiscrepancyRegionsd(Transform): """ - def __init__( - self, label: str = "label", pred: str = "pred", discrepancy: str = "discrepancy", batched: bool = True - ): + def __init__(self, label: str = "label", pred: str = "pred", discrepancy: str = "discrepancy"): self.label = label self.pred = pred self.discrepancy = discrepancy diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 83552f5e71..f466dc8499 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -59,11 +59,12 @@ def run_interaction(self, train, compose): FindDiscrepancyRegionsd(label="label", pred="pred", discrepancy="discrepancy"), AddRandomGuidanced(guidance='guidance', discrepancy='discrepancy', probability='probability'), AddGuidanceSignald(image="image", guidance="guidance"), + ToTensord(keys=('image', 'label')), ] iteration_transforms = Compose(iteration_transforms) if compose else iteration_transforms i = Interaction(transforms=iteration_transforms, train=train, max_interactions=5) - self.assertEqual(len(i.transforms.transforms), 5, "Mismatch in expected transforms") + self.assertEqual(len(i.transforms.transforms), 6, "Mismatch in expected transforms") # set up engine engine = SupervisedTrainer( From d317d00c1cc9b9fb02dbc42d6c34100223ba62cd Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 01:12:02 +0800 Subject: [PATCH 07/11] [DLMED] fix issue in addsignal Signed-off-by: Nic Ma --- monai/apps/deepgrow/transforms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 0f042ca38c..6d44eba5e9 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -209,6 +209,7 @@ def _get_signal(self, image, guidance): def _apply(self, image, guidance): signal = self._get_signal(image, guidance) + image = image[0 : 0 + self.number_intensity_ch, ...] return np.concatenate([image, signal], axis=0) def __call__(self, data): From c9a41f8b9cfd4f27f63843bd6ad983ae02cbd006 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 07:43:59 +0800 Subject: [PATCH 08/11] [DLMED] fix guidance issue Signed-off-by: Nic Ma --- monai/apps/deepgrow/transforms.py | 8 +++++--- tests/test_deepgrow_interaction.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 6d44eba5e9..3389025210 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -12,7 +12,7 @@ import numpy as np import torch - +import json from monai.config import IndexSelection, KeysCollection from monai.networks.layers import GaussianFilter from monai.transforms import Resize, SpatialCrop @@ -144,7 +144,7 @@ def _apply(self, label, sid): def __call__(self, data): d = dict(data) self.randomize(data) - d[self.guidance] = self._apply(d[self.label], self.sid) + d[self.guidance] = json.dumps(self._apply(d[self.label], self.sid).astype(int).tolist()) return d @@ -177,6 +177,7 @@ def __init__( def _get_signal(self, image, guidance): dimensions = 3 if len(image.shape) > 3 else 2 guidance = guidance.tolist() if isinstance(guidance, np.ndarray) else guidance + guidance = json.loads(guidance) if isinstance(guidance, str) else guidance if dimensions == 3: signal = np.zeros((len(guidance), image.shape[-3], image.shape[-2], image.shape[-1]), dtype=np.float32) else: @@ -323,6 +324,7 @@ def add_guidance(self, discrepancy, will_interact): def _apply(self, guidance, discrepancy): guidance = guidance.tolist() if isinstance(guidance, np.ndarray) else guidance + guidance = json.loads(guidance) if isinstance(guidance, str) else guidance pos, neg = self.add_guidance(discrepancy, self._will_interact) if pos: guidance[0].append(pos) @@ -331,7 +333,7 @@ def _apply(self, guidance, discrepancy): guidance[0].append([-1] * len(neg)) guidance[1].append(neg) - return np.asarray(guidance) + return json.dumps(np.asarray(guidance).astype(int).tolist()) def __call__(self, data): d = dict(data) diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index f466dc8499..2458b1e7d4 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -55,7 +55,7 @@ def run_interaction(self, train, compose): iteration_transforms = [ Activationsd(keys="pred", sigmoid=True), - ToNumpyd(keys=["image", "label", "pred", "guidance"]), + ToNumpyd(keys=["image", "label", "pred"]), FindDiscrepancyRegionsd(label="label", pred="pred", discrepancy="discrepancy"), AddRandomGuidanced(guidance='guidance', discrepancy='discrepancy', probability='probability'), AddGuidanceSignald(image="image", guidance="guidance"), From 42ac148bdbc52d7bba7d5b8de49d682d431a870d Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 07:52:18 +0800 Subject: [PATCH 09/11] [DLMED] fix flake8 Signed-off-by: Nic Ma --- monai/apps/deepgrow/transforms.py | 3 ++- tests/test_deepgrow_interaction.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 3389025210..138593c172 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -8,11 +8,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import json from typing import Callable, Dict, Optional, Sequence, Union import numpy as np import torch -import json + from monai.config import IndexSelection, KeysCollection from monai.networks.layers import GaussianFilter from monai.transforms import Resize, SpatialCrop diff --git a/tests/test_deepgrow_interaction.py b/tests/test_deepgrow_interaction.py index 2458b1e7d4..e5c7bf9051 100644 --- a/tests/test_deepgrow_interaction.py +++ b/tests/test_deepgrow_interaction.py @@ -57,9 +57,9 @@ def run_interaction(self, train, compose): Activationsd(keys="pred", sigmoid=True), ToNumpyd(keys=["image", "label", "pred"]), FindDiscrepancyRegionsd(label="label", pred="pred", discrepancy="discrepancy"), - AddRandomGuidanced(guidance='guidance', discrepancy='discrepancy', probability='probability'), + AddRandomGuidanced(guidance="guidance", discrepancy="discrepancy", probability="probability"), AddGuidanceSignald(image="image", guidance="guidance"), - ToTensord(keys=('image', 'label')), + ToTensord(keys=("image", "label")), ] iteration_transforms = Compose(iteration_transforms) if compose else iteration_transforms From df99a095876568fc41da669a7ed346186761b5db Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 08:00:09 +0800 Subject: [PATCH 10/11] [DLMED] fix mypy and docs Signed-off-by: Nic Ma --- monai/apps/deepgrow/interaction.py | 4 ++-- monai/apps/deepgrow/transforms.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/monai/apps/deepgrow/interaction.py b/monai/apps/deepgrow/interaction.py index 6092c70d31..11b56086df 100644 --- a/monai/apps/deepgrow/interaction.py +++ b/monai/apps/deepgrow/interaction.py @@ -76,8 +76,8 @@ def __call__(self, engine: Union[SupervisedTrainer, SupervisedEvaluator], batchd ([1.0 - ((1.0 / self.max_interactions) * j)] if self.train else [1.0]) * len(inputs) ) # decollate batch data to execute click transforms - batchdata = [self.transforms(i) for i in decollate_batch(batchdata, detach=True)] + batchdata_list = [self.transforms(i) for i in decollate_batch(batchdata, detach=True)] # collate list into a batch for next round interaction - batchdata = list_data_collate(batchdata) + batchdata = list_data_collate(batchdata_list) return engine._iteration(engine, batchdata) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 138593c172..db450792b0 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -265,9 +265,9 @@ class AddRandomGuidanced(Randomizable, Transform): """ Add random guidance based on discrepancies that were found between label and prediction. input shape is as below: - Guidance is of shape (2, N, # of dim) - Discrepancy is of shape (2, C, D, H, W) or (2, C, H, W) - Probability is of shape (1) + Guidance is of shape (2, N, # of dim) + Discrepancy is of shape (2, C, D, H, W) or (2, C, H, W) + Probability is of shape (1) Args: guidance: key to guidance source. From 7b2e9b9dd14d96e82ba5cb15efe125531eec4882 Mon Sep 17 00:00:00 2001 From: Nic Ma Date: Wed, 7 Jul 2021 09:51:00 +0800 Subject: [PATCH 11/11] [DLMED] fix CI tests Signed-off-by: Nic Ma --- tests/test_deepgrow_transforms.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_deepgrow_transforms.py b/tests/test_deepgrow_transforms.py index eb1d5967d4..f50e92d146 100644 --- a/tests/test_deepgrow_transforms.py +++ b/tests/test_deepgrow_transforms.py @@ -188,7 +188,7 @@ ADD_INITIAL_POINT_TEST_CASE_1 = [ {"label": "label", "guidance": "guidance", "sids": "sids"}, DATA_1, - np.array([[[1, 0, 2, 2]], [[-1, -1, -1, -1]]]), + "[[[1, 0, 2, 2]], [[-1, -1, -1, -1]]]", ] ADD_GUIDANCE_TEST_CASE_1 = [ @@ -238,7 +238,7 @@ ADD_RANDOM_GUIDANCE_TEST_CASE_1 = [ {"guidance": "guidance", "discrepancy": "discrepancy", "probability": "probability"}, DATA_4, - np.array([[[1, 0, 2, 2], [1, 0, 1, 3]], [[-1, -1, -1, -1], [-1, -1, -1, -1]]]), + "[[[1, 0, 2, 2], [1, 0, 1, 3]], [[-1, -1, -1, -1], [-1, -1, -1, -1]]]", ] ADD_GUIDANCE_FROM_POINTS_TEST_CASE_1 = [ @@ -392,7 +392,7 @@ def test_correct_results(self, arguments, input_data, expected_result): add_fn = AddInitialSeedPointd(**arguments) add_fn.set_random_state(seed) result = add_fn(input_data) - np.testing.assert_allclose(result[arguments["guidance"]], expected_result) + self.assertEqual(result[arguments["guidance"]], expected_result) class TestAddGuidanceSignald(unittest.TestCase): @@ -416,7 +416,7 @@ def test_correct_results(self, arguments, input_data, expected_result): add_fn = AddRandomGuidanced(**arguments) add_fn.set_random_state(seed) result = add_fn(input_data) - np.testing.assert_allclose(result[arguments["guidance"]], expected_result, rtol=1e-5) + self.assertEqual(result[arguments["guidance"]], expected_result) class TestAddGuidanceFromPointsd(unittest.TestCase):