def test_segment_volume_2d(): model = imed_models.Unet(in_channel=1, out_channel=1, depth=2, drop_rate=DROPOUT, bn_momentum=BN) # temporary folder that will be deleted at the end of the test if not os.path.exists(PATH_MODEL): os.mkdir(PATH_MODEL) torch.save(model, os.path.join(PATH_MODEL, "model_test.pt")) config = { "loader_parameters": { "slice_filter_params": { "filter_empty_mask": False, "filter_empty_input": False }, "roi_params": { "suffix": None, "slice_filter_roi": 10 }, "slice_axis": "axial" }, "transformation": { "Resample": { "wspace": 0.75, "hspace": 0.75 }, "ROICrop": { "size": [48, 48] }, "RandomTranslation": { "translate": [0.03, 0.03], "applied_to": ["im", "gt"], "dataset_type": ["training"] }, "NumpyToTensor": {}, "NormalizeInstance": { "applied_to": ["im"] } }, "postprocessing": {}, "training_parameters": { "batch_size": BATCH_SIZE } } PATH_CONFIG = os.path.join(PATH_MODEL, 'model_test.json') with open(PATH_CONFIG, 'w') as fp: json.dump(config, fp) nib_lst, _ = imed_inference.segment_volume(PATH_MODEL, [IMAGE_PATH], ROI_PATH) nib_img = nib_lst[0] assert np.squeeze(nib_img.get_fdata()).shape == nib.load(IMAGE_PATH).shape assert (nib_img.dataobj.max() <= 1.0) and (nib_img.dataobj.min() >= 0.0) assert nib_img.dataobj.dtype == 'float32' shutil.rmtree(PATH_MODEL)
def test_segment_volume_2d(download_functional_test_files): model = imed_models.Unet(in_channel=1, out_channel=1, depth=2, dropout_rate=DROPOUT, bn_momentum=BN) if not PATH_MODEL.exists(): PATH_MODEL.mkdir(parents=True, exist_ok=True) torch.save(model, Path(PATH_MODEL, "model_test.pt")) config = { "loader_parameters": { "slice_filter_params": { "filter_empty_mask": False, "filter_empty_input": False }, "roi_params": { "suffix": "_seg-manual", "slice_filter_roi": 10 }, "slice_axis": "axial" }, "transformation": { "Resample": { "wspace": 0.75, "hspace": 0.75 }, "ROICrop": { "size": [48, 48] }, "RandomTranslation": { "translate": [0.03, 0.03], "applied_to": ["im", "gt"], "dataset_type": ["training"] }, "NormalizeInstance": { "applied_to": ["im"] } }, "postprocessing": {}, "training_parameters": { "batch_size": BATCH_SIZE } } PATH_CONFIG = Path(PATH_MODEL, 'model_test.json') with PATH_CONFIG.open(mode='w') as fp: json.dump(config, fp) nib_lst, _ = imed_inference.segment_volume( str(PATH_MODEL), [str(PATH_IMAGE)], options={'fname_prior': str(PATH_ROI)}) nib_img = nib_lst[0] assert np.squeeze(nib_img.get_fdata()).shape == nib.load(PATH_IMAGE).shape assert (nib_img.dataobj.max() <= 1.0) and (nib_img.dataobj.min() >= 0.0) assert nib_img.dataobj.dtype == 'float32' shutil.rmtree(PATH_MODEL)
def test_segment_volume_2d_no_prepro_transform(download_functional_test_files): model = imed_models.Unet(in_channel=1, out_channel=1, depth=2, dropout_rate=DROPOUT, bn_momentum=BN) if not PATH_MODEL.exists(): PATH_MODEL.mkdir() torch.save(model, Path(PATH_MODEL, "model_test.pt")) config = { "loader_parameters": { "slice_filter_params": { "filter_empty_mask": False, "filter_empty_input": False }, "roi_params": { "suffix": None, "slice_filter_roi": None }, "slice_axis": "axial" }, "transformation": { "NormalizeInstance": { "applied_to": ["im"] } }, "postprocessing": {}, "training_parameters": { "batch_size": BATCH_SIZE } } PATH_CONFIG = Path(PATH_MODEL, 'model_test.json') with PATH_CONFIG.open(mode='w') as fp: json.dump(config, fp) nib_lst, _ = imed_inference.segment_volume(str(PATH_MODEL), [str(PATH_IMAGE)]) nib_img = nib_lst[0] assert np.squeeze(nib_img.get_fdata()).shape == nib.load(PATH_IMAGE).shape assert (nib_img.dataobj.max() <= 1.0) and (nib_img.dataobj.min() >= 0.0) assert nib_img.dataobj.dtype == 'float32' shutil.rmtree(PATH_MODEL)
def test_inference(transforms_dict, test_lst, target_lst, roi_params, testing_params): cuda_available, device = imed_utils.define_device(GPU_ID) model_params = {"name": "Unet", "is_2d": True} loader_params = { "transforms_params": transforms_dict, "data_list": test_lst, "dataset_type": "testing", "requires_undo": True, "contrast_params": {"contrast_lst": ['T2w'], "balance": {}}, "path_data": [__data_testing_dir__], "target_suffix": target_lst, "roi_params": roi_params, "slice_filter_params": { "filter_empty_mask": False, "filter_empty_input": True }, "slice_axis": SLICE_AXIS, "multichannel": False } loader_params.update({"model_params": model_params}) # Get Testing dataset ds_test = imed_loader.load_dataset(**loader_params) test_loader = DataLoader(ds_test, batch_size=BATCH_SIZE, shuffle=False, pin_memory=True, collate_fn=imed_loader_utils.imed_collate, num_workers=0) # Undo transform val_undo_transform = imed_transforms.UndoCompose(imed_transforms.Compose(transforms_dict)) # Update testing_params testing_params.update({ "slice_axis": loader_params["slice_axis"], "target_suffix": loader_params["target_suffix"], "undo_transforms": val_undo_transform }) # Model model = imed_models.Unet() if cuda_available: model.cuda() model.eval() metric_fns = [imed_metrics.dice_score, imed_metrics.hausdorff_score, imed_metrics.precision_score, imed_metrics.recall_score, imed_metrics.specificity_score, imed_metrics.intersection_over_union, imed_metrics.accuracy_score] metric_mgr = imed_metrics.MetricManager(metric_fns) if not os.path.isdir(__output_dir__): os.makedirs(__output_dir__) preds_npy, gt_npy = imed_testing.run_inference(test_loader=test_loader, model=model, model_params=model_params, testing_params=testing_params, ofolder=__output_dir__, cuda_available=cuda_available) metric_mgr(preds_npy, gt_npy) metrics_dict = metric_mgr.get_results() metric_mgr.reset() print(metrics_dict)
def test_inference_target_suffix(download_data_testing_test_files, transforms_dict, test_lst, target_lst, roi_params, testing_params): """ This test checks if the filename(s) of the prediction(s) saved as NifTI file(s) in the pred_masks dir conform to the target_suffix or not. Thus, independent of underscore(s) in the target_suffix. As a result, _seg-axon-manual or _seg-axon_manual should yield the same filename(s). (c.f: https://github.com/ivadomed/ivadomed/issues/1135) """ cuda_available, device = imed_utils.define_device(GPU_ID) model_params = {"name": "Unet", "is_2d": True, "out_channel": 3} loader_params = { "transforms_params": transforms_dict, "data_list": test_lst, "dataset_type": "testing", "requires_undo": True, "contrast_params": {"contrast_lst": ['SEM'], "balance": {}}, "path_data": [str(Path(__data_testing_dir__, "microscopy_png"))], "bids_config": f"{path_repo_root}/ivadomed/config/config_bids.json", "target_suffix": target_lst, "extensions": [".png"], "roi_params": roi_params, "slice_filter_params": {"filter_empty_mask": False, "filter_empty_input": True}, "patch_filter_params": {"filter_empty_mask": False, "filter_empty_input": False}, "slice_axis": SLICE_AXIS, "multichannel": False } loader_params.update({"model_params": model_params}) # restructuring the dataset gt_path = f'{loader_params["path_data"][0]}/derivatives/labels/' for file_path in Path(gt_path).rglob('*.png'): src_filename = file_path.resolve() dst_filename = '_'.join(str(src_filename).rsplit('-', 1)) src_filename.rename(Path(dst_filename)) bids_df = BidsDataframe(loader_params, __tmp_dir__, derivatives=True) ds_test = imed_loader.load_dataset(bids_df, **loader_params) test_loader = DataLoader(ds_test, batch_size=BATCH_SIZE, shuffle=False, pin_memory=True, collate_fn=imed_loader_utils.imed_collate, num_workers=0) # Undo transform val_undo_transform = imed_transforms.UndoCompose(imed_transforms.Compose(transforms_dict)) # Update testing_params testing_params.update({ "slice_axis": loader_params["slice_axis"], "target_suffix": loader_params["target_suffix"], "undo_transforms": val_undo_transform }) # Model model = imed_models.Unet(out_channel=model_params['out_channel']) if cuda_available: model.cuda() model.eval() if not __output_dir__.is_dir(): __output_dir__.mkdir(parents=True, exist_ok=True) preds_npy, gt_npy = imed_testing.run_inference(test_loader=test_loader, model=model, model_params=model_params, testing_params=testing_params, ofolder=str(__output_dir__), cuda_available=cuda_available) for x in __output_dir__.iterdir(): if x.name.endswith('_pred.nii.gz'): assert x.name.rsplit('_', 1)[0].endswith(loader_params['contrast_params']['contrast_lst'][-1]), ( 'Incompatible filename(s) of the prediction(s) saved as NifTI file(s)!' )
def test_inference_2d_microscopy(download_data_testing_test_files, transforms_dict, test_lst, target_lst, roi_params, testing_params): """ This test checks if the number of NifTI predictions equals the number of test subjects on 2d microscopy data. Used to catch a bug where the last slice of the last volume wasn't appended to the prediction (see: https://github.com/ivadomed/ivadomed/issues/823) Also tests the conversions to PNG predictions when source files are not Nifti and checks if the number of PNG predictions is 2x the number of test subjects (2-class model, outputs 1 PNG per class per subject). """ cuda_available, device = imed_utils.define_device(GPU_ID) model_params = {"name": "Unet", "is_2d": True, "out_channel": 3} loader_params = { "transforms_params": transforms_dict, "data_list": test_lst, "dataset_type": "testing", "requires_undo": True, "contrast_params": {"contrast_lst": ['SEM'], "balance": {}}, "path_data": [str(Path(__data_testing_dir__, "microscopy_png"))], "bids_config": f"{path_repo_root}/ivadomed/config/config_bids.json", "target_suffix": target_lst, "extensions": [".png"], "roi_params": roi_params, "slice_filter_params": {"filter_empty_mask": False, "filter_empty_input": True}, "patch_filter_params": {"filter_empty_mask": False, "filter_empty_input": False}, "slice_axis": SLICE_AXIS, "multichannel": False } loader_params.update({"model_params": model_params}) bids_df = BidsDataframe(loader_params, __tmp_dir__, derivatives=True) # Get Testing dataset ds_test = imed_loader.load_dataset(bids_df, **loader_params) test_loader = DataLoader(ds_test, batch_size=BATCH_SIZE, shuffle=False, pin_memory=True, collate_fn=imed_loader_utils.imed_collate, num_workers=0) # Undo transform val_undo_transform = imed_transforms.UndoCompose(imed_transforms.Compose(transforms_dict)) # Update testing_params testing_params.update({ "slice_axis": loader_params["slice_axis"], "target_suffix": loader_params["target_suffix"], "undo_transforms": val_undo_transform }) # Model model = imed_models.Unet(out_channel=model_params['out_channel']) if cuda_available: model.cuda() model.eval() if not __output_dir__.is_dir(): __output_dir__.mkdir(parents=True, exist_ok=True) preds_npy, gt_npy = imed_testing.run_inference(test_loader=test_loader, model=model, model_params=model_params, testing_params=testing_params, ofolder=str(__output_dir__), cuda_available=cuda_available) assert len([x for x in __output_dir__.iterdir() if x.name.endswith(".nii.gz")]) == len(test_lst) assert len([x for x in __output_dir__.iterdir() if x.name.endswith(".png")]) == 2*len(test_lst)
def test_model_creation(): # creating basic model for test model = imed_models.Unet() torch.save(model, "testing_data/model_unet_test.pt") assert os.path.isfile("testing_data/model_unet_test.pt")