Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions Evaluation/evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ def forward(self, y_pred, y_true):
y_true_f = torch.flatten(y_true)
intersection = torch.sum(y_true_f * y_pred_f)
union = torch.sum(y_true_f + y_pred_f) - intersection
score = (intersection + self.smooth) / (union + self.smooth)
return score
return (intersection + self.smooth) / (union + self.smooth)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function IOU.forward refactored with the following changes:



class FocalTverskyLoss(nn.Module):
Expand Down Expand Up @@ -81,10 +80,16 @@ def nan_hook(self, module, inp, output):
torch.save(inp, os.path.join(self.output_dir, 'nan_floss_ip.pt'))
module_params = module.named_parameters()
for name, param in module_params:
torch.save(param, os.path.join(self.output_dir, 'nan_floss_{}_param.pt'.format(name)))
raise RuntimeError(" classname " + self.__class__.__name__ + "i " + str(
i) + f" module: {module} classname {self.__class__.__name__} Found NAN in output {i} at indices: ",
nan_mask.nonzero(), "where:", out[nan_mask.nonzero()[:, 0].unique(sorted=True)])
torch.save(param, os.path.join(self.output_dir, f'nan_floss_{name}_param.pt'))
raise RuntimeError(
(
f" classname {self.__class__.__name__}i {str(i)}"
+ f" module: {module} classname {self.__class__.__name__} Found NAN in output {i} at indices: "
),
nan_mask.nonzero(),
"where:",
out[nan_mask.nonzero()[:, 0].unique(sorted=True)],
)
Comment on lines -84 to +92

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FocalTverskyLoss.nan_hook refactored with the following changes:



class FocalTverskyLoss_detailed(nn.Module):
Expand All @@ -100,7 +105,9 @@ def forward(self, logger, y_pred, y_true):
true_pos = torch.sum(y_true_pos * y_pred_pos)
false_neg = torch.sum(y_true_pos * (1 - y_pred_pos))
false_pos = torch.sum((1 - y_true_pos) * y_pred_pos)
logger.info("True Positive:" + str(true_pos) + " False_Negative:" + str(false_neg) + " False_Positive:" + str(false_pos))
logger.info(
f"True Positive:{str(true_pos)} False_Negative:{str(false_neg)} False_Positive:{str(false_pos)}"
)
Comment on lines -103 to +110

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function FocalTverskyLoss_detailed.forward refactored with the following changes:

pt_1 = (true_pos + self.smooth) / (
true_pos + self.alpha * false_neg + (1 - self.alpha) * false_pos + self.smooth)
return pow((1 - pt_1), self.gamma)
Expand Down Expand Up @@ -159,6 +166,8 @@ def getLosses(logger, true_pos, false_neg, false_pos, intersection, union):
pt_1 = (true_pos + smooth) / (true_pos + alpha * false_neg + (1 - alpha) * false_pos + smooth)
floss = pow((1 - pt_1), gamma)

logger.info("True Positive:" + str(true_pos) + " False_Negative:" + str(false_neg) + " False_Positive:" + str(false_pos))
logger.info("Floss:" + str(floss) + " diceloss:" + str(dice_loss) + " iou:" + str(iou))
logger.info(
f"True Positive:{str(true_pos)} False_Negative:{str(false_neg)} False_Positive:{str(false_pos)}"
)
logger.info(f"Floss:{str(floss)} diceloss:{str(dice_loss)} iou:{str(iou)}")
Comment on lines -162 to +172

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function getLosses refactored with the following changes:

return floss, dice_loss, iou
10 changes: 8 additions & 2 deletions Models/unet3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,15 @@ def nan_hook(self, module, inp, output):
torch.save(inp, os.path.join(self.output_dir, 'nan_values_ip.pt'))
module_params = module.named_parameters()
for name, param in module_params:
torch.save(param, os.path.join(self.output_dir, 'nan_{}_param.pt'.format(name)))
torch.save(param, os.path.join(self.output_dir, f'nan_{name}_param.pt'))
torch.save(self.input_to_net, os.path.join(self.output_dir, 'nan_ip_batch.pt'))
raise RuntimeError(" classname "+self.__class__.__name__+"i "+str(i)+f" module: {module} classname {self.__class__.__name__} Found NAN in output {i} at indices: ", nan_mask.nonzero(), "where:", out[nan_mask.nonzero()[:, 0].unique(sorted=True)])
raise RuntimeError(
f" classname {self.__class__.__name__}i {str(i)}"
+ f" module: {module} classname {self.__class__.__name__} Found NAN in output {i} at indices: ",
nan_mask.nonzero(),
"where:",
out[nan_mask.nonzero()[:, 0].unique(sorted=True)],
)
Comment on lines -229 to +237

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function U_Net_DeepSup.nan_hook refactored with the following changes:


def forward(self, x):
# print("unet")
Expand Down
31 changes: 14 additions & 17 deletions Utils/customutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ def performUndersampling(fullImgVol, mask=None, maskmatpath=None, zeropad=True):
# path will only be used in mask not supplied
fullKSPVol = fft2c(fullImgVol)
underKSPVol = performUndersamplingKSP(fullKSPVol, mask, maskmatpath, zeropad)
underImgVol = ifft2c(underKSPVol)
return underImgVol
return ifft2c(underKSPVol)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function performUndersampling refactored with the following changes:



def performUndersamplingKSP(fullKSPVol, mask=None, maskmatpath=None, zeropad=True):
Expand All @@ -89,18 +88,16 @@ def performUndersamplingKSP(fullKSPVol, mask=None, maskmatpath=None, zeropad=Tru
if mask is None:
mask = sio.loadmat(maskmatpath)['mask']
if zeropad:
underKSPVol = np.multiply(fullKSPVol.transpose((2, 0, 1)), mask).transpose((1, 2, 0))
else:
temp = []
for i in range(mask.shape[0]):
maskline = mask[i, :]
if maskline.any():
temp.append(fullKSPVol[i, ...])
temp = np.array(temp)
underKSPVol = []
for i in range(mask.shape[1]):
maskline = mask[:, i]
if maskline.any():
underKSPVol.append(temp[:, i, ...])
underKSPVol = np.array(underKSPVol).swapaxes(0, 1)
return underKSPVol
return np.multiply(fullKSPVol.transpose((2, 0, 1)), mask).transpose((1, 2, 0))
temp = []
for i in range(mask.shape[0]):
maskline = mask[i, :]
if maskline.any():
temp.append(fullKSPVol[i, ...])
temp = np.array(temp)
underKSPVol = []
for i in range(mask.shape[1]):
maskline = mask[:, i]
if maskline.any():
underKSPVol.append(temp[:, i, ...])
return np.array(underKSPVol).swapaxes(0, 1)
Comment on lines -92 to +103

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function performUndersamplingKSP refactored with the following changes:

9 changes: 3 additions & 6 deletions Utils/madam.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ def step(self, closure=None):
closure (callable, optional): A closure that reevaluates the model
and returns the loss.
"""
loss = None
if closure is not None:
loss = closure()

loss = closure() if closure is not None else None

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Madam.step refactored with the following changes:

for group in self.param_groups:
for p in group['params']:
if p.grad is None:
Expand All @@ -35,11 +32,11 @@ def step(self, closure=None):
state['step'] += 1
bias_correction = 1 - 0.999 ** state['step']
state['exp_avg_sq'] = 0.999 * state['exp_avg_sq'] + 0.001 * p.grad.data**2

g_normed = p.grad.data / (state['exp_avg_sq']/bias_correction).sqrt()
g_normed[torch.isnan(g_normed)] = 0
g_normed.clamp_(-self.g_bound, self.g_bound)

p.data *= torch.exp( -group['lr']*g_normed*torch.sign(p.data) )
p.data.clamp_(-state['max'], state['max'])

Expand Down
8 changes: 4 additions & 4 deletions Utils/vessel_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ def convert_and_save_tif(image3D, output_path, filename='output.tif', isColored=
image = transforms.ToPILImage(mode='RGB')(tensor_image)
image_list.append(image)

print('convert_and_save_tif:size of image:'+ str(len(image_list)))
print(f'convert_and_save_tif:size of image:{len(image_list)}')
with TiffImagePlugin.AppendingTiffWriter(output_path + filename, True) as tifWriter:
for im in image_list:
# with open(DATASET_FOLDER+tiff_in) as tiff_in:
im.save(tifWriter)
tifWriter.newFrame()
print("Conversion to tiff completed, image saved as {}".format(filename))
print(f"Conversion to tiff completed, image saved as {filename}")
Comment on lines -121 to +127

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function convert_and_save_tif refactored with the following changes:


def convert_and_save_tif_greyscale(image3D, output_path, filename='output.tif'):
"""
Expand All @@ -137,13 +137,13 @@ def convert_and_save_tif_greyscale(image3D, output_path, filename='output.tif'):
image = transforms.ToPILImage(mode='F')(tensor_image)
image_list.append(image)

print('convert_and_save_tif:size of image:' + str(len(image_list)))
print(f'convert_and_save_tif:size of image:{len(image_list)}')
with TiffImagePlugin.AppendingTiffWriter(output_path + filename, True) as tifWriter:
for im in image_list:
# with open(DATASET_FOLDER+tiff_in) as tiff_in:
im.save(tifWriter)
tifWriter.newFrame()
print("Conversion to tiff completed, image saved as {}".format(filename))
print(f"Conversion to tiff completed, image saved as {filename}")
Comment on lines -140 to +146

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function convert_and_save_tif_greyscale refactored with the following changes:



def create_mask(predicted, logger):
Expand Down
23 changes: 16 additions & 7 deletions main_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
"""

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 184-210 refactored with the following changes:


import argparse
import random
import os
Expand Down Expand Up @@ -181,15 +182,21 @@
OUTPUT_PATH = args.output_path

LOAD_PATH = args.load_path
CHECKPOINT_PATH = OUTPUT_PATH + "/" + MODEL_NAME + '/checkpoint/'
TENSORBOARD_PATH_TRAINING = OUTPUT_PATH + "/" + MODEL_NAME + '/tensorboard/tensorboard_training/'
TENSORBOARD_PATH_VALIDATION = OUTPUT_PATH + "/" + MODEL_NAME + '/tensorboard/tensorboard_validation/'
TENSORBOARD_PATH_TESTING = OUTPUT_PATH + "/" + MODEL_NAME + '/tensorboard/tensorboard_testing/'
CHECKPOINT_PATH = f"{OUTPUT_PATH}/{MODEL_NAME}/checkpoint/"
TENSORBOARD_PATH_TRAINING = (
f"{OUTPUT_PATH}/{MODEL_NAME}/tensorboard/tensorboard_training/"
)
TENSORBOARD_PATH_VALIDATION = (
f"{OUTPUT_PATH}/{MODEL_NAME}/tensorboard/tensorboard_validation/"
)
TENSORBOARD_PATH_TESTING = (
f"{OUTPUT_PATH}/{MODEL_NAME}/tensorboard/tensorboard_testing/"
)

LOGGER_PATH = OUTPUT_PATH + "/" + MODEL_NAME + '.log'
LOGGER_PATH = f"{OUTPUT_PATH}/{MODEL_NAME}.log"

logger = Logger(MODEL_NAME, LOGGER_PATH).get_logger()
test_logger = Logger(MODEL_NAME + '_test', LOGGER_PATH).get_logger()
test_logger = Logger(f'{MODEL_NAME}_test', LOGGER_PATH).get_logger()
wandb = None
if str(args.wandb).lower() == "true":
import wandb
Expand All @@ -207,7 +214,9 @@


# Model
model = torch.nn.DataParallel(getModel(args.model, OUTPUT_PATH + "/" + MODEL_NAME))
model = torch.nn.DataParallel(
getModel(args.model, f"{OUTPUT_PATH}/{MODEL_NAME}")
)
model.cuda()

writer_training = SummaryWriter(TENSORBOARD_PATH_TRAINING)
Expand Down
53 changes: 22 additions & 31 deletions pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self, cmd_args, model, logger, dir_path, checkpoint_path, writer_tr
self.MODEL_NAME = cmd_args.model_name
self.model_type = cmd_args.model
self.lr_1 = cmd_args.learning_rate
self.logger.info("learning rate " + str(self.lr_1))
self.logger.info(f"learning rate {str(self.lr_1)}")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Pipeline.__init__ refactored with the following changes:

# self.optimizer = torch.optim.Adam(model.parameters(), lr=cmd_args.learning_rate)
self.optimizer = Madam(model.parameters(), lr=cmd_args.learning_rate)
self.num_epochs = cmd_args.num_epochs
Expand Down Expand Up @@ -117,30 +117,25 @@ def create_TIOSubDS(self, vol_path, label_path, crossvalidation_set=None, is_tra
get_subjects_only=False,
transforms=None):
if is_train:
trainDS = SRDataset(logger=self.logger, patch_size=self.patch_size,
dir_path=vol_path,
label_dir_path=label_path,
# TODO: implement non-iso patch-size, now only using the first element
stride_depth=self.stride_depth, stride_length=self.stride_length,
stride_width=self.stride_width, Size=None, fly_under_percent=None,
# TODO: implement fly_under_percent, if needed
patch_size_us=self.patch_size, pre_interpolate=None, norm_data=False,
pre_load=True,
return_coords=True,
files_us=crossvalidation_set) # TODO implement patch_size_us if required - patch_size//scaling_factor
if get_subjects_only:
return trainDS
# sampler = tio.data.UniformSampler(self.patch_size)
# patches_queue = tio.Queue(
# trainDS,
# max_length=(self.samples_per_epoch // len(trainDS.pre_loaded_data['pre_loaded_img'])) * 2,
# samples_per_volume=1,
# sampler=sampler,
# num_workers=0,
# start_background=True
# )
# return patches_queue
return trainDS
return SRDataset(
logger=self.logger,
patch_size=self.patch_size,
dir_path=vol_path,
label_dir_path=label_path,
# TODO: implement non-iso patch-size, now only using the first element
stride_depth=self.stride_depth,
stride_length=self.stride_length,
stride_width=self.stride_width,
Size=None,
fly_under_percent=None,
# TODO: implement fly_under_percent, if needed
patch_size_us=self.patch_size,
pre_interpolate=None,
norm_data=False,
pre_load=True,
return_coords=True,
files_us=crossvalidation_set,
)
Comment on lines -120 to +138

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function Pipeline.create_TIOSubDS refactored with the following changes:

This removes the following comments ( why? ):

#     num_workers=0,
#     max_length=(self.samples_per_epoch // len(trainDS.pre_loaded_data['pre_loaded_img'])) * 2,
# return patches_queue
# TODO implement patch_size_us if required - patch_size//scaling_factor
# )
#     start_background=True
# sampler = tio.data.UniformSampler(self.patch_size)
#     samples_per_volume=1,
# patches_queue = tio.Queue(
#     sampler=sampler,
#     trainDS,

elif is_validate:
validationDS = SRDataset(logger=self.logger, patch_size=self.patch_size,
dir_path=vol_path,
Expand Down Expand Up @@ -186,12 +181,8 @@ def create_TIOSubDS(self, vol_path, label_path, crossvalidation_set=None, is_tra

overlap = np.subtract(self.patch_size, (self.stride_length, self.stride_width, self.stride_depth))
grid_samplers = []
for i in range(len(subjects)):
grid_sampler = tio.inference.GridSampler(
subjects[i],
self.patch_size,
overlap,
)
for subject_ in subjects:
grid_sampler = tio.inference.GridSampler(subject_, self.patch_size, overlap)
grid_samplers.append(grid_sampler)
return torch.utils.data.ConcatDataset(grid_samplers)

Expand Down