def __init__(self, server_env=False): ######################### # Preprocessing # ######################### self.root_dir = '/home/matthew/datasets/platelet-instance-3d' self.min_volume = 100 ######################### # I/O # ######################### # Either 'cell' or 'organelle' self.label_type = 'organelle' # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn']. self.model = 'mrcnn' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. self.select_prototype_subset = None self.hold_out_test_set = True # including val set. will be 3/4 train, 1/4 val. self.n_train_val_data = 1 # path to preprocessed data. self.input_df_name = 'info_df.pickle' self.pp_name = os.path.join('mdt', self.label_type, 'train') self.pp_data_path = os.path.join(self.root_dir, self.pp_name) self.pp_test_name = os.path.join('mdt', self.label_type, 'test') self.pp_test_data_path = os.path.join(self.root_dir, self.pp_test_name) # settings for deployment in cloud. if server_env: # path to preprocessed data. pp_root_dir = '/datasets/datasets_ramien/toy_exp/data' self.pp_name = os.path.join('mdt', self.label_type, 'train') self.pp_data_path = os.path.join(pp_root_dir, self.pp_name) self.pp_test_name = os.path.join('mdt', self.label_type, 'test') self.pp_test_data_path = os.path.join(pp_root_dir, self.pp_test_name) self.select_prototype_subset = None ######################### # Data Loader # ######################### # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_3D = [288, 288, 40] self.patch_size_3D = [288, 288, 40] self.patch_size = self.patch_size_3D self.pre_crop_size = self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.2 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = False # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = None if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 24 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101', 'resnet50' self.norm = None # one of None, 'instance_norm', 'batch_norm' # 0 for no weight decay self.weight_decay = 3e-8 # which weights to exclude from weight decay, options: ["norm", "bias"]. self.exclude_from_wd = ("norm", ) # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (= default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### self.num_epochs = 60 self.num_train_batches = 50 self.batch_size = 1 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is more accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': self.max_val_patients = None # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': self.num_val_batches = 8 # set dynamic_lr_scheduling to True to apply LR scheduling with below settings. self.dynamic_lr_scheduling = True self.lr_decay_factor = 0.7 self.scheduling_patience = np.ceil( 7200 / (self.num_train_batches * self.batch_size)) self.scheduling_criterion = 'all_ap' self.scheduling_mode = 'min' if "loss" in self.scheduling_criterion else 'max' ######################### # Testing / Plotting # ######################### # set the top-n epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' self.class_dict = {1: 'all'} # 0 is background. self.patient_class_of_interest = 1 # patient metrics are only plotted for one class. self.ap_match_ious = [0.1, 0.5, 0.7, 0.8, 0.9 ] # list of ious to be evaluated for ap-scoring. self.model_selection_criteria = [ 'all_ap' ] # criteria to average over for saving epochs. self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. # threshold for clustering predictions together (wcs = weighted cluster scoring). # needs to be >= the expected overlap of predictions coming from one model (typically NMS threshold). # if too high, preds of the same object are separate clusters. self.wcs_iou = 1e-2 self.plot_prediction_histograms = True self.plot_stat_curves = True ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 150.), 'sigma': (10., 30.), 'do_rotation': False, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': False, 'scale': (0.8, 1.1), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### { 'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=None): ######################### # Preprocessing # ######################### self.root_dir = '../../../Moscow_NRRD_Output' # self.root_dir = '/path/to/raw/data' self.raw_data_dir = '{}/nrrd_file'.format(self.root_dir) self.pp_dir_preq = '../../../Moscow_NRRD_Full-Numpy' self.pp_dir = '{}/pp_norm'.format(self.pp_dir_preq) # self.pp_dir = '{}/pp_norm'.format(self.root_dir) self.target_spacing = (0.7, 0.7, 1.25) ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn', 'detection_unet']. self.model = 'retina_net' # self.model = 'mrcnn' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. If None, all data is used. self.select_prototype_subset = None # path to preprocessed data. self.pp_name = 'pp_norm' self.input_df_name = 'info_df.pickle' self.pp_data_path = '../Moscow_NRRD_Full-Numpy/{}'.format(self.pp_name) # self.pp_data_path = '/path/to/preprocessed/data/{}'.format(self.pp_name) self.pp_test_data_path = self.pp_data_path #change if test_data in separate folder. # settings for deployment in cloud. if server_env: # path to preprocessed data. self.pp_name = 'pp_fg_slices' self.crop_name = 'pp_fg_slices_packed' self.pp_data_path = '/path/to/preprocessed/data/{}/{}'.format( self.pp_name, self.crop_name) self.pp_test_data_path = self.pp_data_path self.select_prototype_subset = None ######################### # Data Loader # ######################### # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [300, 300] self.patch_size_2D = [288, 288] self.pre_crop_size_3D = [156, 156, 96] self.patch_size_3D = [128, 128, 64] self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.1 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = True # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = None if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 18 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = None # one of None, 'instance_norm', 'batch_norm' self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### # self.num_epochs = 150 # self.num_epochs = 2 ##### debug self.num_epochs = 100 # self.num_epochs = 5 self.num_train_batches = 80 # self.num_train_batches = 1 # self.num_train_batches = 200 if self.dim == 2 else 200 self.batch_size = 32 if self.dim == 2 else 15 # self.batch_size = 2 ##### debug self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is morge accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': # self.max_val_patients = 50 self.max_val_patients = 1 # self.max_val_patients = 2 # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': # self.num_val_batches = 50 # self.num_val_batches = 2 self.max_val_patients = 1 ######################### # Testing / Plotting # ######################### # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' self.class_dict = {1: 'truenod'} # 0 is background. self.patient_class_of_interest = 1 # patient metrics are only plotted for one class. self.ap_match_ious = [0.1 ] # list of ious to be evaluated for ap-scoring. self.model_selection_criteria = [ 'truenod_ap' ] # criteria to average over for saving epochs. self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. # threshold for clustering predictions together (wcs = weighted cluster scoring). # needs to be >= the expected overlap of predictions coming from one model (typically NMS threshold). # if too high, preds of the same object are separate clusters. self.wcs_iou = 1e-5 self.plot_prediction_histograms = True self.plot_stat_curves = True ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 1500.), 'sigma': (30., 50.), 'do_rotation': True, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale': (0.8, 1.1), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### { 'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, }[self.model]()
def __init__(self): self.gpu = '4' os.environ['CUDA_VISIBLE_DEVICES'] = self.gpu ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'seg_mrcnn','retina_net', 'retina_unet', 'detection_unet', 'ufrcnn', 'detection_unet']. self.model = 'mrcnn' DefaultConfigs.__init__(self, self.model, self.dim) # path to preprocessed data. self.pp_name = 'abus_npy' self.input_df_name = 'info_df.pickle' self.input_id_name = 'fold_ids.pickle' self.pid_pth = 'fold_ids.txt' self.pp_data_path = '/shenlab/lab_stor6/yuezhou/ABUSdata/{}/'.format( self.pp_name) self.pp_test_data_path = self.pp_data_path #change if test_data in separate folder. ######################### # Data Loader # ######################### # data aug in training self.data_aug_training = False # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. #self.pre_crop_size_2D = [300, 300] #self.patch_size_2D = [288, 288] if self.data_aug_training == True: self.pre_crop_size_3D = [72, 144, 144] else: self.pre_crop_size_3D = [64, 128, 128] self.patch_size_3D = [64, 128, 128] #[128, 128, 64] self.patch_size = self.patch_size_3D #self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_3D #self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.5 #0.2 ######################### # Architecture # ######################### self.backbone_path = 'models/backbone_vnet.py' self.multi_scale_det = False self.start_filts = 48 if self.dim == 2 else 18 if 'vnet' in self.backbone_path: if self.multi_scale_det == False: self.end_filts = [32, 64, 128, 256, 256] else: self.end_filts = [ 36, 36, 36, 36, 36 ] #self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 if 'fpn' in self.backbone_path: self.end_filts = [ 36, 36, 36, 36, 36 ] #self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = None # one of None, 'instance_norm', 'batch_norm' self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### self.debug = 0 if self.debug == 1: self.num_epochs = 2 self.num_train_batches = 2 #2 if self.dim == 2 else 2 self.batch_size = 2 #20 if self.dim == 2 else 2 self.n_workers = 1 else: self.num_epochs = 250 self.num_train_batches = 200 if self.dim == 2 else 200 self.batch_size = 20 if self.dim == 2 else 2 self.n_workers = 16 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is morge accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # this is a bug only sampling one of 'val_sampling' , 'val_patient' if self.debug == 1: self.num_val_batches = 2 else: self.num_val_batches = None self.new_data = True self.text_for_next = False ######################### # loss # ######################### # in ['BCE','roiDice','mapDice'] self.mask_loss_flag = 'BCE' # in ['seg-only','mrcnn-only','frcnn-only','mrcnn-seg','frcnn-seg','mrcnn-seg-fusion'] self.loss_flag = 'mrcnn-seg-fusion' ######################### # fusion method # ######################### #fusion in prob or feature self.fusion_prob_feature = 'prob' # in ['cat-only','add-only','weight-cat','weight-add'] self.fusion_method = 'weight-add' # in ['before','after'] self.fusion_feature_method = 'after' #fusion conoral number self.fusion_conv_num = 'no' #'no' or 'more' or 'less' or 'one' ######################### # Testing / Plotting # ######################### # show detection box score self.show_det_source_th = 0.1 # patch stride during testing self.testing_patch_stride = [64, 128, 128] # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 self.testing_epoch_num = 0 # test the best epoch or the last epoch self.test_last_epoch = False # show image if self.debug == 1: self.show_train_images = 1 self.show_val_images = 1 else: self.show_train_images = 5 self.show_val_images = 5 #select detected box score #self.source_th = 0.1 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' self.class_dict = { 1: 'mass' } #{1: 'benign', 2: 'malignant'} # 0 is background. self.patient_class_of_interest = 1 # patient metrics are only plotted for one class. self.ap_match_ious = [0.1 ] # list of ious to be evaluated for ap-scoring. #['val_dice_seg','val_dice_mask','val_dice_fusion']#criteria to average over for saving epochs. if 'seg' in self.loss_flag and 'seg-only' not in self.loss_flag: self.model_selection_criteria = [ 'val_dice_fusion' ] #criteria to average over for saving epochs. if 'seg-only' in self.loss_flag: self.model_selection_criteria = ['val_deice_seg'] if 'seg' not in self.loss_flag: self.model_selection_criteria = ['val_precision', 'val_recall'] self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 1500.), 'sigma': (30., 50.), 'do_rotation': True, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale': (0.8, 1.1), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### { 'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=None): ######################### # Preprocessing # ######################### self.root_dir = '/media/gregor/HDD2TB/data/toy_mdt' ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 2 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn', 'detection_unet']. self.model = 'mrcnn' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. self.select_prototype_subset = None self.hold_out_test_set = True self.n_train_data = 2500 # choose one of the 3 toy experiments described in https://arxiv.org/pdf/1811.08661.pdf # one of ['donuts_shape', 'donuts_pattern', 'circles_scale']. toy_mode = 'donuts_shape_nonoise_dia12' # path to preprocessed data. self.input_df_name = 'info_df.pickle' self.pp_name = os.path.join(toy_mode, 'train') self.pp_data_path = os.path.join(self.root_dir, self.pp_name) self.pp_test_name = os.path.join(toy_mode, 'test') self.pp_test_data_path = os.path.join(self.root_dir, self.pp_test_name) # settings for deployment in cloud. if server_env: # path to preprocessed data. pp_root_dir = '/datasets/datasets_ramien/toy_exp/data' self.pp_name = os.path.join(toy_mode, 'train') self.pp_data_path = os.path.join(pp_root_dir, self.pp_name) self.pp_test_name = os.path.join(toy_mode, 'test') self.pp_test_data_path = os.path.join(pp_root_dir, self.pp_test_name) self.select_prototype_subset = None ######################### # Data Loader # ######################### # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [320, 320] self.patch_size_2D = [320, 320] self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.2 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = False # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = None if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 18 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = None # one of None, 'instance_norm', 'batch_norm' self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### self.num_epochs = 24 self.num_train_batches = 100 if self.dim == 2 else 200 self.batch_size = 20 if self.dim == 2 else 8 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is morge accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_patient' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': self.max_val_patients = None # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': self.num_val_batches = 50 ######################### # Testing / Plotting # ######################### # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' self.class_dict = {1: 'benign', 2: 'malignant'} # 0 is background. self.patient_class_of_interest = 2 # patient metrics are only plotted for one class. self.ap_match_ious = [0.1 ] # list of ious to be evaluated for ap-scoring. self.model_selection_criteria = [ 'benign_ap', 'malignant_ap' ] # criteria to average over for saving epochs. self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. # threshold for clustering predictions together (wcs = weighted cluster scoring). # needs to be >= the expected overlap of predictions coming from one model (typically NMS threshold). # if too high, preds of the same object are separate clusters. self.wcs_iou = 1e-5 self.plot_prediction_histograms = True self.plot_stat_curves = False ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 1500.), 'sigma': (30., 50.), 'do_rotation': True, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale': (0.8, 1.1), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### { 'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'ufrcnn_surrounding': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, 'prob_detector': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=False): #Change some things if debugging #Set always to false, it is set to true by others self.debugging = False ######################### # Preprocessing # ######################### #Already done! self.root_dir = r'../' #self.raw_data_dir = os.path.join(self.root_dir, './') self.pp_dir = os.path.join(self.root_dir, 'out') self.target_spacing = (0.5, 0.5, 3.) ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn']. # Only retina_unet can be used with the current model setup self.model = 'retina_unet' self.model_path = '././' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. If None, all data is used. self.select_prototype_subset = None # path to preprocessed data. self.pp_name = 'out' self.input_df_name = 'info_df.pickle' self.pp_data_path = os.path.join(self.root_dir, self.pp_name) self.pp_test_data_path = self.pp_data_path #change if test_data in separate folder. # settings for deployment in cloud. if server_env: # path to preprocessed data. self.pp_name = '' self.crop_name = '' self.pp_data_path = '' self.pp_test_data_path = self.pp_data_path self.select_prototype_subset = None ######################### # Data Loader # ######################### #Use a single CV split self.n_cv_splits = 5 # select modalities from preprocessed data self.channels = list(range(8)) self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [160, 160] self.patch_size_2D = [160, 160] self.pre_crop_size_3D = [160, 160, 24] self.patch_size_3D = [160, 160, 24] self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.2 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = self.dim == 2 # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = 3 if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 15 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.n_blocks = [3, 7, 21, 3] #[3, 4, 23, 3] 'resnet101' self.norm = 'batch_norm' # one of None, 'instance_norm', 'batch_norm' # 0 for no weight decay self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### self.num_epochs = 115 #99 self.num_train_batches = 120 if self.dim == 2 else 120 self.batch_size = 20 if self.dim == 2 else 6 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is more accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': self.max_val_patients = 50 # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': self.num_val_batches = 50 self.optimizer = "Adam" # set dynamic_lr_scheduling to True to apply LR scheduling with below settings. self.dynamic_lr_scheduling = False self.lr_decay_factor = 0.25 self.scheduling_patience = np.ceil( 16000 / (self.num_train_batches * self.batch_size)) self.scheduling_criterion = 'malignant_ap' self.scheduling_mode = 'min' if "loss" in self.scheduling_criterion else 'max' ######################### # Testing / Plotting # ######################### # General matching IOU self.match_iou = 1e-5 # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 # If true, all epochs (not only best k) are kept self.keep_all_epochs = False # use 'train', 'val' or 'test' data for testing self.test_subset = 'test' # Drop some channels during test? #T2:[0], B500,B800+,ADC:[1,2,3], ktrans:[4], Perf:[5,6,7] self.drop_channels_test = [] # use a temporal ensemble of a list of epochs, or None, to use instead the best validation cps def steps(start, end, n): if n < 2: raise Exception("Behaviour not defined for n<2") step = (end - start) / float(n - 1) return [int(round(start + x * step)) for x in range(n)] self.test_checkpoints = None #steps(25, self.num_epochs, self.test_n_epochs) # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.scan_det_thresh = False #Used in evaluator > return_metrics self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' self.class_dict = { 1: 'benign', 2: 'GGG_1', 3: 'GGG_2', 4: 'GGG_3' } # 0 is background. self.patient_class_of_interest = 3 # patient metrics are only plotted for one class. self.ap_match_ious = [self.match_iou ] # list of ious to be evaluated for ap-scoring. # criteria to average over for saving epochs. self.model_selection_criteria = [ 'GGG_%d_%s' % (g, metric) for g in range(1, 4) for metric in ['ap'] ] + ['benign_ap'] self.min_det_thresh = 0. # minimum confidence value to select predictions for evaluation. #Use prostatex test set too with masked classification loss? self.use_prostatex_test = True # evaluates average precision per image and averages over images. instead computing one ap over data set. self.per_patient_ap = False # threshold for clustering 2D box predictions to 3D Cubes. Overlap is computed in XY. self.merge_3D_iou = self.match_iou #Custom dict preprocessing function to transform classes 10,1 -> 0, 2,3,4,5 -> 1, 20 -> 20 #Please note that class 20 is a very special class for which bce loss is masked! #correspondance_dict= {0:0, 10:0, 1:0, 2:1, 3:1, 4:1, 5:1, 20:20} correspondance_dict = { 0: 0, 10: 0, 1: 1, 2: 2, 3: 3, 4: 3, 5: 3, 20: 20 } def modify_class_target(class_targets): return [correspondance_dict[target] for target in class_targets] self.modify_class_target_fn = modify_class_target # threshold for clustering predictions together (wcs = weighted cluster scoring). # needs to be >= the expected overlap of predictions coming from one model (typically NMS threshold). # if too high, preds of the same object are separate clusters. self.wcs_iou = 1e-5 self.plot_prediction_histograms = False self.plot_stat_curves = False # if True, test data lies in a separate folder and is not part of the cross validation. self.hold_out_test_set = True # if hold_out_test_set provided, ensemble predictions over models of all trained cv-folds. # implications for hold-out test sets: if True, evaluate folds separately on the test set, aggregate only the # evaluations. if False, aggregate the raw predictions across all folds, then evaluate. self.ensemble_folds = True ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 300.), 'sigma': (20., 40.), 'do_rotation': True, 'angle_x': (-np.pi / 30., np.pi / 30), 'angle_y': (-np.pi / 20., np.pi / 20) if self.dim == 2 else (0., 0.), #must be 0!! 'angle_z': (-np.pi / 20., np.pi / 20), 'do_scale': True, 'scale': (1 / 1.15, 1.15), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 3 } self.test_aug = False #Seems to be true by default self.mirror_axes = (1, ) #Custom augmentation: drop a channel with some prob #Do not drop T2 nor final channels & consider perfusion channels as one # 0:T2, 1:B500, 2:B800, 3:ADC, 4:ktrans, # 5:Prostate mask, 6:CZ mask, 7: PZ mask self.droppable_channels = [[1], [2], [3], [4]] self.channel_drop_p = 0.05 ######################### # Add model specifics # ######################### { 'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, 'retina_unet_coral': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=None): ######################### # Preprocessing # ######################### self.root_dir = '/home/gregor/datasets/toy_mdt' ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 2 DefaultConfigs.__init__(self, server_env, self.dim) # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn']. self.model = 'mrcnn' self.model_path = 'models/{}.py'.format(self.model if not 'retina' in self.model else 'retina_net') self.model_path = os.path.join(self.source_dir, self.model_path) # int [0 < dataset_size]. select n patients from dataset for prototyping. self.select_prototype_subset = None self.hold_out_test_set = True # including val set. will be 3/4 train, 1/4 val. self.n_train_val_data = 2500 # choose one of the 3 toy experiments described in https://arxiv.org/pdf/1811.08661.pdf # one of ['donuts_shape', 'donuts_pattern', 'circles_scale']. toy_mode = 'donuts_shape_noise' # path to preprocessed data. self.info_df_name = 'info_df.pickle' self.pp_name = os.path.join(toy_mode, 'train') self.data_sourcedir = os.path.join(self.root_dir, self.pp_name) self.pp_test_name = os.path.join(toy_mode, 'test') self.test_data_sourcedir = os.path.join(self.root_dir, self.pp_test_name) # settings for deployment in cloud. if server_env: # path to preprocessed data. pp_root_dir = '/datasets/datasets_ramien/toy_exp/data' self.pp_name = os.path.join(toy_mode, 'train') self.data_sourcedir = os.path.join(pp_root_dir, self.pp_name) self.pp_test_name = os.path.join(toy_mode, 'test') self.test_data_sourcedir = os.path.join(pp_root_dir, self.pp_test_name) self.select_prototype_subset = None ######################### # Data Loader # ######################### # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) self.plot_bg_chan = 0 # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [320, 320] self.patch_size_2D = [320, 320] self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_random_ratio = 0.2 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = False ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 18 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = "instance_norm" # one of None, 'instance_norm', 'batch_norm' # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = "xavier_uniform" # compatibility self.regression_n_features = 1 self.num_classes = 2 # excluding bg self.num_seg_classes = 3 # incl bg ######################### # Schedule / Selection # ######################### self.num_epochs = 26 self.num_train_batches = 100 if self.dim == 2 else 200 self.batch_size = 20 if self.dim == 2 else 8 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is morge accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_patient' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': self.max_val_patients = "all" # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': self.num_val_batches = 50 self.optimizer = "ADAMW" # set dynamic_lr_scheduling to True to apply LR scheduling with below settings. self.dynamic_lr_scheduling = True self.lr_decay_factor = 0.25 self.scheduling_patience = np.ceil(4800 / (self.num_train_batches * self.batch_size)) self.scheduling_criterion = 'donuts_ap' self.scheduling_mode = 'min' if "loss" in self.scheduling_criterion else 'max' self.weight_decay = 1e-5 self.exclude_from_wd = ["norm"] self.clip_norm = 200 ######################### # Testing / Plotting # ######################### self.ensemble_folds = False # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 self.test_aug_axes = (0, 1, (0, 1)) self.n_test_plots = 2 self.clustering = "wbc" self.clustering_iou = 1e-5 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois'] # choose list from 'patient', 'rois' self.class_labels = [Label(0, 'bg', (*self.white, 0.)), Label(1, 'circles', (*self.orange, .9)), Label(2, 'donuts', (*self.blue, .9)),] if self.class_specific_seg: self.seg_labels = self.class_labels self.box_type2label = {label.name: label for label in self.box_labels} self.class_id2label = {label.id: label for label in self.class_labels} self.class_dict = {label.id: label.name for label in self.class_labels if label.id != 0} self.seg_id2label = {label.id: label for label in self.seg_labels} self.cmap = {label.id: label.color for label in self.seg_labels} self.metrics = ["ap", "auc", "dice"] self.patient_class_of_interest = 2 # patient metrics are only plotted for one class. self.ap_match_ious = [0.1] # list of ious to be evaluated for ap-scoring. self.model_selection_criteria = {name + "_ap": 1. for name in self.class_dict.values()}# criteria to average over for saving epochs. self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. self.plot_prediction_histograms = True self.plot_stat_curves = False self.plot_class_ids = True ######################### # Data Augmentation # ######################### self.do_aug = False self.da_kwargs={ 'do_elastic_deform': True, 'alpha':(0., 1500.), 'sigma':(30., 50.), 'do_rotation':True, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale':(0.8, 1.1), 'random_crop':False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### {'detection_fpn': self.add_det_fpn_configs, 'mrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=False): ######################### # Predictions # ######################### self.patient_path = None self.output_dir = None ######################### # Preprocessing # ######################### datasets_dir = os.getenv('MDT_DATASETS_DIR') self.root_dir = os.path.join(datasets_dir, 'MDT-LIDC-IDRI') self.raw_data_dir = f'{self.root_dir}/NRRDs' self.pp_dir = os.path.join(datasets_dir, 'MDT-PP') self.target_spacing = (0.7, 0.7, 1.25) ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn']. self.model = 'retina_unet' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. If None, all data is used. self.select_prototype_subset = None # path to preprocessed data. self.pp_name = 'lidc_mdt' self.input_df_name = 'info_df.pickle' self.pp_data_path = self.pp_dir self.pp_test_data_path = self.pp_data_path #change if test_data in separate folder. # settings for deployment in cloud. if server_env: # path to preprocessed data. self.pp_name = 'lidc_mdt_npz' self.crop_name = 'pp_fg_slices_packed' self.pp_data_path = '/datasets/datasets_ramien/lidc_exp/data/{}'.format( self.pp_name) self.pp_test_data_path = self.pp_data_path self.select_prototype_subset = None ######################### # Data Loader # ######################### self.gan_dataset = False self.train_set_proportion = 1.0 self.n_cv_splits = 10 # 10 to split data 80 train - 10 val - 10 test # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [300, 300] self.patch_size_2D = [288, 288] self.pre_crop_size_3D = [156, 156, 96] self.patch_size_3D = [128, 128, 64] self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.2 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = self.dim == 2 # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = None if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 18 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = None # one of None, 'instance_norm', 'batch_norm' # 0 for no weight decay self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### self.num_epochs = 50 self.num_train_batches = 200 if self.dim == 2 else 200 self.batch_size = 20 if self.dim == 2 else 10 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is more accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': self.max_val_patients = 50 # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': self.num_val_batches = 25 self.optimizer = "Adam" # set dynamic_lr_scheduling to True to apply LR scheduling with below settings. self.dynamic_lr_scheduling = False self.lr_decay_factor = 0.25 self.scheduling_patience = np.ceil( 16000 / (self.num_train_batches * self.batch_size)) self.scheduling_criterion = 'malignant_ap' self.scheduling_mode = 'min' if "loss" in self.scheduling_criterion else 'max' ######################### # Testing / Plotting # ######################### # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' #self.class_dict = {1: 'benign', 2: 'malignant'} # 0 is background. #self.patient_class_of_interest = 2 # patient metrics are only plotted for one class. self.class_dict = {1: 'nodule'} # 1 output class self.patient_class_of_interest = 1 self.ap_match_ious = [0.1 ] # list of ious to be evaluated for ap-scoring. self.model_selection_criteria = [ 'nodule_ap' ] # ['malignant_ap', 'benign_ap'] # criteria to average over for saving epochs. self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. # threshold for clustering predictions together (wcs = weighted cluster scoring). # needs to be >= the expected overlap of predictions coming from one model (typically NMS threshold). # if too high, preds of the same object are separate clusters. self.wcs_iou = 1e-5 self.plot_prediction_histograms = True self.plot_stat_curves = True ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 1500.), 'sigma': (30., 50.), 'do_rotation': True, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale': (0.8, 1.1), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### { 'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=None): ######################### # Preprocessing # ######################### self.root_dir = '/path/to/raw/data' self.raw_data_dir = '{}/data_nrrd'.format(self.root_dir) self.pp_dir = '{}/pp_norm'.format(self.root_dir) self.target_spacing = (0.7, 0.7, 1.25) ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'generic_unet', 'ufrcnn', 'probabilistic_unet']. self.model = 'generic_unet' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. If None, all data is used. self.select_prototype_subset = None # path to preprocessing data. self.pp_name = 'pp_norm' self.input_df_name = 'info_df.pickle' self.pp_data_path = '/path/to/preprocessing/data/{}'.format( self.pp_name) self.pp_test_data_path = self.pp_data_path #change if test_data in separate folder. # settings for deployment in cloud. if server_env: # path to preprocessing data. self.pp_name = 'pp_fg_slices' self.crop_name = 'pp_fg_slices_packed' self.pp_data_path = '/path/to/preprocessing/data/{}/{}'.format( self.pp_name, self.crop_name) self.pp_test_data_path = self.pp_data_path self.select_prototype_subset = None ######################### # Data Loader # ######################### # select modalities from preprocessing data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [300, 300] self.patch_size_2D = [288, 288] self.pre_crop_size_3D = [156, 156, 96] self.patch_size_3D = [128, 128, 64] self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.2 # set 2D net to operate in 3D images. self.merge_2D_to_3D_preds = True # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = None if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Data Analysis # ######################### # be set to background if the volume is less than X times of the minimum volume of # that class in the training data self.MIN_SIZE_PER_CLASS_FACTOR = 0.5 self.TARGET_SPACING_PERCENTILE = 50 self.FEATUREMAP_MIN_EDGE_LENGTH_BOTTLENECK = 4 self.FEATUREMAP_MIN_EDGE_LENGTH_BOTTLENECK2 = 6 # z is defined as the axis with the highest spacing, also used to # determine whether to use 2d or 3d data augmentation self.RESAMPLING_SEPARATE_Z_ANISOTROPY_THRESHOLD = 3 # 1/4 of a patient self.HOW_MUCH_OF_A_PATIENT_MUST_THE_NETWORK_SEE_AT_STAGE0 = 4 # all samples in the batch cannot cover more than 5% of the entire dataset self.batch_size_covers_max_percent_of_dataset = 0.05 # minimum batch size >= 2 self.dataset_min_batch_size_cap = 2 ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 18 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = None # one of None, 'instance_norm', 'batch_norm' self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None ######################### # Schedule / Selection # ######################### self.num_epochs = 100 self.num_train_batches = 200 if self.dim == 2 else 200 self.batch_size = 20 if self.dim == 2 else 8 self.do_validation = True # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is morge accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': self.max_val_patients = 50 # if 'None' iterates over entire val_set once. if self.val_mode == 'val_sampling': self.num_val_batches = 50 ######################### # Testing / Plotting # ######################### # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 5 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.report_score_level = ['patient', 'rois' ] # choose list from 'patient', 'rois' self.class_dict = {1: 'benign', 2: 'malignant'} # 0 is background. self.patient_class_of_interest = 2 # patient metrics are only plotted for one class. self.ap_match_ious = [0.1 ] # list of ious to be evaluated for ap-scoring. self.model_selection_criteria = [ 'malignant_ap', 'benign_ap' ] # criteria to average over for saving epochs. self.min_det_thresh = 0.1 # minimum confidence value to select predictions for evaluation. # threshold of wcs (weighted cluster scoring), used for clustering predictions together. # needs to be >= the expected overlap of predictions coming from one model.(typically NMS threshold). self.wcs_iou = 1e-5 self.plot_prediction_histograms = True self.plot_stat_curves = False ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 1500.), 'sigma': (30., 50.), 'do_rotation': True, 'angle_x': (0., 2 * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale': (0.8, 1.1), 'random_crop': False, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['do_elastic_deform'] = False self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) #must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) self.aug_3D_kwargs = { "selected_data_channels": None, "selected_seg_channels": None, "do_elastic": True, "elastic_deform_alpha": (0., 900.), "elastic_deform_sigma": (9., 13.), "do_scaling": True, "scale_range": (0.85, 1.25), "do_rotation": True, "rotation_x": (-15. / 360 * 2. * np.pi, 15. / 360 * 2. * np.pi), "rotation_y": (-15. / 360 * 2. * np.pi, 15. / 360 * 2. * np.pi), "rotation_z": (-15. / 360 * 2. * np.pi, 15. / 360 * 2. * np.pi), "random_crop": False, "random_crop_dist_to_border": None, "do_gamma": True, "gamma_retain_stats": True, "gamma_range": (0.7, 1.5), "p_gamma": 0.3, "num_threads": 12, "num_cached_per_thread": 1, "mirror": True, "mirror_axes": (0, 1, 2), "p_eldef": 0.2, "p_scale": 0.2, "p_rot": 0.2, "dummy_2D": False, "mask_was_used_for_normalization": False, "all_segmentation_labels": None, # used for pyramid "move_last_seg_chanel_to_data": False, # used for pyramid "border_mode_data": "constant", "advanced_pyramid_augmentations": False # used for pyramid } self.aug_2D_kwargs = deepcopy(self.aug_3D_kwargs) self.aug_2D_kwargs["elastic_deform_alpha"] = (0., 200.) self.aug_2D_kwargs["elastic_deform_sigma"] = (9., 13.) self.aug_2D_kwargs["rotation_x"] = (-180. / 360 * 2. * np.pi, 180. / 360 * 2. * np.pi) # according to unsupported 3d data augmentation, transfer 3d data into 2d data and # transform them back after augmentation self.aug_2D_kwargs["dummy_2D"] = False self.aug_2D_kwargs["mirror_axes"] = ( 0, 1) # this can be (0, 1, 2) if dummy_2D=True ######################### # Add model specifics # ######################### { 'generic_unet': self.add_gen_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, }[self.model]()
def __init__(self, server_env=None): ######################### # Preprocessing # ######################### self.data = ["Thesis", "LiTS"] self.root_dir = '/home/rgunti/data/{}'.format(self.data[0]) self.raw_data_dir = '{}/data_raw/data/'.format(self.root_dir) self.raw_seg_dir = '{}/data_raw/seg/'.format(self.root_dir) self.pp_dir = '{}/data_pp'.format(self.root_dir) self.pp_dir_wocrop = '{}/data_pp_wocrop'.format(self.root_dir) self.pp_dir_int = '{}/data_pp_int'.format(self.root_dir) self.pp_dir_int_wocrop = '{}/data_pp_int_wocrop'.format(self.root_dir) self.target_spacing = (1.0, 1.0, 2.5) if server_env: self.root_dir = "/content/drive/My\' \'Drive/Thesis/Thesis/" self.raw_data_dir = '{}/Dataset/data/'.format(self.root_dir) self.raw_seg_dir = '{}/Dataset/seg/'.format(self.root_dir) self.pp_dir = '{}/data_pp'.format(self.root_dir) ######################### # I/O # ######################### # one out of [2, 3]. dimension the model operates in. self.dim = 3 # one out of ['mrcnn', 'retina_net', 'retina_unet', 'detection_unet', 'ufrcnn', 'decoupled_refinement']. self.model = 'retina_net' DefaultConfigs.__init__(self, self.model, server_env, self.dim) # int [0 < dataset_size]. select n patients from dataset for prototyping. If None, all data is used. self.select_prototype_subset = None self.subset_ixs = None self.subset_pids = None self.hold_out_test_set = True self.data_dest = '' # path to preprocessed data. # self.pp_name = 'data_pp' # self.pp_name = 'data_pp_int' # self.pp_name = 'data_pp_wocrop' self.pp_name = 'data_pp_int_wocrop' self.input_df_name = 'info_df.pickle' self.pp_data_path = '{}/{}/'.format(self.root_dir, self.pp_name) # change if test_data in separate folder. self.pp_test_data_path = self.pp_data_path # settings for deployment in cloud. if server_env: # path to preprocessed data. # self.pp_name = 'lidc_mdt_npz' self.crop_name = 'pp_fg_slices_packed' # self.pp_data_path = '/datasets/datasets_ramien/lidc_exp/data/{}'.format(self.pp_name) self.data_dest = '/content/' self.pp_test_data_path = self.pp_data_path self.select_prototype_subset = None ######################### # Data Loader # ######################### # select modalities from preprocessed data self.channels = [0] self.n_channels = len(self.channels) # patch_size to be used for training. pre_crop_size is the patch_size before data augmentation. self.pre_crop_size_2D = [256, 256] self.patch_size_2D = [224, 224] self.use_big_patch = 0 if self.use_big_patch: self.pre_crop_size_3D = [256, 256, 112] self.patch_size_3D = [224, 224, 96] else: self.pre_crop_size_3D = [156, 156, 96] self.patch_size_3D = [128, 128, 64] self.pre_crop_size = self.pre_crop_size_2D if self.dim == 2 else self.pre_crop_size_3D self.patch_size = self.patch_size_2D if self.dim == 2 else self.patch_size_3D # ratio of free sampled batch elements before class balancing is triggered # (>0 to include "empty"/background patches.) self.batch_sample_slack = 0.2 # self.batch_sample_slack = 0.5 if self.dim == 2 else 1.0 # set 2D network to operate in 3D images. self.merge_2D_to_3D_preds = False # feed +/- n neighbouring slices into channel dimension. set to None for no context. self.n_3D_context = None if self.n_3D_context is not None and self.dim == 2: self.n_channels *= (self.n_3D_context * 2 + 1) ######################### # Architecture # ######################### self.start_filts = 48 if self.dim == 2 else 32 self.end_filts = self.start_filts * 4 if self.dim == 2 else self.start_filts * 2 self.res_architecture = 'resnet50' # 'resnet101' , 'resnet50' self.norm = 'batch_norm' # one of None, 'instance_norm', 'batch_norm' self.weight_decay = 0 # one of 'xavier_uniform', 'xavier_normal', or 'kaiming_normal', None (=default = 'kaiming_uniform') self.weight_init = None # Path to checkpoint of an experiment. Models loads only the matching keys from net.state_dict self.pre_train_path = None ######################### # Schedule / Selection # ######################### self.num_epochs = 1200 self.num_train_batches = 50 if self.dim == 2 else 50 self.batch_size = 64 if self.dim == 2 else 1 if self.use_big_patch else 4 self.do_validation = True if self.select_prototype_subset is None else False # decide whether to validate on entire patient volumes (like testing) or sampled patches (like training) # the former is morge accurate, while the latter is faster (depending on volume size) self.val_mode = 'val_sampling' # one of 'val_sampling' , 'val_patient' if self.val_mode == 'val_patient': # if 'None' iterates over entire val_set once. self.max_val_patients = None if self.val_mode == 'val_sampling': self.num_val_batches = 10 ######################### # Testing / Plotting # ######################### # set the top-n-epochs to be saved for temporal averaging in testing. self.save_n_models = 5 self.test_n_epochs = 1 # set a minimum epoch number for saving in case of instabilities in the first phase of training. self.min_save_thresh = 0 if self.dim == 2 else 0 self.test_aug = False # choose list from 'patient', 'rois' self.report_score_level = ['rois'] # self.class_dict = {1: 'benign', 2: 'malignant'} # 0 is background. self.class_dict = {1: 'lesion'} # 0 is background. # self.patient_class_of_interest = 2 # patient metrics are only plotted for one class. self.patient_class_of_interest = 1 # list of ious to be evaluated for ap-scoring. self.ap_match_ious = [0.1] # self.model_selection_criteria = ['malignant_ap', 'benign_ap'] # criteria to average over for saving epochs. self.model_selection_criteria = ['lesion_ap'] # minimum confidence value to select predictions for evaluation. self.min_det_thresh = 0 # analysis of the hyper-parameter cf.min_det_thresh, for optimization on validation set. self.scan_det_thresh = False # threshold for clustering predictions together (wcs = weighted cluster scoring). # needs to be >= the expected overlap of predictions coming from one model (typically NMS threshold). # if too high, preds of the same object are separate clusters. self.wcs_iou = 1e-5 self.plot_prediction_histograms = True self.plot_stat_curves = True ######################### # Data Augmentation # ######################### self.da_kwargs = { 'do_elastic_deform': True, 'alpha': (0., 1500.), 'sigma': (30., 50.), 'do_rotation': True, 'angle_x': (0., 0. * np.pi), 'angle_y': (0., 0), 'angle_z': (0., 0), 'do_scale': True, 'scale': (0.8, 1.2), 'random_crop': True, 'rand_crop_dist': (self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3), 'border_mode_data': 'constant', 'border_cval_data': 0, 'order_data': 1 } if self.dim == 3: self.da_kwargs['rand_crop_dist'] = ( self.patch_size[0] / 2. - 3, self.patch_size[1] / 2. - 3, self.patch_size[2] / 2. - 3) self.da_kwargs['do_elastic_deform'] = True self.da_kwargs['angle_x'] = (0, 0.0) self.da_kwargs['angle_y'] = (0, 0.0) # must be 0!! self.da_kwargs['angle_z'] = (0., 2 * np.pi) ######################### # Add model specifics # ######################### {'detection_unet': self.add_det_unet_configs, 'mrcnn': self.add_mrcnn_configs, 'ufrcnn': self.add_mrcnn_configs, 'retina_net': self.add_mrcnn_configs, 'retina_unet': self.add_mrcnn_configs, 'decoupled_refinement': self.add_mrcnn_configs, }[self.model]()