Configuration#
Empanada uses YAML to define training and inference parameters.
Training#
There are four sections to the training config: DATASET
, MODEL
, TRAIN
and EVAL
.
The DATASET
section gives a name to the training dataset, names the classes that will be segmented
and lists the ids of classes that require instance segmentation.
An example for instance segmentation of a single class:
DATASET:
# name of dataset tracked by MLFLOW (see Logging in docs)
dataset_name: "Mitochondria"
# name of the segmentation class
class_names: [ "mito" ]
# only 1 segmentation class, id == 1
labels: [ 1 ]
# the 1 segmentation class has instances
thing_list: [ 1 ]
# pixel mean and std in dataset images
norms: { mean: 0.508979, std: 0.148561 }
An example for true panoptic segmentation:
DATASET:
dataset_name: "Organelles"
# name of the segmentation class
class_names: [ "er", "nuclei", "vesicles", "mito" ]
# the four segmentation classes
labels: [ 1, 2, 3, 4 ]
# ER is semantic, all the others are instance
thing_list: [ 2, 3, 4 ]
norms: { mean: 0.577841, std: 0.114811 }
The MODEL
section provides arguments to the model class. Any model arg or kwarg can be
added to the config file and passed to the model during training.
MODEL:
# name of the model architecture
arch: "PanopticDeepLabPR"
# the encoder network to use
encoder: "resnet50"
# kwargs for this particular model architecture
num_classes: 1
stage4_stride: 16
decoder_channels: 256
low_level_stages: [ 1 ]
low_level_channels_project: [ 32 ]
atrous_rates: [ 2, 4, 6 ]
aspp_channels: null
aspp_dropout: 0.5
ins_decoder: True
ins_ratio: 0.5
The TRAIN
section defines all parameters used to train the model, it’s pretty extensive to
allow for maximum flexibility.
TRAIN:
# name of the run stored in MLFLOW under "dataset_name"
run_name: "Panoptic DeepLab PR Baseline"
# Directories containing images and masks for the segmentation
# task. Multiple directories can be appended to the main train_dir
train_dir: "mitochondria_data"
additional_train_dirs: [ "new_mitochondria_data" ]
# directory to save models to
# and epochs between saving
model_dir: "pdlpr_baselines/"
save_freq: 1
# path to .pth file for resuming training
resume: null
# encoder pretrained weights
encoder_pretraining: "cem1.5m_swav_resnet50_200ep_balanced.pth.tar"
# pretrained weights for the entire model, useful for finetuning
whole_pretraining: null
# layers in the encoder to finetune, choice of
# "all", "none", "stage1", "stage2", "stage3", "stage4"
finetune_layer: "all"
# the learning rate schedule,
# see torch.optim.lr_scheduler
lr_schedule: "OneCycleLR"
schedule_params:
max_lr: 0.003
epochs: 30
steps_per_epoch: 339
pct_start: 0.3
# automatic mixed precision
amp: True
# setup the optimizer, see torch.optim
optimizer: "AdamW"
optimizer_params:
weight_decay: 0.1
# parameters to pass to the PDL loss function, see empanada.losses
criterion_params:
ce_weight: 1
mse_weight: 200
l1_weight: 0.01
top_k_percent: 0.2
confidence_loss: False
cl_weight: 0.1
pr_weight: 1
# training performance metric to track, see empanada.metrics
print_freq: 50
metrics: [ "IoU" ]
metric_params:
topk: 1
# dataset and dataloader parameters, see empanada.data
batch_size: 64
dataset_class: "SingleClassInstanceDataset"
weight_gamma: 0.3
workers: 8
# augmentations to apply to images,
# nearly any in albumentations are supported
augmentations:
# aug name and kwargs
- { aug: "RandomScale", scale_limit: [ -0.9, 1 ]}
- { aug: "PadIfNeeded", min_height: 256, min_width: 256, border_mode: 0 }
- { aug: "RandomCrop", height: 256, width: 256}
- { aug: "Rotate", limit: 180, border_mode: 0 }
- { aug: "RandomBrightnessContrast", brightness_limit: 0.3, contrast_limit: 0.3 }
- { aug: "HorizontalFlip" }
- { aug: "VerticalFlip" }
# parameters for multi-GPU training
multiprocessing_distributed: False
gpu: null
world_size: 1
rank: 0
dist_url: "tcp://localhost:10001"
dist_backend: "nccl"
The EVAL
section handles the evaluation of the model during training. It’s an optional
section. Setting aside a validation dataset is useful for tuning training parameters though.
EVAL:
eval_dir: "eval_mitochondria"
# track segmentation of particular images in the
# evaluation data, stored in MLFLOW
eval_track_indices: [ 10, 32, 19, 7 ]
# how often to record segmentations
eval_track_freq: 10
# epochs between evaluation
epochs_per_eval: 1
# parameters needed for eval_metrics
# see empanada.metrics
metrics: [ "IoU", "PQ", "F1" ]
metric_params:
topk: 1
labels: [ 1 ]
label_divisor: 1000
iou_thr: 0.5
# parameters used for panoptic inference
# see empanada.inference.engines
engine_params:
thing_list: [ 1 ]
label_divisor: 1000
stuff_area: 64
void_label: 0
nms_threshold: 0.1
nms_kernel: 7
confidence_thr: 0.5
Inference#
The config file for model inference has only a single section and is less complicated than the training config.
# axes to predict for 3d
# for stack inference, just 'xy'
axes: [ 'xy', 'xz', 'yz' ]
# list of all segmentation labels
labels: [ 1 ]
# parameters for the inference engine
# see empanada.inference.engines
engine_params:
median_kernel_size: 7
thing_list: [ 1 ]
label_divisor: 20000
stuff_area: 64
void_label: 0
nms_threshold: 0.1
nms_kernel: 7
confidence_thr: 0.3
input_scale: 1
scales: [ 1 ]
# parameters for instance matching
# across 2d images
matcher_params:
merge_iou_thr: 0.25
merge_ioa_thr: 0.25
force_connected: True
# parameters for the consensus algorithm
consensus_params:
pixel_vote_thr: 0.5
cluster_iou_thr: 0.75
# object filters, see empanada.inference.filters
filters:
- { name: "remove_small_objects", min_size: 500 }
- { name: "remove_pancakes", min_span: 4 }
Inheritance#
Fortunately, defining a training config file from scratch is almost never necessary. To modify one or a few parameters just
add the BASE
key to the top of the config file and point it to the parent config file. Any parameters that you define
in this new config file will overwrite the parameters in the BASE
config, everything else gets inherited.
For example, to change the number of training epochs used by the OneCycle policy, the complete config file would look like this:
BASE: "path_to_parent_training.yaml"
TRAIN:
# not necessary to change the run name
# but it makes tracking experiments easier
run_name: "Panoptic DeepLab PR Baseline - 100 Epochs"
schedule_params:
epochs: 100
Or the change the median filter size for inference:
BASE: "path_to_parent_inference.yaml"
engine_params:
median_kernel_size: 3
Inheritance is a powerful way to test many different configurations with minimal effort and should be used as often as possible. An arbitrary number of levels are possible too; for example, a config file can inherit from another file that also uses inheritance.