TRUSWorthy: Towards Clinically Applicable Deep Learning for Confident Detection of Prostate Cancer in Micro-Ultrasound
This code represents a significant portion of the code used to generate the results for our paper. The models are implemented in projects/TRUS_ViT/models. There are several types of models implemented:
-
The ResNet (dubbed
ResNet10in the code) model is implemented insrc/modeling/registry.py, and a wrapperResNet10Experimentis provided inprojects/TRUS_ViT/models/resnet.pyfor training, validation, and testing. -
SSL+ResNet uses the same ResNet10 backbone as above, but is trained using the logic of
projects/TRUS_ViT/models/vicreg.py. -
The TRUSformer architecture uses the SSL+ResNet architecture as a feature extractor, and the
TransformerEncoder(BERT) architecture implemented insrc/modeling/bert.pyas a MIL aggregator.
To train a single-model architecture, we use the bash scripts located in projects/TRUS_ViT/job_submission. These scripts parse a set of hyperparameters outlined in a .yaml file in projects/TRUS_ViT/experiments. For example:
augmentations_mode: tensor_augs
batch_size: 64
device: cuda
fold: 0
lr: 3e-4
model_name: resnet10
num_epochs: 25
seed: 42To train an
python main.py experiment=resnet10 seed=42 fold=0
python main.py experiment=resnet10 seed=81 fold=0
python main.py experiment=resnet10 seed=881 fold=0
python main.py experiment=resnet10 seed=392 fold=0
python main.py experiment=resnet10 seed=659 fold=0The code above trains an ensemble of 5 ResNets on folds 1,2,3,4 and evaluates it on fold 0.
We can also train an ensemble of TRUSformers using:
python main.py experiment=trusformer seed=42 fold=0
python main.py experiment=trusformer seed=81 fold=0
python main.py experiment=trusformer seed=881 fold=0
python main.py experiment=trusformer seed=392 fold=0
python main.py experiment=trusformer seed=659 fold=0We can train a TRUSWorthy model using the same code presented above. The only difference is that we are also resampling the set of benign cores seen by the model during training using the same seed specified in the experiment .yaml file.
To enable this, we use the mix_ens flag, which sends the seed to the data loader to be used during sampling (when mix_ens=false, the data loader's seed is set to 0).
python main.py experiment=trusformer mix_ens=true seed=42 fold=0
python main.py experiment=trusformer mix_ens=true seed=81 fold=0
python main.py experiment=trusformer mix_ens=true seed=881 fold=0
python main.py experiment=trusformer mix_ens=true seed=392 fold=0
python main.py experiment=trusformer mix_ens=true seed=659 fold=0We summarize the full range of hyperparameters used for every component of the model (VICReg,ResNet,TRUSformer, Mixed Ensembling) below, and indicate the final combination of hyperparameters used. The hyperparameters live in the .yaml files in the experiments folders. We provide more details on each hyperparameter in the subsections below.
VICReg
lr: 1e-4, 1e-5
scheduler: none, cosine
batch_size: 16, 32, 64
optimizer: adam, novograd
augmentations_mode: bothResNet
lr: 1e-4, 1e-5
scheduler: none, cosine
batch_size: 16, 32, 64
optimizer: adam, novograd
benign_to_cancer_ratio: 1, 2, 5
augmentations_mode: none, tensor_augs,
ultrasound_augs, bothTRUSformer (single-model)
lr: 1e-4, 1e-5
scheduler: none, cosine
batch_size: 8
optimizer: adam, novograd
benign_to_cancer_ratio: 1, 2, 5
augmentations_mode: noneTRUSWorthy (mixed ens.)
lr: 1e-4, 1e-5
scheduler: none, cosine
batch_size: 8
optimizer: adam, novograd
# the following hyperparams are external (see above)
number of members: 4, 6, 8, 10VICReg:
lr: 1e-4, 1e-5
scheduler: cosine
batch_size: 64
optimizer: novograd
num_epochs: 200 # we use early stopping
ResNet:
lr: 1e-5
scheduler: none
batch_size: 64
optimizer: adam
num_epochs: 15
benign_to_cancer_ratio: 2
augmentations_mode: tensor_augs
TRUSformer:
lr: 1e-4
scheduler: none
batch_size: 8
optimizer: novograd
num_epochs: 75 # early stopping
benign_to_cancer_ratio: 2
augmentations_mode: noneTo tune a hyperparameter .yaml file.
Once we establish the best value for
For our purposes, we started with the learning rate (and the schedulers), then the batch size, then the optimizers. We also tuned the type of data augmentations (augmentations_mode), the number of epochs, and the undersampling ratio.
By default,
cross_val: trueTo perform leave-one-center-out cross-validation, the following combination of parameters should be used:
cross_val: true
kfold_centerwise: trueAfter we train
This logic is presented in notebooks/trusworthy_results.ipynb. We are unable to share the result files themselves at this time.
