diff --git a/configs/mri-recon/mridata-3dfse-knee/motion_eval_unet_ssdu_vortex.sh b/configs/mri-recon/mridata-3dfse-knee/motion_eval_unet_ssdu_vortex.sh new file mode 100755 index 00000000..5cd25306 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/motion_eval_unet_ssdu_vortex.sh @@ -0,0 +1,18 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/motion_eval/unet_official/ssdu/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_UNET_13_Scan.yaml --auto-version --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard MODEL.WEIGHTS 3Dmridata/SSDU/model.cpkt + +# gpu=$(python get_available_gpu.py) +# echo "The first available gpu for VORTEX is $gpu" + +# # Run vortex unet yaml +# # took off --debug to allow wb to work. +# WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Aug_UNET_13_Scan.yaml --auto-version diff --git a/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Aug_UNET_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Aug_UNET_13_Scan.yaml new file mode 100644 index 00000000..a86656fd --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Aug_UNET_13_Scan.yaml @@ -0,0 +1,199 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has 1 supervised and 13 unsupervised +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 13 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: SSDU 16x mridata - loss=k_l1, uniform/loss=k_l1/version_001 + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/SSDU + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse +# For motion aug, A2R and Consistency were kept with std_dev range of 0.2 to 0.5. +# For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: + - 1 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: SSDUModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: + kind: uniform + p: 1.0 + per_example: true + rhos: 0.4 + std_scale: 4 + META_ARCHITECTURE: UnetModel + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/SSDU +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 100 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Aug_Unrolled_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Aug_Unrolled_13_Scan.yaml new file mode 100644 index 00000000..88092b05 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Aug_Unrolled_13_Scan.yaml @@ -0,0 +1,199 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has 1 supervised and 13 unsupervised +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 13 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: SSDU 16x mridata - loss=k_l1, uniform/loss=k_l1/version_001 + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/SSDU + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency were removed. +# For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: + - 1 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: SSDUModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: + kind: uniform + p: 1.0 + per_example: true + rhos: 0.4 + std_scale: 4 + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/SSDU +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 100 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Template.yaml b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Template.yaml new file mode 100644 index 00000000..8d3fa7a1 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Template.yaml @@ -0,0 +1,209 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 6 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 5 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: SSDU 16x mridata - loss=k_l1, uniform/loss=k_l1/version_001 + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/SSDU + PROJECT_NAME: '' + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + CONSISTENCY: + AUG: + MOTION: + RANGE: + - 0.2 + - 0.5 + SCHEDULER: + WARMUP_ITERS: 0 + WARMUP_METHOD: '' + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE: + MASK: + RHO: 1.0 + SCHEDULER: + WARMUP_ITERS: 0 + WARMUP_METHOD: '' + STD_DEV: + - 1 + LATENT_LOSS_NAME: mag_l1 + LATENT_LOSS_WEIGHT: 0.1 + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + NUM_LATENT_LAYERS: 1 + USE_CONSISTENCY: true + USE_LATENT: false + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: + - 1 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: SSDUModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: + kind: uniform + p: 1.0 + per_example: true + rhos: 0.4 + std_scale: 4 + META_ARCHITECTURE: UnetModel + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/SSDU +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 100 diff --git a/configs/mri-recon/mridata-3dfse-knee/old/SSDU_UNET_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_UNET_13_Scan.yaml new file mode 100644 index 00000000..5d4dc406 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_UNET_13_Scan.yaml @@ -0,0 +1,180 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has 1 supervised and 13 unsupervised +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 13 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: SSDU 16x mridata - loss=k_l1, uniform/loss=k_l1/version_001 + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/SSDU + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency were removed. +# For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel +MODEL: + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: + - 1 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: SSDUModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: + kind: uniform + p: 1.0 + per_example: true + rhos: 0.4 + std_scale: 4 + META_ARCHITECTURE: UnetModel + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/SSDU +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 100 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Unrolled_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Unrolled_13_Scan.yaml new file mode 100644 index 00000000..abf612fe --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/SSDU_Unrolled_13_Scan.yaml @@ -0,0 +1,180 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has 1 supervised and 13 unsupervised +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 13 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: SSDU 16x mridata - loss=k_l1, uniform/loss=k_l1/version_001 + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/SSDU + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency were removed. +# For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel +MODEL: + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: + - 1 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: SSDUModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: + kind: uniform + p: 1.0 + per_example: true + rhos: 0.4 + std_scale: 4 + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/SSDU +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 100 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_UNET_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_UNET_14_Scan.yaml new file mode 100644 index 00000000..d9d69b98 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_UNET_14_Scan.yaml @@ -0,0 +1,193 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has 14 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For motion aug, A2R and Consistency was implemented. +# For UNET, kept META_ARCHITECTURE is UnetModel +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: UnetModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_UNET_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_UNET_1_Scan.yaml new file mode 100644 index 00000000..f5128c0d --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_UNET_1_Scan.yaml @@ -0,0 +1,193 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has only 1 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For motion aug, A2R and Consistency was implemented. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: UnetModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_Unrolled_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_Unrolled_14_Scan.yaml new file mode 100644 index 00000000..5ddbe2fe --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_Unrolled_14_Scan.yaml @@ -0,0 +1,193 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has only 1 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For motion aug, A2R and Consistency was implemented. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: GeneralizedUnrolledCNN + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_Unrolled_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_Unrolled_1_Scan.yaml new file mode 100644 index 00000000..62348e30 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Aug_Unrolled_1_Scan.yaml @@ -0,0 +1,193 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has only 1 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For motion aug, A2R and Consistency was implemented. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: GeneralizedUnrolledCNN + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Template.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Template.yaml new file mode 100644 index 00000000..599c0f2d --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Template.yaml @@ -0,0 +1,216 @@ +# These are included in the template.yaml +# make new AUG_TEST and AUG_TRAIN like template.yaml +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false + +# Make new template.yaml that includes this stuff for the dataloader +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +# keep this +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +# keep this +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: '' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse + +# Use UNET at first for the meta architecture +# But remove motion +MODEL: + # For no motion, remove A2R and Consistency, since this is for + # motion implementation. + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + # Doesn't need this. + CONSISTENCY: + AUG: + MOTION: + RANGE: + - 0.2 + - 0.5 + SCHEDULER: + WARMUP_ITERS: 0 + WARMUP_METHOD: '' + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE: + MASK: + RHO: 1.0 + SCHEDULER: + WARMUP_ITERS: 0 + WARMUP_METHOD: '' + STD_DEV: &id001 + - 1 + LATENT_LOSS_NAME: mag_l1 + LATENT_LOSS_WEIGHT: 0.1 + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + NUM_LATENT_LAYERS: 1 + USE_CONSISTENCY: true + USE_LATENT: false + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + # just modify META_ARCHITECTURE HERE. + META_ARCHITECTURE: UnetModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_UNET_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_UNET_14_Scan.yaml new file mode 100644 index 00000000..2d41cb08 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_UNET_14_Scan.yaml @@ -0,0 +1,174 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has 14 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE is UnetModel +MODEL: + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: UnetModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_UNET_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_UNET_1_Scan.yaml new file mode 100644 index 00000000..394a66fd --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_UNET_1_Scan.yaml @@ -0,0 +1,174 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has only 1 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: UnetModel + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Unrolled_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Unrolled_14_Scan.yaml new file mode 100644 index 00000000..ac568954 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Unrolled_14_Scan.yaml @@ -0,0 +1,174 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has only 1 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: GeneralizedUnrolledCNN + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Unrolled_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Unrolled_1_Scan.yaml new file mode 100644 index 00000000..966a871c --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/Supervised_Unrolled_1_Scan.yaml @@ -0,0 +1,174 @@ +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: + - 16 +AUG_TRAIN: + MOTION_P: 0.2 + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: [] + NOISE_P: 0.2 + UNDERSAMPLE: + ACCELERATIONS: + - 16 + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + MAX_ATTEMPTS: 30 + NAME: PoissonDiskMaskFunc + USE_MOTION: false + USE_NOISE: false +CUDNN_BENCHMARK: false +# DATALOADER has only 1 supervised scan +DATALOADER: + ALT_SAMPLER: + PERIOD_SUPERVISED: 1 + PERIOD_UNSUPERVISED: 1 + DATA_KEYS: [] + DROP_LAST: true + FILTER: + BY: [] + GROUP_SAMPLER: + AS_BATCH_SAMPLER: false + BATCH_BY: [] + NUM_WORKERS: 8 + PREFETCH_FACTOR: 2 + SAMPLER_TRAIN: '' + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_TOTAL_BY_GROUP: [] + NUM_UNDERSAMPLED: 0 + NUM_VAL: -1 + NUM_VAL_BY_GROUP: [] + SEED: 1000 +DATASETS: + TEST: + - mridata_knee_2019_test + TRAIN: + - mridata_knee_2019_train + VAL: + - mridata_knee_2019_val +DESCRIPTION: + BRIEF: Aug2Recon 16x mridata baseline + ENTITY_NAME: '' + EXP_NAME: vortex/mridata_knee_3dfse/Supervised + PROJECT_NAME: 'vortex_rm' + TAGS: + - baseline + - supervised + - 16x + - mridata_knee_3dfse +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + CS: + MAX_ITER: 200 + REGULARIZATION: 0.005 + DENOISING: + META_ARCHITECTURE: GeneralizedUnrolledCNN + NOISE: + STD_DEV: *id001 + USE_FULLY_SAMPLED_TARGET: true + USE_FULLY_SAMPLED_TARGET_EVAL: null + DEVICE: cpu + M2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + META_ARCHITECTURE: GeneralizedUnrolledCNN + N2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NM2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false + NORMALIZER: + KEYWORDS: [] + NAME: TopMagnitudeNormalizer + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false + SEG: + ACTIVATION: sigmoid + CLASSES: [] + INCLUDE_BACKGROUND: false + SSDU: + MASKER: + PARAMS: {} + META_ARCHITECTURE: GeneralizedUnrolledCNN + UNET: + BLOCK_ORDER: + - conv + - relu + - conv + - relu + - batchnorm + - dropout + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NORMALIZE: false + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + UNROLLED: + BLOCK_ARCHITECTURE: ResNet + CONV_BLOCK: + ACTIVATION: relu + NORM: none + NORM_AFFINE: false + ORDER: + - norm + - act + - drop + - conv + DROPOUT: 0.0 + FIX_STEP_SIZE: false + KERNEL_SIZE: + - 3 + NUM_EMAPS: 1 + NUM_FEATURES: 256 + NUM_RESBLOCKS: 2 + NUM_UNROLLED_STEPS: 5 + PADDING: '' + SHARE_WEIGHTS: false + WEIGHTS: '' +OUTPUT_DIR: results://vortex/mridata_knee_3dfse/Supervised +SEED: 1000 +SOLVER: + BASE_LR: 0.001 + BIAS_LR_FACTOR: 1.0 + CHECKPOINT_PERIOD: -10 + GAMMA: 0.1 + GRAD_ACCUM_ITERS: 1 + LR_SCHEDULER_NAME: '' + MAX_ITER: -200 + MOMENTUM: 0.9 + OPTIMIZER: Adam + STEPS: [] + TEST_BATCH_SIZE: 24 + TRAIN_BATCH_SIZE: 24 + WARMUP_FACTOR: 0.001 + WARMUP_ITERS: 1000 + WARMUP_METHOD: linear + WEIGHT_DECAY: 0.0001 + WEIGHT_DECAY_BIAS: 0.0001 + WEIGHT_DECAY_NORM: 0.0 +TEST: + EVAL_PERIOD: -10 + EXPECTED_RESULTS: [] + FLUSH_PERIOD: 0 + VAL_AS_TEST: true + VAL_METRICS: + RECON: + - psnr + - psnr_scan + - psnr_mag + - psnr_mag_scan + - nrmse + - nrmse_scan + - nrmse_mag + - nrmse_mag_scan + - ssim (Wang) +TIME_SCALE: iter +VERSION: 1 +VIS_PERIOD: 400 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/template.yaml b/configs/mri-recon/mridata-3dfse-knee/old/template.yaml new file mode 100644 index 00000000..a62c1df8 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/template.yaml @@ -0,0 +1,36 @@ +# Shared/default properties between different configs for the 3d fse mridata knee dataset. +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: (16,) +AUG_TRAIN: + UNDERSAMPLE: + ACCELERATIONS: (16,) + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + NAME: PoissonDiskMaskFunc +MODEL: + RECON_LOSS: + NAME: "l1" + RENORMALIZE_DATA: False +DATASETS: + TRAIN: ("mridata_knee_2019_train",) + VAL: ("mridata_knee_2019_val",) + TEST: ("mridata_knee_2019_test",) +DATALOADER: + DROP_LAST: True + NUM_WORKERS: 8 +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + CHECKPOINT_PERIOD: -5000 # Checkpoint every 10 epochs + MAX_ITER: -8000 # Max number of epochs to train for +TEST: + EVAL_PERIOD: -5000 # Run validation every 10 epochs + VAL_METRICS: + RECON: ("psnr", "psnr_scan", "psnr_mag", "psnr_mag_scan", "nrmse", "nrmse_scan", "nrmse_mag", "nrmse_mag_scan", "ssim (Wang)") +TIME_SCALE: "epoch" +SEED: 1000 +VIS_PERIOD: -400 # save images every 400 iterations +VERSION: 1 +DESCRIPTION: + PROJECT_NAME: "vortex_rm" diff --git a/configs/mri-recon/mridata-3dfse-knee/old/unet.yaml b/configs/mri-recon/mridata-3dfse-knee/old/unet.yaml new file mode 100644 index 00000000..09d9c8b2 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/unet.yaml @@ -0,0 +1,17 @@ +# Configuration for DL-CS Paper +_BASE_: "template.yaml" +MODEL: + META_ARCHITECTURE: "UnetModel" + UNET: + IN_CHANNELS: 2 + OUT_CHANNELS: 2 + CHANNELS: 32 + NUM_POOL_LAYERS: 4 + DROPOUT: 0. +SOLVER: + TRAIN_BATCH_SIZE: 16 + TEST_BATCH_SIZE: 16 + BASE_LR: 1e-3 +OUTPUT_DIR: "results://mri-recon/mridata-3dfse-knee/unet" +DESCRIPTION: + EXP_NAME: "UNET_NON_VORTEX" \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/unrolled.yaml b/configs/mri-recon/mridata-3dfse-knee/old/unrolled.yaml new file mode 100644 index 00000000..dbfd9c0e --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/unrolled.yaml @@ -0,0 +1,23 @@ +_BASE_: "template.yaml" +MODEL: + META_ARCHITECTURE: "GeneralizedUnrolledCNN" + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + TRAIN_BATCH_SIZE: 4 + GRAD_ACCUM_ITERS: 4 + TEST_BATCH_SIZE: 12 + BASE_LR: 1e-4 +OUTPUT_DIR: "results://mri-recon/mridata-3dfse-knee/unrolled" +VERSION: 1 +DESCRIPTION: + EXP_NAME: "UNROLLED_NON_VORTEX" diff --git a/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_template.yaml b/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_template.yaml new file mode 100644 index 00000000..3a83e1fe --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_template.yaml @@ -0,0 +1,39 @@ +# Shared/default properties between different configs for the 3d fse mridata knee dataset. +AUG_TEST: + UNDERSAMPLE: + ACCELERATIONS: (16,) +AUG_TRAIN: + UNDERSAMPLE: + ACCELERATIONS: (16,) + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + NAME: PoissonDiskMaskFunc +MODEL: + RECON_LOSS: + NAME: "l1" + RENORMALIZE_DATA: False +DATASETS: + TRAIN: ("mridata_knee_2019_train",) + VAL: ("mridata_knee_2019_val",) + TEST: ("mridata_knee_2019_test",) +DATALOADER: + DROP_LAST: True + NUM_WORKERS: 8 + SUBSAMPLE_TRAIN: + NUM_UNDERSAMPLED: 13 +SOLVER: + # Set to step counts, not epoch counts + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + CHECKPOINT_PERIOD: -5000 # Checkpoint every 10 epochs + MAX_ITER: -8000 # Max number of epochs to train for +TEST: + EVAL_PERIOD: -5000 # Run validation every 10 epochs + VAL_METRICS: + RECON: ("psnr", "psnr_scan", "psnr_mag", "psnr_mag_scan", "nrmse", "nrmse_scan", "nrmse_mag", "nrmse_mag_scan", "ssim (Wang)") +TIME_SCALE: "epoch" +SEED: 1000 +VIS_PERIOD: -400 # save images every 400 iterations +VERSION: 1 +DESCRIPTION: + PROJECT_NAME: "vortex_rm" \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_unet.yaml b/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_unet.yaml new file mode 100644 index 00000000..7969019d --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_unet.yaml @@ -0,0 +1,41 @@ +# Configuration for DL-CS Paper +_BASE_: "vortex_rm_template.yaml" +MODEL: + DEVICE: cuda + META_ARCHITECTURE: VortexModel + A2R: + META_ARCHITECTURE: UnetModel + USE_SUPERVISED_CONSISTENCY: false # TUNE + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomNoise + p: 1.0 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true +SOLVER: + TRAIN_BATCH_SIZE: 16 + TEST_BATCH_SIZE: 16 + BASE_LR: 1e-3 +OUTPUT_DIR: "results://mri-recon/mridata-3dfse-knee/vortex_rm_unet" +DESCRIPTION: + EXP_NAME: "UNET_VORTEX_RM" + diff --git a/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_unrolled.yaml b/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_unrolled.yaml new file mode 100644 index 00000000..32f94078 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/old/vortex_rm_unrolled.yaml @@ -0,0 +1,43 @@ +_BASE_: "vortex_rm_template.yaml" +MODEL: + DEVICE: cuda + META_ARCHITECTURE: VortexModel + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + USE_SUPERVISED_CONSISTENCY: false # TUNE + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") + CONSISTENCY: + AUG: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + SCHEDULER_P: + IGNORE: false + TRANSFORMS: + - name: RandomNoise + p: 1.0 + std_devs: + - 0.2 + - 0.5 + use_mask: true + LOSS_NAME: l1 + LOSS_WEIGHT: 0.1 + USE_CONSISTENCY: true +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + TRAIN_BATCH_SIZE: 4 + GRAD_ACCUM_ITERS: 4 + TEST_BATCH_SIZE: 12 + BASE_LR: 1e-4 +OUTPUT_DIR: "results://mri-recon/mridata-3dfse-knee/vortex_rm_unrolled/" +VERSION: 1 +DESCRIPTION: + EXP_NAME: "UNROLLED_VORTEX_RM" diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/template.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/template.yaml new file mode 100644 index 00000000..4e960b70 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/template.yaml @@ -0,0 +1,45 @@ +# Shared/default properties between different configs for the 3d fse mridata knee dataset. +DESCRIPTION: + # You want to log in the ss_recon team + ENTITY_NAME: 'ss_recon' + # You want to log in the vortex_rm project + PROJECT_NAME: 'vortex_rm' +AUG_TRAIN: + UNDERSAMPLE: + # Use 16x acceleration at train time. + ACCELERATIONS: (16,) + CALIBRATION_SIZE: 20 + CENTER_FRACTIONS: [] + NAME: PoissonDiskMaskFunc +AUG_TEST: + UNDERSAMPLE: + # Use 16x acceleration at validation & test time. + ACCELERATIONS: (16,) +MODEL: + DEVICE: cuda + RECON_LOSS: + NAME: "l1" + RENORMALIZE_DATA: False +DATASETS: + TRAIN: ("mridata_knee_2019_train",) + VAL: ("mridata_knee_2019_val",) + TEST: ("mridata_knee_2019_test",) +DATALOADER: + DROP_LAST: True + NUM_WORKERS: 8 +TIME_SCALE: "iter" # Positive values are in iterations +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + # Checkpointing frequency + CHECKPOINT_PERIOD: 5000 + # Number of iterations to train for. + MAX_ITER: 80000 +TEST: + # Validation frequency + EVAL_PERIOD: 5000 + VAL_METRICS: + RECON: ("psnr", "psnr_scan", "psnr_mag", "psnr_mag_scan", "nrmse", "nrmse_scan", "nrmse_mag", "nrmse_mag_scan", "ssim (Wang)") +SEED: 1000 +VIS_PERIOD: 100 # save images every 100 iterations +VERSION: 1 diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/template_aug.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/template_aug.yaml new file mode 100644 index 00000000..f1e6502b --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/template_aug.yaml @@ -0,0 +1,10 @@ +_BASE_: "template.yaml" +AUG_TRAIN: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/template_multi_aug_2D.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/template_multi_aug_2D.yaml new file mode 100644 index 00000000..d50f6fc6 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/template_multi_aug_2D.yaml @@ -0,0 +1,28 @@ +_BASE_: "template.yaml" +AUG_TRAIN: + MRI_RECON: + AUG_SENSITIVITY_MAPS: true + TRANSFORMS: + - name: RandomMRIMultiShotMotion + tfms_or_gens: + - name: RandomAffine + p: 1.0 + angle: 7 + translate: 0.1 + scale: 1.0 + shear: 0 + - name: RandomAffine + p: 1.0 + angle: 0 + translate: 0.2 + scale: 1.0 + shear: 0 + - name: RandomAffine + p: 1.0 + angle: 15 + translate: 0 + scale: 1.0 + shear: 0 + nshots: 5 + trajectory: interleaved + p: 1.0 diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/unet.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/unet.yaml new file mode 100644 index 00000000..6250bdc5 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/unet.yaml @@ -0,0 +1,14 @@ +# Configuration for DL-CS Paper +_BASE_: "template.yaml" +MODEL: + META_ARCHITECTURE: "UnetModel" + UNET: + IN_CHANNELS: 2 + OUT_CHANNELS: 2 + CHANNELS: 32 + NUM_POOL_LAYERS: 4 + DROPOUT: 0. +SOLVER: + TRAIN_BATCH_SIZE: 16 + TEST_BATCH_SIZE: 16 + BASE_LR: 1e-3 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/unet_aug.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/unet_aug.yaml new file mode 100644 index 00000000..73e794aa --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/unet_aug.yaml @@ -0,0 +1,14 @@ +# Configuration for DL-CS Paper +_BASE_: "template_aug.yaml" +MODEL: + META_ARCHITECTURE: "UnetModel" + UNET: + IN_CHANNELS: 2 + OUT_CHANNELS: 2 + CHANNELS: 32 + NUM_POOL_LAYERS: 4 + DROPOUT: 0. +SOLVER: + TRAIN_BATCH_SIZE: 16 + TEST_BATCH_SIZE: 16 + BASE_LR: 1e-3 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/unet_multi_aug.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/unet_multi_aug.yaml new file mode 100644 index 00000000..525a26b2 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/unet_multi_aug.yaml @@ -0,0 +1,14 @@ +# Configuration for DL-CS Paper +_BASE_: "template_multi_aug_2D.yaml" +MODEL: + META_ARCHITECTURE: "UnetModel" + UNET: + IN_CHANNELS: 2 + OUT_CHANNELS: 2 + CHANNELS: 32 + NUM_POOL_LAYERS: 4 + DROPOUT: 0. +SOLVER: + TRAIN_BATCH_SIZE: 16 + TEST_BATCH_SIZE: 16 + BASE_LR: 1e-3 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/unrolled.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/unrolled.yaml new file mode 100644 index 00000000..c0d35540 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/unrolled.yaml @@ -0,0 +1,20 @@ +_BASE_: "template.yaml" +MODEL: + META_ARCHITECTURE: "GeneralizedUnrolledCNN" + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + TRAIN_BATCH_SIZE: 4 + GRAD_ACCUM_ITERS: 4 + TEST_BATCH_SIZE: 12 + BASE_LR: 1e-4 +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/unrolled_aug.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/unrolled_aug.yaml new file mode 100644 index 00000000..c8817576 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/unrolled_aug.yaml @@ -0,0 +1,20 @@ +_BASE_: "template_aug.yaml" +MODEL: + META_ARCHITECTURE: "GeneralizedUnrolledCNN" + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + TRAIN_BATCH_SIZE: 4 + GRAD_ACCUM_ITERS: 4 + TEST_BATCH_SIZE: 12 + BASE_LR: 1e-4 +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/templates/unrolled_multi_aug.yaml b/configs/mri-recon/mridata-3dfse-knee/templates/unrolled_multi_aug.yaml new file mode 100644 index 00000000..a6ca2d08 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/templates/unrolled_multi_aug.yaml @@ -0,0 +1,20 @@ +_BASE_: "template_multi_aug_2D.yaml" +MODEL: + META_ARCHITECTURE: "GeneralizedUnrolledCNN" + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") +SOLVER: + OPTIMIZER: "Adam" + LR_SCHEDULER_NAME: "" + TRAIN_BATCH_SIZE: 4 + GRAD_ACCUM_ITERS: 4 + TEST_BATCH_SIZE: 12 + BASE_LR: 1e-4 +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Aug_UNET_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Aug_UNET_13_Scan.yaml new file mode 100644 index 00000000..d56b6d9d --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Aug_UNET_13_Scan.yaml @@ -0,0 +1,48 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet.yaml" +DATALOADER: + SUBSAMPLE_TRAIN: + # 1 supervised and 13 unsupervised scans for training + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/ssdu/ssdu_aug_unet_13_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"SSDU Aug U-Net {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - {MODEL.SSDU.MASKER.PARAMS.kind}/loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/SSDU_Aug + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse + - unet +# For motion aug, A2R and Consistency were kept with std_dev range of 0.2 to 0.5. +MODEL: + META_ARCHITECTURE: SSDUModel + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SSDU: + # For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel + META_ARCHITECTURE: UnetModel + MASKER: + # These paramters were taken from the VORTEX/Noise2Recon papers. + PARAMS: + kind: uniform + rhos: 0.4 # Default value in SSDU code + p: 1.0 + per_example: true + AUGMENTOR: + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 +AUG_TRAIN: + MRI_RECON: + TRANSFORMS: [] +VERSION: 1 + diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Multi_Aug_UNET_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Multi_Aug_UNET_13_Scan.yaml new file mode 100644 index 00000000..bd08e581 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_Multi_Aug_UNET_13_Scan.yaml @@ -0,0 +1,66 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet.yaml" +DATALOADER: + SUBSAMPLE_TRAIN: + # 1 supervised and 13 unsupervised scans for training + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/ssdu/ssdu_multi_aug_unet_13_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"SSDU Multi Aug U-Net {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - {MODEL.SSDU.MASKER.PARAMS.kind}/loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/SSDU_Multi_Aug + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse + - unet +# For motion aug, A2R and Consistency were kept with std_dev range of 0.2 to 0.5. +MODEL: + META_ARCHITECTURE: SSDUModel + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SSDU: + # For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel + META_ARCHITECTURE: UnetModel + MASKER: + # These paramters were taken from the VORTEX/Noise2Recon papers. + PARAMS: + kind: uniform + rhos: 0.4 # Default value in SSDU code + p: 1.0 + per_example: true + AUGMENTOR: + TRANSFORMS: + - name: RandomMRIMultiShotMotion + tfms_or_gens: + - name: RandomAffine + p: 1.0 + angle: 7 + translate: 0.1 + scale: 1.0 + shear: 0 + - name: RandomAffine + p: 1.0 + angle: 0 + translate: 0.2 + scale: 1.0 + shear: 0 + - name: RandomAffine + p: 1.0 + angle: 15 + translate: 0 + scale: 1.0 + shear: 0 + nshots: 5 + trajectory: interleaved + p: 1.0 +AUG_TRAIN: + MRI_RECON: + TRANSFORMS: [] +VERSION: 1 + diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_UNET_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_UNET_13_Scan.yaml new file mode 100644 index 00000000..a8437e07 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/ssdu/SSDU_UNET_13_Scan.yaml @@ -0,0 +1,36 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet.yaml" +DATALOADER: + SUBSAMPLE_TRAIN: + # 1 supervised and 13 unsupervised scans for training. + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/ssdu/ssdu_unet_13_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"SSDU U-Net {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - {MODEL.SSDU.MASKER.PARAMS.kind}/loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/ssdu + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse + - unet +MODEL: + META_ARCHITECTURE: SSDUModel + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SSDU: + # For UNET, the META_ARCHITECTURE of SSDUModel is UnetModel. + META_ARCHITECTURE: UnetModel + MASKER: + # These parameters were taken from the VORTEX/Noise2Recon papers. + PARAMS: + kind: uniform + p: 1.0 + rhos: 0.4 # Default value in SSDU code + per_example: true +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_14_Scan.yaml new file mode 100644 index 00000000..32b6a9ac --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_14_Scan.yaml @@ -0,0 +1,29 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet_aug.yaml" +# DATALOADER has 14 supervised scans +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_aug_unet_14_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"Supervised Aug U-Net 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/supervised_aug_unet_14 + TAGS: + - baseline + - supervised + - 14_scan + - 16x + - mridata_knee_3dfse + - unet +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: UnetModel + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_1_Scan.yaml new file mode 100644 index 00000000..7e69288d --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_1_Scan.yaml @@ -0,0 +1,28 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet_aug.yaml" +# DATALOADER has only 1 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_UNDERSAMPLED: 0 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_aug_unet_1_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"Supervised Aug U-Net 1 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/supervised_aug_unet_1 + TAGS: + - baseline + - supervised + - one_scan + - 16x + - mridata_knee_3dfse + - unet +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: UnetModel + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Multi_Aug_UNET_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Multi_Aug_UNET_14_Scan.yaml new file mode 100644 index 00000000..870d3217 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Multi_Aug_UNET_14_Scan.yaml @@ -0,0 +1,29 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet_multi_aug.yaml" +# DATALOADER has 14 supervised scans +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_multi_aug_unet_14_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"Supervised Multi Aug U-Net 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/supervised_multi_aug_unet_14 + TAGS: + - baseline + - supervised + - 14_scan + - 16x + - mridata_knee_3dfse + - unet +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: UnetModel + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Multi_Aug_UNET_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Multi_Aug_UNET_1_Scan.yaml new file mode 100644 index 00000000..fd517fe4 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Multi_Aug_UNET_1_Scan.yaml @@ -0,0 +1,28 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet_multi_aug.yaml" +# DATALOADER has only 1 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_UNDERSAMPLED: 0 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_multi_aug_unet_1_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"Supervised Multi Aug U-Net 1 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/supervised_multi_aug_unet_1 + TAGS: + - baseline + - supervised + - one_scan + - 16x + - mridata_knee_3dfse + - unet +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: UnetModel + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_14_Scan.yaml new file mode 100644 index 00000000..2c6b9d63 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_14_Scan.yaml @@ -0,0 +1,29 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet.yaml" +# DATALOADER has 14 supervised scans +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_unet_14_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"Supervised U-Net 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/supervised_unet_14 + TAGS: + - baseline + - supervised + - 14_scan + - 16x + - mridata_knee_3dfse + - unet +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: UnetModel + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_1_Scan.yaml new file mode 100644 index 00000000..4858fbbf --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_1_Scan.yaml @@ -0,0 +1,29 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet.yaml" +# DATALOADER has only 1 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_UNDERSAMPLED: 0 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_unet_1_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"Supervised U-Net 1 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/supervised_unet_1 + TAGS: + - baseline + - supervised + - one_scan + - 16x + - mridata_knee_3dfse + - unet +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: UnetModel + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unet/vortex/VORTEX_Multi_Aug_UNET_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unet/vortex/VORTEX_Multi_Aug_UNET_14_Scan.yaml new file mode 100644 index 00000000..5f100619 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unet/vortex/VORTEX_Multi_Aug_UNET_14_Scan.yaml @@ -0,0 +1,53 @@ +# Inherit fields from the unet.yaml config. +_BASE_: "../../templates/unet.yaml" +# DATALOADER has 14 supervised scans +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unet/vortex/vortex_multi_aug_unet_14_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"VORTEX Multi Aug U-Net 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unet/vortex_multi_aug_unet_14 + TAGS: + - baseline + - vortex + - 14_scan + - 16x + - mridata_knee_3dfse + - unet +# For no motion aug, A2R and Consistency was removed. +# For UNET, kept META_ARCHITECTURE as UnetModel +MODEL: + META_ARCHITECTURE: VortexModel + UNET: + CHANNELS: 32 + DROPOUT: 0.0 + IN_CHANNELS: 2 + NUM_POOL_LAYERS: 4 + OUT_CHANNELS: 2 + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + A2R: + META_ARCHITECTURE: UnetModel + CONSISTENCY: + AUG: + MRI_RECON: + TRANSFORMS: + - name: RandomMRIMultiShotMotion + tfms_or_gens: + - name: RandomAffine + p: 1.0 + angle: 7 + translate: 0.1 + scale: 1.0 + shear: 0 + nshots: 5 + trajectory: interleaved + p: 1.0 + LOSS_NAME: k_l1 +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Aug_Unrolled_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Aug_Unrolled_13_Scan.yaml new file mode 100644 index 00000000..a1200ee7 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Aug_Unrolled_13_Scan.yaml @@ -0,0 +1,49 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled.yaml" +DATALOADER: + SUBSAMPLE_TRAIN: + # 1 supervised and 13 unsupervised scans for training + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/ssdu/ssdu_aug_unrolled_13_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"SSDU Aug Unrolled {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - {MODEL.SSDU.MASKER.PARAMS.kind}/loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/SSDU_Aug + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse + - unrolled +# For motion aug, A2R and Consistency were kept with std_dev range of 0.2 to 0.5. +# For Unrolled, the META_ARCHITECTURE of SSDUModel is GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: SSDUModel + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SSDU: + META_ARCHITECTURE: GeneralizedUnrolledCNN + MASKER: + # These parameters were taken from the VORTEX/Noise2Recon papers. + PARAMS: + kind: uniform + rhos: 0.4 # Default value in SSDU code + p: 1.0 + per_example: true + AUGMENTOR: + TRANSFORMS: + - name: RandomMRIMotion + p: 0.2 + std_devs: + - 0.2 + - 0.5 +AUG_TRAIN: + MRI_RECON: + TRANSFORMS: [] +VERSION: 1 + + diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Multi_Aug_Unrolled_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Multi_Aug_Unrolled_13_Scan.yaml new file mode 100644 index 00000000..ff4eb830 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Multi_Aug_Unrolled_13_Scan.yaml @@ -0,0 +1,67 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled.yaml" +DATALOADER: + SUBSAMPLE_TRAIN: + # 1 supervised and 13 unsupervised scans for training + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +# Specify an output directory that is unique for this experiment. +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/ssdu/ssdu_multi_aug_unrolled_13_scan +DESCRIPTION: + # Use f-strings to specify reading values in braces ({}) the config file. + # This can only be done for string fields. + BRIEF: f"SSDU Multi Aug Unrolled {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - {MODEL.SSDU.MASKER.PARAMS.kind}/loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/SSDU_Multi_Aug + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse + - unrolled +# For motion aug, A2R and Consistency were kept with std_dev range of 0.2 to 0.5. +# For Unrolled, the META_ARCHITECTURE of SSDUModel is GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: SSDUModel + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SSDU: + META_ARCHITECTURE: GeneralizedUnrolledCNN + MASKER: + # These parameters were taken from the VORTEX/Noise2Recon papers. + PARAMS: + kind: uniform + rhos: 0.4 # Default value in SSDU code + p: 1.0 + per_example: true + AUGMENTOR: + TRANSFORMS: + - name: RandomMRIMultiShotMotion + tfms_or_gens: + - name: RandomAffine + p: 1.0 + angle: 7 + translate: 0.1 + scale: 1.0 + shear: 0 + - name: RandomAffine + p: 1.0 + angle: 0 + translate: 0.2 + scale: 1.0 + shear: 0 + - name: RandomAffine + p: 1.0 + angle: 15 + translate: 0 + scale: 1.0 + shear: 0 + nshots: 5 + trajectory: interleaved + p: 1.0 +AUG_TRAIN: + MRI_RECON: + TRANSFORMS: [] +VERSION: 1 + + diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Unrolled_13_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Unrolled_13_Scan.yaml new file mode 100644 index 00000000..18f096fa --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Unrolled_13_Scan.yaml @@ -0,0 +1,33 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled.yaml" +DATALOADER: + # DATALOADER has 1 supervised and 13 unsupervised + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 13 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/ssdu/ssdu_unrolled_13_scan +DESCRIPTION: + BRIEF: f"SSDU Unrolled {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - {MODEL.SSDU.MASKER.PARAMS.kind}/loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/SSDU + TAGS: + - baseline + - ssdu + - 16x + - mridata_knee_3dfse + - unrolled +# For no motion aug, A2R and Consistency were removed. +# For Unrolled, the META_ARCHITECTURE of SSDUModel is GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: SSDUModel + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + SSDU: + META_ARCHITECTURE: GeneralizedUnrolledCNN + MASKER: + PARAMS: + kind: uniform + p: 1.0 + rhos: 0.4 # Default value in SSDU code + per_example: true +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Aug_Unrolled_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Aug_Unrolled_14_Scan.yaml new file mode 100644 index 00000000..c3eacb0b --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Aug_Unrolled_14_Scan.yaml @@ -0,0 +1,26 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled_aug.yaml" +# DATALOADER has 14 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_aug_unrolled_14_scan +DESCRIPTION: + BRIEF: f"Supervised Aug Unrolled 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/supervised_aug_14_scan + TAGS: + - baseline + - supervised + - 14_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: GeneralizedUnrolledCNN + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Aug_Unrolled_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Aug_Unrolled_1_Scan.yaml new file mode 100644 index 00000000..1593480b --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Aug_Unrolled_1_Scan.yaml @@ -0,0 +1,25 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled_aug.yaml" +# DATALOADER has only 1 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_aug_unrolled_1_scan +DESCRIPTION: + BRIEF: f"Supervised Aug Unrolled 1 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/supervised_aug_1_scan + TAGS: + - baseline + - supervised + - one_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: GeneralizedUnrolledCNN + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_14_Scan.yaml new file mode 100644 index 00000000..3db3b255 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_14_Scan.yaml @@ -0,0 +1,26 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled_multi_aug.yaml" +# DATALOADER has 14 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_multi_aug_unrolled_14_scan +DESCRIPTION: + BRIEF: f"Supervised Multi Aug Unrolled 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/supervised_multi_aug_14_scan + TAGS: + - baseline + - supervised + - 14_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: GeneralizedUnrolledCNN + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_1_Scan.yaml new file mode 100644 index 00000000..26249944 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_1_Scan.yaml @@ -0,0 +1,25 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled_multi_aug.yaml" +# DATALOADER has only 1 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_multi_aug_unrolled_1_scan +DESCRIPTION: + BRIEF: f"Supervised Multi Aug Unrolled 1 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/supervised_multi_aug_1_scan + TAGS: + - baseline + - supervised + - one_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: GeneralizedUnrolledCNN + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_14_Scan.yaml new file mode 100644 index 00000000..0320d7fe --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_14_Scan.yaml @@ -0,0 +1,26 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled.yaml" +# DATALOADER has 14 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_unrolled_14_scan +DESCRIPTION: + BRIEF: f"Supervised Unrolled 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/supervised_14_scan + TAGS: + - baseline + - supervised + - 14_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: GeneralizedUnrolledCNN + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_1_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_1_Scan.yaml new file mode 100644 index 00000000..581afe12 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_1_Scan.yaml @@ -0,0 +1,26 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled.yaml" +# DATALOADER has only 1 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 1 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_unrolled_1_scan +DESCRIPTION: + BRIEF: f"Supervised Unrolled 1 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/supervised_1_scan + TAGS: + - baseline + - supervised + - one_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: GeneralizedUnrolledCNN + RECON_LOSS: + NAME: l1 + RENORMALIZE_DATA: false +VERSION: 1 \ No newline at end of file diff --git a/configs/mri-recon/mridata-3dfse-knee/unrolled/vortex/VORTEX_Multi_Aug_Unrolled_14_Scan.yaml b/configs/mri-recon/mridata-3dfse-knee/unrolled/vortex/VORTEX_Multi_Aug_Unrolled_14_Scan.yaml new file mode 100644 index 00000000..0386e859 --- /dev/null +++ b/configs/mri-recon/mridata-3dfse-knee/unrolled/vortex/VORTEX_Multi_Aug_Unrolled_14_Scan.yaml @@ -0,0 +1,53 @@ +# Inherit fields from the unrolled.yaml config. +_BASE_: "../../templates/unrolled.yaml" +# DATALOADER has 14 supervised scan +DATALOADER: + SUBSAMPLE_TRAIN: + NUM_TOTAL: 14 + NUM_UNDERSAMPLED: 0 +OUTPUT_DIR: results://vortex-rm/mridata_knee_3dfse/unrolled/vortex/vortex_multi_aug_unrolled_14_scan +DESCRIPTION: + BRIEF: f"VORTEX Multi Aug Unrolled 14 Scan {AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS}x mridata - loss={MODEL.RECON_LOSS.NAME}" + EXP_NAME: mridata_knee_3dfse/unrolled/vortex_multi_aug_14_scan + TAGS: + - baseline + - vortex + - 14_scan + - 16x + - mridata_knee_3dfse + - unrolled +# For no motion aug, A2R and Consistency was removed. +# For Unrolled, made META_ARCHITECTURE GeneralizedUnrolledCNN +MODEL: + META_ARCHITECTURE: VortexModel + UNROLLED: + NUM_UNROLLED_STEPS: 8 + NUM_RESBLOCKS: 2 + NUM_FEATURES: 128 + DROPOUT: 0. + CONV_BLOCK: + ACTIVATION: "relu" + NORM: "none" + ORDER: ("act", "conv") + RECON_LOSS: + NAME: k_l1 + RENORMALIZE_DATA: false + A2R: + META_ARCHITECTURE: GeneralizedUnrolledCNN + CONSISTENCY: + AUG: + MRI_RECON: + TRANSFORMS: + - name: RandomMRIMultiShotMotion + tfms_or_gens: + - name: RandomAffine + p: 1.0 + angle: 7 + translate: 0.1 + scale: 1.0 + shear: 0 + nshots: 5 + trajectory: interleaved + p: 1.0 + LOSS_NAME: k_l1 +VERSION: 1 \ No newline at end of file diff --git a/get_available_gpu.py b/get_available_gpu.py new file mode 100644 index 00000000..fbd5d09b --- /dev/null +++ b/get_available_gpu.py @@ -0,0 +1,4 @@ +from meddlr.utils.env import get_available_gpus + +if len(get_available_gpus()) > 0: + print(get_available_gpus()[0]) diff --git a/meddlr/data/build.py b/meddlr/data/build.py index 5fab414d..e361aa0e 100644 --- a/meddlr/data/build.py +++ b/meddlr/data/build.py @@ -2,7 +2,7 @@ import logging import random from collections import defaultdict -from typing import Dict, Mapping, Sequence, Tuple, Union +from typing import Callable, Dict, Mapping, Optional, Sequence, Tuple, Union import numpy as np from torch.utils.data import DataLoader @@ -258,8 +258,16 @@ def build_recon_val_loader( as_test: bool = False, add_noise: bool = False, add_motion: bool = False, + data_transform: Optional[Callable] = None, dataset_type=None, ): + mask_func = build_mask_func(cfg.AUG_TRAIN) + + if data_transform is None: + data_transform = T.DataTransform( + cfg, mask_func, is_test=as_test, add_noise=add_noise, add_motion=add_motion + ) + if ( cfg.DATALOADER.SUBSAMPLE_TRAIN.NUM_VAL > 0 and cfg.DATALOADER.SUBSAMPLE_TRAIN.NUM_VAL_BY_GROUP @@ -284,9 +292,6 @@ def build_recon_val_loader( dataset_type = _get_default_dataset_type(dataset_name) mask_func = build_mask_func(cfg.AUG_TRAIN) - data_transform = T.DataTransform( - cfg, mask_func, is_test=as_test, add_noise=add_noise, add_motion=add_motion - ) val_data = _build_dataset( cfg, dataset_dicts, data_transform, is_eval=True, dataset_type=dataset_type diff --git a/meddlr/data/transforms/transform.py b/meddlr/data/transforms/transform.py index 24db1bcc..aa0fc2ea 100644 --- a/meddlr/data/transforms/transform.py +++ b/meddlr/data/transforms/transform.py @@ -1,15 +1,19 @@ """Basic Transforms. """ +import math from functools import partial +from typing import List, Optional, Sequence, Tuple from typing import Any, Dict - import numpy as np import torch from fvcore.common.registry import Registry +import meddlr.ops as F from meddlr.data.transforms.subsample import MaskFunc from meddlr.forward import SenseModel from meddlr.ops import complex as cplx +from meddlr.transforms.gen.spatial import RandomAffine, RandomTranslation +from meddlr.transforms.transform_gen import TransformGen from meddlr.utils import transforms as T from .motion import MotionModel @@ -21,6 +25,60 @@ """ +def add_affine_motion( + image: torch.Tensor, + nshots: int, + transforms: Sequence[TransformGen], + trajectory: str = "blocked", +) -> torch.Tensor: + """ + Simulate 2D motion for multi-shot Cartesian MRI. + + This function supports two trajectories: + - 'blocked': Where each shot corresponds to a consecutive block of kspace. + (e.g. 1 1 2 2 3 3) + - 'interleaved': Where shots are interleaved (e.g. 1 2 3 1 2 3) + + We assume the phase encode direction is left to right + (i.e. along width dimension). + + TODO: Add support for sensitivity maps. + + Args: + image: The complex-valued image. Shape [..., height, width]. + nshots: The number of shots in the image. + This should be equivalent to ceil(phase_encode_dim / echo_train_length). + transforms: A sequence of random transform generators. These transforms + will be used to augment images in the image domain. We recommend using + [RandomTranslation, RandomAffine] in that order. This matches the MRAugment + augmentation strategy. + trajectory: One of 'interleaved' or 'blocked'. + + Returns: + A motion corrupted image. + """ + kspace = torch.zeros_like(image) + offset = int(math.ceil(kspace.shape[-1] / nshots)) + + for shot in range(nshots): + # Apply sequence of random transforms to the image. + motion_image = image + for tfm in transforms: + motion_image = tfm.get_transform(motion_image).apply_image(motion_image) + + motion_kspace = F.fft2c(motion_image) + if trajectory == "blocked": + kspace[..., shot * offset : (shot + 1) * offset] = motion_kspace[ + ..., shot * offset : (shot + 1) * offset + ] + elif trajectory == "interleaved": + kspace[..., shot::nshots] = motion_kspace[..., shot::nshots] + else: + raise ValueError(f"trajectory '{trajectory}' not supported.") + + return F.ifft2c(kspace) + + def build_normalizer(cfg): cfg = cfg.MODEL.NORMALIZER name = cfg.NAME @@ -404,3 +462,243 @@ def __call__( if postprocessing_mask is not None: out["postprocessing_mask"] = postprocessing_mask.squeeze(0) return out + +class MotionDataTransform: + """ + Data Transformer for training unrolled reconstruction models. + + This is for emulating 2D roto-translational motion corrupted MR scans. + """ + + def __init__( + self, + cfg, + mask_func, + nshots: int, + is_test: bool = False, + add_noise: bool = False, + add_motion: bool = False, + mri_dim: int = 2, + angle: Optional[Tuple[float, float]] = (-5.0, 5.0), + translation: Optional[Tuple[float, float]] = (0.1, 0.1), + pad_like: str = "none", + trajectory: str = "blocked", + ): + """ + Args: + mask_func (utils.subsample.MaskFunc): A function that can create a + mask of appropriate shape. + is_test (bool): If `True`, this class behaves with test-time + functionality. In particular, it computes a pseudo random number + generator seed from the filename. This ensures that the same + mask is used for all the slices of a given volume every time. + """ + if not is_test: + raise ValueError( + "is_test must be true for this class to work - it is currently set to false" + ) + + self._cfg = cfg + self.mask_func = mask_func + self._is_test = is_test + + # Build subsampler. + # mask_func = build_mask_func(cfg) + self._subsampler = Subsampler(self.mask_func) + self.add_noise = add_noise + self.add_motion = add_motion + + # These will be used for the motion corruption. + self.angle = angle + self.translation = translation + self.mri_dim = mri_dim + + if nshots is None: + raise ValueError("The parameter nshots must be set to some integer value.") + + self.nshots = nshots + self.trajectory = trajectory + self.pad_like = pad_like + + seed = cfg.SEED if cfg.SEED > -1 else None + self.rng = np.random.RandomState(seed) + + if is_test: + # When we test we dont want to initialize with certain parameters (e.g. scheduler). + self.noiser = NoiseModel(cfg.MODEL.CONSISTENCY.AUG.NOISE.STD_DEV, seed=seed) + else: + pass + + self.p_noise = cfg.AUG_TRAIN.NOISE_P + self.p_motion = cfg.AUG_TRAIN.MOTION_P + self._normalizer = build_normalizer(cfg) + self._postprocessor = cfg.TEST.POSTPROCESSOR.NAME + + # Build augmentation pipeline. + self.augmentor = None + if not is_test and cfg.AUG_TRAIN.MRI_RECON.TRANSFORMS: + pass + + def _get_mask(self, masked_kspace): + # If any of the coils are non-zero at a coordinate, we assume + assert torch.is_complex(masked_kspace) + return cplx.get_mask(masked_kspace, coil_dim=-1) + + def __call__(self, kspace, maps, target, fname, slice_id, is_fixed, acceleration: int = None): + """ + Args: + kspace (numpy.array): Input k-space of shape + (num_coils, rows, cols, 2) for multi-coil + data or (rows, cols, 2) for single coil data. + target (numpy.array): Target image + attrs (dict): Acquisition related information stored in the HDF5 + object. + fname (str): File name + slice (int): Serial number of the slice. + is_fixed (bool, optional): If `True`, transform the example + to have a fixed mask and acceleration factor. + acceleration (int): Acceleration factor. Must be provided if + `is_undersampled=True`. + Returns: + (tuple): tuple containing: + image (torch.Tensor): Zero-filled input image. + target (torch.Tensor): Target image converted to a torch Tensor. + mean (float): Mean value used for normalization. + std (float): Standard deviation value used for normalization. + norm (float): L2 norm of the entire volume. + """ + if is_fixed and not acceleration: + raise ValueError("Accelerations must be specified for undersampled scans") + + # Convert everything from numpy arrays to tensors + kspace = cplx.to_tensor(kspace).unsqueeze(0) + maps = cplx.to_tensor(maps).unsqueeze(0) + target_init = cplx.to_tensor(target).unsqueeze(0) + target = ( + torch.complex(target_init, torch.zeros_like(target_init)).unsqueeze(-1) + if not torch.is_complex(target_init) + else target_init + ) # handle rss vs. sensitivity-integrated + norm = torch.sqrt(torch.mean(cplx.abs(target) ** 2)) + + # Apply mask in k-space + seed = sum(tuple(map(ord, fname))) if self._is_test or is_fixed else None # noqa + masked_kspace, mask = self._subsampler( + kspace, mode="2D", seed=seed, acceleration=acceleration + ) + + # TODO: Add other transforms here. + + edge_mask = self._subsampler.edge_mask(kspace, mode="2D") + postprocessing_mask = None + if self._is_test and self._postprocessor: + postprocessing_mask = edge_mask + if self._postprocessor == "hard_dc_all": + postprocessing_mask = (postprocessing_mask + mask).bool().type(torch.float32) + + # If 2D MRI, then each slice will have different motion - seed is some + # combination of the file name and the slice id (+). + # If 3D MRI, then each slice should have the same motion - seed is + # determined only by the file name. + if self.mri_dim == 2: + seed = sum(tuple(map(ord, fname))) + slice_id if self._is_test else None # noqa + elif self.mri_dim == 3: + seed = sum(tuple(map(ord, fname))) if self._is_test else None # noqa + + if self.pad_like == "none": + pad = None + if self.pad_like == "mraugment": + pad = "MRAugment" + + # Zero-filled Sense Recon. + if torch.is_complex(target_init): + A = SenseModel(maps) + image = A(kspace, adjoint=True) + # Zero-filled RSS Recon. + else: + image = T.ifft2(kspace) + image_rss = torch.sqrt(torch.sum(cplx.abs(image) ** 2, axis=-1)) + image = torch.complex(image_rss, torch.zeros_like(image_rss)).unsqueeze(-1) + + add_motion = self.add_motion and self._is_test + if add_motion: + # Separate translation and affine transformations for proper padding. + translation = RandomTranslation( + p=1.0, + translate=self.translation, + pad_mode="reflect" if self.pad_like == "mraugment" else "constant", + pad_value=0.0, + ndim=2 + ) + affine = RandomAffine( + p=1.0, translate=None, angle=self.angle, pad_like=pad + ) + transforms: List[TransformGen] = [translation, affine] + # Motion seed should not be different for each slice for now. + # TODO: Change this for 2D acquisitions. + for tfm_gen in transforms: + tfm_gen.seed(seed) + + image = image.permute(0, 3, 1, 2) # Shape: (B, 1, H, W) + + motion_img = add_affine_motion( + image=image, + nshots=self.nshots, + transforms=transforms, + trajectory=self.trajectory, + ) + + motion_img = motion_img.permute(0, 2, 3, 1) # Shape: (B, H, W, 1) + sense = SenseModel(maps) + kspace = sense(motion_img) + + # Apply mask in k-space + masked_kspace, mask = self._subsampler( + kspace, mode="2D", seed=seed, acceleration=acceleration + ) + + # Zero-filled Sense Recon. + if torch.is_complex(target_init): + A = SenseModel(maps, weights=mask) + image = A(masked_kspace, adjoint=True) + # Zero-filled RSS Recon. + else: + image = T.ifft2(masked_kspace) + image_rss = torch.sqrt(torch.sum(cplx.abs(image) ** 2, axis=-1)) + image = torch.complex(image_rss, torch.zeros_like(image_rss)).unsqueeze(-1) + + # Normalize + normalized = self._normalizer.normalize( + **{"masked_kspace": masked_kspace, "image": image, "target": target, "mask": mask} + ) + masked_kspace = normalized["masked_kspace"] + target = normalized["target"] + mean = normalized["mean"] + std = normalized["std"] + + add_noise = self.add_noise and self._is_test + + if add_noise: + # Seed should be different for each slice of a scan. + noise_seed = seed + slice_id if seed is not None else None + masked_kspace = self.noiser(masked_kspace, mask=mask, seed=noise_seed) + + # Get rid of batch dimension... + masked_kspace = masked_kspace.squeeze(0) + maps = maps.squeeze(0) + target = target.squeeze(0) + + out = { + "kspace": masked_kspace, + "maps": maps, + "target": target, + "mean": mean, + "std": std, + "norm": norm, + "edge_mask": edge_mask.squeeze(0), + "mask": self._get_mask(masked_kspace), + } + if postprocessing_mask is not None: + out["postprocessing_mask"] = postprocessing_mask.squeeze(0) + return out + diff --git a/meddlr/transforms/base/__init__.py b/meddlr/transforms/base/__init__.py index 5c1d75ba..ddf4ab52 100644 --- a/meddlr/transforms/base/__init__.py +++ b/meddlr/transforms/base/__init__.py @@ -1,5 +1,6 @@ from meddlr.transforms.base.mask import KspaceMaskTransform # noqa from meddlr.transforms.base.motion import MRIMotionTransform # noqa +from meddlr.transforms.base.motion import MRIMultiShotMotion # noqa from meddlr.transforms.base.noise import NoiseTransform # noqa from meddlr.transforms.base.spatial import ( # noqa AffineTransform, diff --git a/meddlr/transforms/base/motion.py b/meddlr/transforms/base/motion.py index b3dff762..f84eed67 100644 --- a/meddlr/transforms/base/motion.py +++ b/meddlr/transforms/base/motion.py @@ -2,9 +2,10 @@ import torch -import meddlr.transforms.functional as stf +import meddlr.transforms.functional.mri as stf from meddlr.transforms.build import TRANSFORM_REGISTRY from meddlr.transforms.transform import Transform +from meddlr.transforms.transform_gen import TransformGen @TRANSFORM_REGISTRY.register() @@ -79,3 +80,95 @@ def apply_kspace(self, kspace, channel_first: bool = True) -> torch.Tensor: def _eq_attrs(self) -> Tuple[str]: return ("std_dev", "seed", "_generator_state") + + +@TRANSFORM_REGISTRY.register() +class MRIMultiShotMotion(Transform): + """A model that simulates motion artifacts in multi-shot MRI. + + To simulate motion, the coil-combined image is augmented with random + affine transformations. The number of augmentations corresponds to the + number of echo trains (i.e. number of shots) used during acquisition. + The multi-coil kspace for each of these augmented versions is combined based + on the trajectory. + """ + + def __init__( + self, + tfm_gens: Sequence[TransformGen], + trajectory: torch.Tensor, + seed: Optional[int] = None, + generator: Optional[torch.Generator] = None, + ): + """ + Args: + tfm_gens (Sequence[TransformGen]): The transform generators to use. + These will be seeded prior to use. + trajectory (torch.Tensor): The trajectory to use for the multi-shot + motion simulation. + seed (int, optional): The seed to use for the random number generator. + generator (torch.Generator, optional): The random number generator to use. + Must be specified if ``seed`` is not set. + """ + self.tfm_gens = tfm_gens + self.trajectory = trajectory + self.seed = seed + + gen_state = None + if generator is not None: + gen_state = generator.get_state() + self._generator_state = gen_state + + def _generator(self, data: torch.Tensor): + seed = self.seed + + g = torch.Generator(device=data.device) + if seed is None: + g.set_state(self._generator_state) + else: + g = g.manual_seed(seed) + return g + + def _apply_x(self, x: torch.Tensor, *, maps: torch.Tensor, channel_first: bool, xtype: str): + g = self._generator(x) + seeds = torch.randint(0, 2**32, (len(self.tfm_gens),), device=g.device, generator=g) + seeds = [seed.cpu().item() for seed in seeds] + for tfm_gen, seed in zip(self.tfm_gens, seeds): + tfm_gen.seed(seed) + + return stf.add_affine_motion( + x, + transform_gens=self.tfm_gens, + trajectory=self.trajectory, + maps=maps, + is_batch=True, + channels_first=channel_first, + xtype=xtype, + ) + + def apply_kspace( + self, + kspace: torch.Tensor, + *, + maps: torch.Tensor = None, + channel_first: bool = True, + ) -> torch.Tensor: + """Performs motion corruption on kspace image. + + Args: + kspace (torch.Tensor): The complex tensor. Shape ``(N, #coils, Y, X, [2])``. + maps (torch.Tensor, optional): The sensitivity maps. + Shape ``(N, #coils, #maps, Y, X, [2])``. + + Returns: + torch.Tensor: The motion corrupted kspace. + """ + return self._apply_x(kspace, maps=maps, channel_first=channel_first, xtype="kspace") + + def apply_image( + self, image: torch.Tensor, *, maps: torch.Tensor = None, channel_first: bool = True + ) -> torch.Tensor: + return self._apply_x(image, maps=maps, channel_first=channel_first, xtype="image") + + def _eq_attrs(self) -> Tuple[str]: + return ("tfm_gens", "trajectory", "seed", "_generator_state") diff --git a/meddlr/transforms/functional/mri.py b/meddlr/transforms/functional/mri.py index e2805b7c..92d74fa8 100644 --- a/meddlr/transforms/functional/mri.py +++ b/meddlr/transforms/functional/mri.py @@ -1,7 +1,12 @@ +import math +from typing import Sequence, Tuple + import numpy as np import torch +import meddlr.ops as oF import meddlr.ops.complex as cplx +from meddlr.forward import SenseModel def add_even_odd_motion( @@ -35,3 +40,156 @@ def add_even_odd_motion( phase_matrix[:, :, line] = phase_error aug_kspace = kspace * phase_matrix return aug_kspace + + +def add_affine_motion( + x: torch.Tensor, + *, + transform_gens, + trajectory: torch.Tensor, + maps: torch.Tensor = None, + is_batch: bool = False, + channels_first: bool = True, + xtype: str = "image", +) -> torch.Tensor: + """Simulate 2D motion for multi-shot Cartesian MRI. + + This function supports two trajectories: + - 'blocked': Where each shot corresponds to a consecutive block of kspace. + (e.g. 1 1 2 2 3 3) + - 'interleaved': Where shots are interleaved (e.g. 1 2 3 1 2 3). + + We assume the phase encode direction is left to right + (i.e. along width dimension). + TODO: Add support for sensitivity maps. + + Args: + image: The complex-valued image. Shape [(batch,), height, width, 1]. + transforms: A sequence of random transform generators. These transforms + will be used to augment images in the image domain. We recommend using + [RandomTranslation, RandomAffine] in that order. This matches the MRAugment + augmentation strategy. + trajectory: The trajectory tensor. Shape [height, width]. + maps: The sensitivity maps. Shape [(batch,) height, width, ncoils, nmaps]. + is_batch: Whether the image (and maps) are batched. + Note, the trajectory should not be batched. To run each example with + different trajectories, call this method multiple times (once per example). + + Returns: + A motion corrupted image. + """ + from meddlr.transforms.transform import TransformList + from meddlr.transforms.transform_gen import TransformGen + + if xtype not in ["image", "kspace"]: + raise ValueError(f"Invalid xtype: {xtype}. Must be one of ['image', 'kspace'].") + + if not channels_first: + if maps is not None: + if is_batch: + dims = (0, maps.ndim - 2, maps.ndim - 1, *range(1, maps.ndim - 2)) + else: + dims = (maps.ndim - 2, maps.ndim - 1, *range(0, maps.ndim - 2)) + maps = maps.permute(dims) # Shape: [(batch), ncoils, nmaps, ...] + x = cplx.channels_first(x) + + def _maps_channels_first(_maps): + if is_batch: + dims = (0, *range(3, maps.ndim), 1, 2) + else: + dims = (*range(2, maps.ndim), 0, 1) + return _maps.permute(dims) + + def _to_image(_x, _maps): + if _maps is None: + _maps = maps + if _maps is None: + return oF.ifft2c(_x) + else: + _maps = _maps_channels_first(_maps) + out = SenseModel(_maps)(cplx.channels_last(_x), adjoint=True) + return cplx.channels_first(out) + + def _to_kspace(_x, _maps): + if _maps is None: + _maps = maps + if _maps is None: + return oF.fft2c(_x) + else: + _maps = _maps_channels_first(_maps) + out = SenseModel(_maps)(cplx.channels_last(_x), adjoint=False) + return cplx.channels_first(out) + + image = x if xtype == "image" else _to_image(x, maps) + + transform_gens: Sequence[TransformGen] = transform_gens + + if maps is None: + shape = image.shape + elif is_batch: + shape = (image.shape[0], maps.shape[1], *image.shape[-2:]) + else: + shape = (maps.shape[1], *image.shape[-2:]) + kspace = torch.zeros(shape, device=image.device, dtype=image.dtype) + + shot_ids = torch.unique(trajectory) # the sorted shot ids. + assert trajectory.shape == kspace.shape[-2:], f"{trajectory.shape} != {kspace.shape[-2:]}" + trajectory = trajectory.expand_as(kspace) + + for shot_id in shot_ids: + motion_image = image + motion_maps = maps + # Apply sequence of random transforms to the image. + tfms = TransformList([]) + for tfm_gen in transform_gens: + tfm = tfm_gen.get_transform(motion_image) + tfms += tfm + motion_image = tfm.apply_image(motion_image) + if motion_maps is not None: + motion_maps = tfms.apply_image(motion_maps) + + motion_kspace = _to_kspace(motion_image, motion_maps) + + # Replace locations in the kspace with the motion corrupted kspace. + kspace[trajectory == shot_id] = motion_kspace[trajectory == shot_id] + + if xtype == "kspace": + return cplx.channels_last(kspace) if not channels_first else kspace + image = _to_image(kspace, maps) + return cplx.channels_last(image) if not channels_first else image + + +def get_multishot_trajectory( + kind: str, nshots: int, shape: Tuple[int], device="cpu" +) -> torch.Tensor: + """Build a multi-shot cartesian trajectory. + + This function supports two trajectories: + - 'blocked': Where each shot corresponds to a consecutive block of kspace. + (e.g. 1 1 2 2 3 3) + - 'interleaved': Where shots are interleaved (e.g. 1 2 3 1 2 3). + + Args: + kind: One of 'interleaved' or 'blocked'. + nshots: The number of shots in the image. + This should be equivalent to ceil(phase_encode_dim / echo_train_length). + shape: The shape of the 2D kspace tensor (height, width). + + Returns: + torch.Tensor: A categorical tensor of shape [height, width]. + Values range from [0, nshots-1] which correspond to the readouts + per shot. + """ + if kind not in ["blocked", "interleaved"]: + raise ValueError( + f"trajectory '{kind}' not supported. " "Must be one of 'blocked' or 'interleaved'." + ) + + trajectory = torch.zeros(shape, dtype=torch.long, device=device) + offset = int(math.ceil(shape[-1] / nshots)) + for shot in range(nshots): + if kind == "blocked": + trajectory[..., shot * offset : (shot + 1) * offset] = shot + elif kind == "interleaved": + trajectory[..., shot::nshots] = shot + return trajectory diff --git a/meddlr/transforms/gen/motion.py b/meddlr/transforms/gen/motion.py index 1db6d962..dfb1b0c3 100644 --- a/meddlr/transforms/gen/motion.py +++ b/meddlr/transforms/gen/motion.py @@ -1,9 +1,13 @@ -from typing import Sequence, Union +from typing import Any, List, Mapping, Sequence, Tuple, Union import torch -from meddlr.transforms.base.motion import MRIMotionTransform -from meddlr.transforms.build import TRANSFORM_REGISTRY +import meddlr.transforms.functional.mri as tF +from meddlr.config.config import CfgNode +from meddlr.transforms.base.motion import MRIMotionTransform, MRIMultiShotMotion +from meddlr.transforms.build import TRANSFORM_REGISTRY, build_transforms +from meddlr.transforms.mixins import DeviceMixin +from meddlr.transforms.tf_scheduler import SchedulableMixin from meddlr.transforms.transform import NoOpTransform from meddlr.transforms.transform_gen import TransformGen @@ -53,3 +57,105 @@ def get_transform(self, input: torch.Tensor): if gen is None or gen.device != input.device: gen = torch.Generator(device=input.device).manual_seed(int(self._rand() * 1e10)) return MRIMotionTransform(std_dev=std_dev, generator=gen) + + +@TRANSFORM_REGISTRY.register() +class RandomMRIMultiShotMotion(TransformGen): + """A model that corrupts kspace inputs with affine motion. + + Similar to :class:`RandomMRIMotion`, but supports affine transformations. + Transformations are performed in image space and filled in based on a trajectory. + + Note: + We do not store this as a module or else it would be saved to the model + definition, which we dont want. + """ + + _base_transform = MRIMultiShotMotion + + def __init__( + self, + tfms_or_gens: Sequence[TransformGen], + nshots: Union[int, Tuple[int, int]], + trajectory: str = "blocked", + p: float = 0.0, + ): + self.tfms_or_gens = tfms_or_gens + self.trajectory = trajectory + if isinstance(nshots, float): + if not nshots.is_integer(): + raise ValueError("`nshots` must be an integer") + nshots = int(nshots) + if isinstance(nshots, int): + nshots = (nshots, nshots) + super().__init__(params={"nshots": nshots}, p=p) + + def get_transform(self, input: torch.Tensor, channel_first: bool = True): + params = self._get_param_values(use_schedulers=True) + if self._rand() >= params["p"]: + return NoOpTransform() + + shape = input.shape[-2:] if channel_first else input.shape[1:3] + + nshots = self._rand_range(*params["nshots"]) + trajectory = tF.get_multishot_trajectory( + kind=self.trajectory, + nshots=int(round(nshots)), + shape=shape, + device=input.device, + ) + + gen = self._generator + if gen is None or gen.device != input.device: + gen = torch.Generator(device=input.device).manual_seed(int(self._rand() * 1e10)) + + return MRIMultiShotMotion( + tfm_gens=self.tfms_or_gens, + trajectory=trajectory, + generator=gen, + ) + + def schedulers(self): + tfms: List[SchedulableMixin] = self._get_tfm_by_type(SchedulableMixin) + schedulers = list(self._schedulers) + schedulers.extend([sch for tfm in tfms for sch in tfm.schedulers()]) + return schedulers + + def seed(self, value: int): + self._generator = torch.Generator(device=self._device).manual_seed(value) + tfms: List[TransformGen] = self._get_tfm_by_type(TransformGen) + for t in tfms: + t.seed(value) + return self + + def to(self, device): + super().to(device) + tfms: List[DeviceMixin] = self._get_tfm_by_type(DeviceMixin) + for t in tfms: + t.to(device) + return self + + def _get_tfm_by_type(self, klass): + tfms = [] + for tfm in self.tfms_or_gens: + if isinstance(tfm, (list, tuple)): + tfms.extend(t for t in tfm if isinstance(t, klass)) + elif isinstance(tfm, klass): + tfms.append(tfm) + return tfms + + def __repr__(self): + classname = type(self).__name__ + argstr = ",\n ".join("{}".format(repr(t)) for t in zip(self.tfms_or_gens)) + params = ["nshots", "trajectory", "p"] + params_str = ",\n ".join("{}={}".format(k, repr(getattr(self, k))) for k in params) + return "{}(\n {},\n {}\n)".format(classname, argstr, params_str) + + @classmethod + def from_dict(cls, cfg: CfgNode, init_kwargs: Mapping[str, Any], **kwargs): + init_kwargs = init_kwargs.copy() + tfms_or_gens = [] + for tfm_cfg in init_kwargs.pop("tfms_or_gens"): + tfms_or_gens.append(build_transforms(cfg, tfm_cfg, **kwargs)) + + return cls(tfms_or_gens, **init_kwargs) diff --git a/motion_eval_unet_ssdu_vortex.sh b/motion_eval_unet_ssdu_vortex.sh new file mode 100755 index 00000000..fb80e8ce --- /dev/null +++ b/motion_eval_unet_ssdu_vortex.sh @@ -0,0 +1,20 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/motion_eval/unet_official/ssdu/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unet_official/ssdu/wandb/vortex-rm/mridata_knee_3dfse/unet/ssdu/ssdu_unet_13_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + + +# gpu=$(python get_available_gpu.py) +# echo "The first available gpu for VORTEX is $gpu" + +# # Run vortex unet yaml +# # took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unet_official/ssdu/wandb/vortex-rm/mridata_knee_3dfse/unet/ssdu/ssdu_aug_unet_13_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + diff --git a/motion_eval_unet_supervised_vortex.sh b/motion_eval_unet_supervised_vortex.sh new file mode 100755 index 00000000..8138bf8e --- /dev/null +++ b/motion_eval_unet_supervised_vortex.sh @@ -0,0 +1,28 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/motion_eval/unet_official/supervised/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unet_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_unet_1_scan/version_002/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unet_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_unet_14_scan/version_002/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# # took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unet_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_aug_unet_1_scan/version_002/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# # took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unet_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unet/supervised/supervised_aug_unet_14_scan/version_002/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard diff --git a/motion_eval_unrolled_ssdu_vortex.sh b/motion_eval_unrolled_ssdu_vortex.sh new file mode 100755 index 00000000..af89ee07 --- /dev/null +++ b/motion_eval_unrolled_ssdu_vortex.sh @@ -0,0 +1,18 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/motion_eval/unrolled_official/ssdu/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/ssdu/wandb/vortex-rm/mridata_knee_3dfse/unrolled/ssdu/ssdu_unrolled_13_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# # took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/ssdu/wandb/vortex-rm/mridata_knee_3dfse/unrolled/ssdu/ssdu_aug_unrolled_13_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + diff --git a/motion_eval_unrolled_supervised_vortex.sh b/motion_eval_unrolled_supervised_vortex.sh new file mode 100755 index 00000000..2ca1fa0f --- /dev/null +++ b/motion_eval_unrolled_supervised_vortex.sh @@ -0,0 +1,29 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/motion_eval/unrolled_official/supervised/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_unrolled_1_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_unrolled_14_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# # took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_aug_unrolled_1_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# # took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/eval_net.py --config-file /mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/supervised/wandb/vortex-rm/mridata_knee_3dfse/unrolled/supervised/supervised_aug_unrolled_14_scan/version_001/config.yaml --metric val_psnr_mag --save-scans --angle 30 --translation 0.1 --nshots 5 --trajectory interleaved --mri_dim 2 --motion standard + diff --git a/run_unet_multi_vortex.sh b/run_unet_multi_vortex.sh new file mode 100644 index 00000000..c3aa405a --- /dev/null +++ b/run_unet_multi_vortex.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/unet_official/supervised/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_UNET_1_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_UNET_14_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unrolled yaml +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Multi_Aug_UNET_13_Scan.yaml --auto-version \ No newline at end of file diff --git a/run_unet_norm_vortex.sh b/run_unet_norm_vortex.sh new file mode 100755 index 00000000..59910732 --- /dev/null +++ b/run_unet_norm_vortex.sh @@ -0,0 +1,18 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/vortex_rm_unet.yaml --auto-version diff --git a/run_unet_supervised_vortex.sh b/run_unet_supervised_vortex.sh new file mode 100755 index 00000000..57b920ff --- /dev/null +++ b/run_unet_supervised_vortex.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/unet_official/supervised/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_1_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_UNET_14_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_1_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unet/supervised/Supervised_Aug_UNET_14_Scan.yaml --auto-version diff --git a/run_unrolled_multi_vortex.sh b/run_unrolled_multi_vortex.sh new file mode 100644 index 00000000..a4d87887 --- /dev/null +++ b/run_unrolled_multi_vortex.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/supervised/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_1_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_14_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unrolled yaml +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Multi_Aug_Unrolled_13_Scan.yaml --auto-version \ No newline at end of file diff --git a/run_unrolled_norm_vortex.sh b/run_unrolled_norm_vortex.sh new file mode 100755 index 00000000..81dd3f91 --- /dev/null +++ b/run_unrolled_norm_vortex.sh @@ -0,0 +1,16 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unrolled yaml +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unrolled yaml +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/vortex_rm_unrolled.yaml --auto-version \ No newline at end of file diff --git a/run_unrolled_ssdu_vortex.sh b/run_unrolled_ssdu_vortex.sh new file mode 100755 index 00000000..5c9be7db --- /dev/null +++ b/run_unrolled_ssdu_vortex.sh @@ -0,0 +1,11 @@ +#!/bin/bash +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/ssdu/wandb + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unrolled yaml +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/ssdu/SSDU_Unrolled_13_Scan.yaml --auto-version + diff --git a/run_unrolled_supervised_vortex.sh b/run_unrolled_supervised_vortex.sh new file mode 100755 index 00000000..9288fe37 --- /dev/null +++ b/run_unrolled_supervised_vortex.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +export MEDDLR_DATASETS_DIR=/mnt/dense/ozt/dl-ss-recon/data +export MEDDLR_CACHE_DIR=/mnt/dense/deepro/cache +export MEDDLR_RESULTS_DIR=/mnt/dense/deepro/results/Summer_2022_2023/unrolled_official/supervised/wandb + +# gpu=$(python get_available_gpu.py) +# echo "The first available gpu is $gpu" + +# # Run normal unet yaml +# # took off --debug to allow wb to work. +# WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_1_Scan.yaml --auto-version + +# gpu=$(python get_available_gpu.py) +# echo "The first available gpu is $gpu" + +# # Run normal unet yaml +# # took off --debug to allow wb to work. +# WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Unrolled_14_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu is $gpu" + +# Run normal unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_1_Scan.yaml --auto-version + +gpu=$(python get_available_gpu.py) +echo "The first available gpu for VORTEX is $gpu" + +# Run vortex unet yaml +# took off --debug to allow wb to work. +WANDB__SERVICE_WAIT=300 CUDA_VISIBLE_DEVICES=$gpu$ python tools/train_net.py --config-file configs/mri-recon/mridata-3dfse-knee/unrolled/supervised/Supervised_Multi_Aug_Unrolled_14_Scan.yaml --auto-version + diff --git a/tools/eval_net.py b/tools/eval_net.py index 1addccdd..4ef1ce4b 100644 --- a/tools/eval_net.py +++ b/tools/eval_net.py @@ -19,6 +19,8 @@ from meddlr.checkpoint import Checkpointer from meddlr.config import get_cfg from meddlr.data.build import build_recon_val_loader +from meddlr.data.transforms import transform as T +from meddlr.data.transforms.subsample import build_mask_func from meddlr.engine import DefaultTrainer, default_argument_parser, default_setup from meddlr.evaluation import DatasetEvaluators, ReconEvaluator, inference_on_dataset from meddlr.evaluation.testing import check_consistency, find_weights @@ -187,6 +189,14 @@ def update_metrics(metrics_new: pd.DataFrame, metrics_old: pd.DataFrame, on: Seq @torch.no_grad() def eval(cfg, args, model, weights_basename, criterion, best_value): zero_filled = args.zero_filled + + mri_dim = args.mri_dim + angle = args.angle + translation = args.translation + nshots = args.nshots + padlike = args.pad_like.lower() + trajectory = args.trajectory.lower() + noise_arg = args.noise.lower() motion_arg = args.motion.lower() include_noise = noise_arg != "false" @@ -202,6 +212,49 @@ def eval(cfg, args, model, weights_basename, criterion, best_value): # if use_wandb: # run = init_wandb_run(cfg, resume=True, job_type="eval", use_api=True) + data_transform = None + + if not ( + mri_dim is None + and angle is None + and translation is None + and nshots is None + and trajectory == "none" + and padlike == "none" + ): + transform_mri_dim = 2 + transform_angle = 0 + transform_translation = 0 + transform_nshots = 0 + transform_trajectory = 0 + transform_padlike = "none" + if mri_dim is not None: + transform_mri_dim = mri_dim + if angle is not None: + transform_angle = (-angle, angle) + if translation is not None: + transform_translation = (translation, translation) + if nshots is not None: + transform_nshots = nshots + if trajectory != "none": + transform_trajectory = trajectory + if padlike != "none": + transform_padlike = padlike + mask_func = build_mask_func(cfg.AUG_TRAIN) + data_transform = T.MotionDataTransform( + cfg, + mask_func, + nshots=transform_nshots, + is_test=True, + add_noise=include_noise, + add_motion=include_motion != "false", + mri_dim=transform_mri_dim, + angle=transform_angle, + translation=transform_translation, + pad_like=transform_padlike, + trajectory=transform_trajectory, + ) + device = cfg.MODEL.DEVICE model = model.to(device) model = model.eval() @@ -256,6 +309,11 @@ def eval(cfg, args, model, weights_basename, criterion, best_value): "dataset": dataset_name, "Noise Level": noise_level, "Motion Level": motion_level, + "Angle": str(angle), + "Translation": str(translation), + "Trajectory": trajectory, + "n-shots": str(nshots), + "mri_dim": str(mri_dim), "weights": weights_basename, "rescaled": not skip_rescale, } @@ -301,7 +359,8 @@ def eval(cfg, args, model, weights_basename, criterion, best_value): dataset_name, as_test=True, add_noise=noise_level > 0, - add_motion=motion_level > 0, + add_motion=(include_motion and data_transform is not None), + data_transform=data_transform, ) # Build evaluators. Only save reconstructions for last scan. @@ -458,6 +517,47 @@ def main(args): choices=("false", "standard", "sweep"), help="Type of noise evaluation", ) + + # Arguments for 2D Motion Corruption of the Dataset + + parser.add_argument( + "--angle", + default=None, + type=float, + help="How much rotation angle should be used for motion corruption of the dataset", + ) + + parser.add_argument( + "--translation", + default=None, + type=float, + help="How much translation should be used for motion corruption of the dataset", + ) + parser.add_argument( + "--nshots", + default=None, + type=int, + help="How many shots should be used for motion corruption of the dataset.", + ) + + parser.add_argument( + "--trajectory", + default="None", + choices=("None", "interleaved", "blocked"), + help= "Chooses between interleaved or blocked shots for motion corruption of the dataset", + ) + + parser.add_argument("--mri_dim", default=None, type=int, help="Selects dimensionality number") + + parser.add_argument( + "--pad_like", + default="None", + choices=("None", "MRAugment"), + help=("Specify pad like argument to Random Affine transformation"), + ) + + # End of Arguments for 2D Motion Corruption of the Dataset + parser.add_argument( "--motion", default="false", diff --git a/tools/eval_net_motion.py b/tools/eval_net_motion.py new file mode 100644 index 00000000..58a4ce24 --- /dev/null +++ b/tools/eval_net_motion.py @@ -0,0 +1,541 @@ +"""Run inference on test set scans. + +This consists of comparing both zero-filled recon and DL-recon to fully-sampled +scans. All comparisons are done per volume (not per slice). + +Example: + python eval_net.py --config-file my/experiment/folder/config.yaml --metric val_psnr_scan +""" +import itertools +import os +from copy import deepcopy +from typing import Any, Dict, Sequence + +import pandas as pd +import torch +from tabulate import tabulate + +import meddlr.ops.complex as cplx +from meddlr.checkpoint import Checkpointer +from meddlr.config import get_cfg +from meddlr.data.build import build_recon_val_loader +from meddlr.engine import DefaultTrainer, default_argument_parser, default_setup +from meddlr.evaluation import DatasetEvaluators, ReconEvaluator, inference_on_dataset +from meddlr.evaluation.testing import check_consistency, find_weights +from meddlr.modeling.meta_arch import CSModel +from meddlr.utils.logger import setup_logger + +_FILE_NAME = os.path.splitext(os.path.basename(__file__))[0] +_LOGGER_NAME = "{}.{}".format(_FILE_NAME, __name__) +# logger = logging.getLogger(_LOGGER_NAME) +logger = None # initialize in setup() + +# Default values for parameters that may not have been initially added. +_DEFAULT_VALS = {"rescaled": True} + + +class ZFReconEvaluator(ReconEvaluator): + """Zero-filled recon evaluator.""" + + def process(self, inputs, outputs): + zf_out = {k: outputs[k] for k in ("target",)} + zf_image = outputs["zf_image"] + if cplx.is_complex_as_real(zf_image): + zf_image = torch.view_as_complex(zf_image) + zf_out["pred"] = zf_image + return super().process(inputs, zf_out) + + +def setup(args): + """ + Create configs and perform basic setups. + We do not save the config. + """ + cfg = get_cfg() + cfg.merge_from_file(args.config_file) + opts = args.opts + if opts and opts[0] == "--": + opts = opts[1:] + cfg.merge_from_list(opts) + cfg.freeze() + default_setup(cfg, args, save_cfg=False) + + # Setup logger for test results + global logger + dirname = "test_results" + logger = setup_logger(os.path.join(cfg.OUTPUT_DIR, dirname), name=_FILE_NAME) + + logger.info(f"Command Line Args: {args}") + return cfg + + +def add_default_params(metrics: pd.DataFrame, ignore_case=True): + """Adds default config parameters (if missing). + + Args: + metrics (pd.DataFrame): Will be filtered based on column values. + ignore_case (bool, optional): If `True`, ignores the column casing. + Raises `ValueError` if two columns have the same lower case + form. + """ + + df = deepcopy(metrics) + if ignore_case: + column_map = {x: x.lower() for x in df.columns} + defaults_keys_map = {k.lower(): k for k in _DEFAULT_VALS.keys()} + df = df.rename(columns=column_map) + else: + defaults_keys_map = {k: k for k in _DEFAULT_VALS.keys()} + + for fmt_key, real_key in defaults_keys_map.items(): + if fmt_key not in df.columns: + df[real_key] = _DEFAULT_VALS[real_key] + + if ignore_case: + df = df.rename(columns={v: k for k, v in column_map.items()}) + + return df + + +def find_metrics( + metrics: pd.DataFrame, params: Dict[str, Any], ignore_missing=False, ignore_case=True +): + """Find subset of metrics dictionary that matches parameter configuration. + + Note: + Values that are not available will be filled in by _DEFAULT_VALS. + + Args: + metrics (pd.DataFrame): Will be filtered based on column values. + params (Dict[str, Any]): Parameter values to filter by. + Keys should correspond to column names in `metrics`. + ignore_missing (bool, optional): If `True`, ignores filtering by + columns that are missing. + ignore_case (bool, optional): If `True`, ignores the column casing. + Raises `ValueError` if two columns have the same lower case + form. + + Returns: + df (pd.DataFrame): The remaining dataframe after filtering. + """ + + df = deepcopy(metrics) + if ignore_case: + column_map = {x: x.lower() for x in df.columns} + df = df.rename(columns=column_map) + params = {k.lower(): v for k, v in params.items()} + + # Fill in with default values if missing. + # Note these will always be lower case, so we match based on case. + # Fill in default values when the columns are not available. + default_keys = {x.lower() for x in params} & {x.lower() for x in _DEFAULT_VALS.keys()} + lowercase_cols = [x.lower() for x in df.columns] + for k in default_keys: + if k not in lowercase_cols: + df[k] = _DEFAULT_VALS[k] + + for k, v in params.items(): + if k not in df.columns: + if ignore_missing: + continue + else: + raise KeyError(f"No column {k} in `metrics`") + df = df[df[k] == v] + + # Undo matching by lower case. + if ignore_case: + df = df.rename(columns={v: k for k, v in column_map.items()}) + + return df + + +def update_metrics(metrics_new: pd.DataFrame, metrics_old: pd.DataFrame, on: Sequence[str]): + """Update a previous metrics version with the new one. + + Metrics that were previously computed, may not be recomputed. + To avoid overwriting them when writing to a csv, we want to + port over any old metrics that we did not recompute. + """ + # We currently do not support missing columns. + missing_cols = [k not in metrics_old.columns for k in on] + if any(missing_cols): + raise KeyError(f"Column(s) {missing_cols} not found in `metrics_old`") + missing_cols = [k not in metrics_new.columns for k in on] + if any(missing_cols): + raise KeyError(f"Column(s) {missing_cols} not found in `metrics_new`") + + # Find combination of columns to select on that is not + # available in the new metrics, but is available in the + # old metrics. + old_metrics_combos = list(itertools.product(*[metrics_old[k].unique().tolist() for k in on])) + new_metrics_combos = list(itertools.product(*[metrics_new[k].unique().tolist() for k in on])) + + to_prepend = [] + for combo in old_metrics_combos: + if combo not in new_metrics_combos: + combo_as_dict = {k: v for k, v in zip(on, combo)} + to_prepend.append(find_metrics(metrics_old, combo_as_dict)) + + if len(to_prepend) > 0: + to_prepend = pd.concat(to_prepend, ignore_index=True) + metrics = pd.concat([to_prepend, metrics_new], ignore_index=True) + else: + metrics = metrics_new + return metrics + + +@torch.no_grad() +def eval(cfg, args, model, weights_basename, criterion, best_value): + zero_filled = args.zero_filled + angle = args.angle + translation = args.translation + nshots = args.nshots + trajectory = args.trajectory.lower() + + noise_arg = args.noise.lower() + motion_arg = args.motion.lower() + + include_noise = noise_arg != "false" + include_motion = motion_arg != "false" + noise_sweep_vals = args.sweep_vals + skip_rescale = args.skip_rescale + overwrite = args.overwrite + save_scans = args.save_scans or "save_scans" in args.ops + compute_metrics = "metrics" in args.ops + # TODO: Set up W&B configuration. + # use_wandb = args.use_wandb + # if use_wandb: + # run = init_wandb_run(cfg, resume=True, job_type="eval", use_api=True) + + device = cfg.MODEL.DEVICE + model = model.to(device) + model = model.eval() + + # Get and load metrics file + output_dir = os.path.join(cfg.OUTPUT_DIR, "test_results") + metrics_file = os.path.join(output_dir, args.metrics_file) + if not overwrite and os.path.isfile(metrics_file): + metrics = pd.read_csv(metrics_file, index_col=0) + # Add default parameters to metrics. + metrics = add_default_params(metrics) + else: + metrics = None + + # Returns average or each scan + group_by_scan = True + + # Find range of noise values to search + if include_noise: + noise_vals = noise_sweep_vals if noise_arg == "sweep" else [0] + # noise_vals += list(cfg.MODEL.CONSISTENCY.AUG.NOISE.STD_DEV) + noise_vals = sorted(set(noise_vals)) + else: + noise_vals = [0] + + values = itertools.product( + cfg.DATASETS.TEST, + cfg.AUG_TEST.UNDERSAMPLE.ACCELERATIONS, + noise_vals, + ) + values = list(values) + all_results = [] + + default_metrics = ReconEvaluator.default_metrics() + if args.extra_metrics: + if not compute_metrics: + raise ValueError( + "Extra metrics were specified, but `--ops` did not " + "indicate eval should perform metric computation" + ) + default_metrics.extend(args.extra_metrics) + + for exp_idx, (dataset_name, acc, noise_level) in enumerate(values): + # Check if the current configuration already has metrics computed + # If so, dont recompute + params = { + "Acceleration": acc, + "dataset": dataset_name, + "Noise Level": noise_level, + "weights": weights_basename, + "rescaled": not skip_rescale, + } + eval_metrics = default_metrics + + logger.info("==" * 30) + logger.info("Experiment ({}/{})".format(exp_idx + 1, len(values))) + logger.info(", ".join([f"{k}: {v}" for k, v in params.items()])) + logger.info("==" * 30) + + existing_metrics = None + if metrics is not None and compute_metrics: + try: + existing_metrics = find_metrics(metrics, params) + except KeyError: + existing_metrics = None + if existing_metrics is not None and len(existing_metrics) > 0: + eval_metrics = list(set(eval_metrics) - set(existing_metrics.columns)) + if len(eval_metrics) == 0: + logger.info( + "Metrics for ({}) exist:\n{}".format( + ", ".join([f"{k}: {v}" for k, v in params.items()]), + tabulate(existing_metrics, headers=existing_metrics.columns), + ) + ) + all_results.append(existing_metrics) + continue + + # Add criterion and value after to avoid searching by it. + params.update({"Criterion Name": criterion, "Criterion Val": best_value}) + + # Assign the current acceleration + s_cfg = cfg.clone() + s_cfg.defrost() + s_cfg.AUG_TRAIN.UNDERSAMPLE.ACCELERATIONS = (acc,) + s_cfg.MODEL.CONSISTENCY.AUG.NOISE.STD_DEV = (noise_level,) + s_cfg.freeze() + + # Build a recon val loader + dataloader = build_recon_val_loader( + s_cfg, + dataset_name, + as_test=True, + add_noise=noise_level > 0, + add_motion=include_motion != "false", + angle=angle, + translation=translation, + nshots=nshots, + trajectory=trajectory, + ) + + # Build evaluators. Only save reconstructions for last scan. + params_str = "-".join(f"{k}={v}" for k, v in params.items() if k != "dataset") + exp_output_dir = os.path.join(output_dir, dataset_name, params_str) + evaluators = [ + ReconEvaluator( + dataset_name, + s_cfg, + group_by_scan=group_by_scan, + skip_rescale=skip_rescale, + save_scans=save_scans, + output_dir=exp_output_dir, + metrics=eval_metrics if compute_metrics else False, + prefix=None, + ) + ] + # TODO: add support for multiple evaluators. + if zero_filled: + zf_output_dir = os.path.join(output_dir, dataset_name, "ZeroFilled-" + params_str) + + evaluators.append( + ZFReconEvaluator( + dataset_name, + s_cfg, + group_by_scan=group_by_scan, + skip_rescale=skip_rescale, + save_scans=save_scans, + output_dir=zf_output_dir, + metrics=eval_metrics if compute_metrics else False, + prefix=None, + ) + ) + evaluators = DatasetEvaluators(evaluators, as_list=True) + + results = inference_on_dataset(model, dataloader, evaluators) + results = [ + pd.DataFrame(x).T.reset_index().rename(columns={"index": "scan_name"}) for x in results + ] + + results[0]["Method"] = s_cfg.MODEL.META_ARCHITECTURE + if zero_filled: + results[1]["Method"] = "Zero-Filled" + scan_results = pd.concat(results, ignore_index=True) + + if existing_metrics is not None and len(existing_metrics) > 0: + scan_results = existing_metrics.merge( + scan_results, on=["scan_name", "Method"], suffixes=("", "_y") + ) + scan_results = scan_results.drop( + scan_results.filter(regex="_y$").columns.tolist(), axis=1 + ) + else: + for k, v in params.items(): + scan_results[k] = v + logger.info("\n" + tabulate(scan_results, headers=scan_results.columns)) + + all_results.append(scan_results) + del evaluators + del dataloader + # Currently don't support writing data because it takes too long + # logger.info("Saving data...") + # file_path = os.path.join(output_dir, dataset_name, "{}.h5".format(scan_name)) + # os.makedirs(os.path.dirname(file_path), exist_ok=True) + + if len(all_results) > 0: + all_results = pd.concat(all_results, ignore_index=True) + logger.info("Summary:\n{}".format(tabulate(all_results, headers=all_results.columns))) + else: + logger.info("No evaluation metrics were computed or available in this run") + + # Try to copy over old metrics information. + # TODO: If fails, it automatically saves the old file in a versioned + # form and prints logging message. + if compute_metrics: + if metrics is not None: + try: + running_results = update_metrics( + all_results, + metrics, + on=[ + "Acceleration", + "dataset", + "Noise Level", + "Motion Level", + "weights", + "Method", + "rescaled", + ], + ) + except KeyError as e: + logger.error(e) + logger.error("Failed to load old metrics information") + # raise e + running_results = all_results + else: + running_results = all_results + running_results.to_csv(metrics_file, mode="w") + + +def main(args): + cfg = setup(args) + model = DefaultTrainer.build_model(cfg) + if isinstance(model, CSModel): + weights, criterion, best_value = None, None, 0 + else: + metric = args.metric if args.metric else f"val_{cfg.MODEL.RECON_LOSS.NAME}" + weights, criterion, best_value = ( + (cfg.MODEL.WEIGHTS, None, None) + if cfg.MODEL.WEIGHTS + else find_weights(cfg, metric, iter_limit=args.iter_limit) + ) + model = model.to(cfg.MODEL.DEVICE) + Checkpointer(model, save_dir=cfg.OUTPUT_DIR).resume_or_load(weights, resume=args.resume) + + # See https://github.com/pytorch/pytorch/issues/42300 + logger.info("Checking weights were properly loaded...") + check_consistency(torch.load(weights)["model"], model) + + logger.info("\n\n==============================") + logger.info("Loading weights from {}".format(weights)) + + # Do not limit number of scans to evaluate during testing. + cfg.defrost() + cfg.DATALOADER.SUBSAMPLE_TRAIN.NUM_VAL = -1 + cfg.freeze() + + eval(cfg, args, model, os.path.basename(weights) if weights else None, criterion, best_value) + + +if __name__ == "__main__": + parser = default_argument_parser() + # parser.add_argument( + # "--dir", type=str, default=None, + # help="Process all completed experiment directories under this directory" + # ) + parser.add_argument( + "--metric", + "--criterion", + type=str, + default="", + help=( + "Val metric used to select weights. " + "Defaults to recon loss. " + "Ignored if `MODEL.WEIGHTS` specified" + ), + ) + parser.add_argument( + "--zero-filled", action="store_true", help="Calculate metrics for zero-filled images" + ) + parser.add_argument( + "--noise", + default="false", + choices=("false", "standard", "sweep"), + help="Type of noise evaluation", + ) + + # Arguments for 2D Motion Corruption of the Dataset + + parser.add_argument( + "--angle", + default=0, + type=float, + help=("How much rotation angle should be used for motion corruption " "of the dataset"), + ) + parser.add_argument( + "--translation", + default=0, + type=float, + help=("How much translation should be used for motion " "corruption of the dataset"), + ) + parser.add_argument( + "--nshots", + default=0, + type=int, + help=("How many shots should be used for motion corruption " "of the dataset."), + ) + parser.add_argument( + "--trajectory", + default="blocked", + choice=("interleaved", "blocked"), + help=( + "Chooses between interleaved or blocked shots for motion " "corruption of the dataset" + ), + ) + parser.add_argument( + "--motion", + default="false", + choices=("false", "true"), + help="Motion corruption included or not", + ) + parser.add_argument( + "--sweep-vals", + default=[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], + nargs="*", + type=float, + help="args to sweep for noise", + ) + parser.add_argument("--extra-metrics", nargs="*", help="Extra metrics for testing") + + parser.add_argument( + "--iter-limit", + default=None, + type=int, + help=( + "Time limit. If negative, interpreted as epoch. " + "Chooses weights at or before this time point." + ), + ) + parser.add_argument("--overwrite", action="store_true", help="Overwrite existing metrics file") + parser.add_argument( + "--skip-rescale", action="store_true", help="Skip rescaling when evaluating" + ) + parser.add_argument("--save-scans", action="store_true", help="Save reconstruction outputs") + parser.add_argument("--metrics-file", type=str, default="metrics.csv", help="Metrics file") + # parser.add_argument( + # "--wandb", action="store_true", help="Log to W&B during evaluation" + # ) + parser.add_argument( + "--ops", + type=str, + nargs="*", + default=["metrics"], + choices=["metrics", "save_scans"], + help="Operations to run. 'metrics': Compute metrics. 'save_scans': Save Scans", + ) + + args = parser.parse_args() + args.ops = set(args.ops) + if args.save_scans: + args.ops |= {"save_scans"} + + print("Command Line Args:", args) + main(args)