Pytorch multilabel classification example¶
In this page, we will show you how to run a multilabel classification experiment exploiting Pytorch and Pytorch Lightning to finetune or train from scratch a model on a custom dataset.
This example will demonstrate how to create a custom experiment starting from default settings.
Training¶
Dataset¶
Let's start with the dataset that we are going to use. Since we are using the multilabel classification datamodule we must follow a precise structure for the dataset.
dataset/
├── images
│ ├── abc.xyz
│ └── ...
├── samples.txt # optional
├── test.txt # optional
├── train.txt # optional
└── val.txt # optional
Either samples.txt
or both train.txt
and test.txt
must be provided. If samples.txt
is provided, it will be used to split the dataset into train/val/test based on the datamodule parameters. Otherwise, train.txt
and val.txt
will be used to split the dataset into train/val and test.txt
will be used to create the test set.
The content of the files is the same for both samples.txt
and train.txt
/val.txt
/test.txt
:
images/abc.xyz,class_1,class_2
images/abc_2.xyz,class_3
So the first column is the path to the image, while the other columns are the labels associated with that image. The labels must be separated by a comma.
The standard datamodule configuration for classification is found under configs/datamodule/base/multilabel_classification.yaml
.
_target_: quadra.datamodules.MultilabelClassificationDataModule
data_path: ???
images_and_labels_file: null
train_split_file: null
test_split_file: null
val_split_file: null
dataset:
_target_: hydra.utils.get_method
path: quadra.datasets.classification.MultilabelClassificationDataset
num_classes: null
num_workers: 8
batch_size: 64
test_batch_size: 64
seed: ${core.seed}
val_size: 0.2
test_size: 0.2
train_transform: ${transforms.train_transform}
test_transform: ${transforms.test_transform}
val_transform: ${transforms.val_transform}
class_to_idx: null
The most important parameters are:
- data_path
: the path to the dataset folder
- images_and_labels_file
: the path to the samples.txt
file
- train_split_file
: the path to the train.txt
file
- test_split_file
: the path to the test.txt
file
- val_split_file
: the path to the val.txt
file
Experiment¶
Suppose that we want to run the experiment on the given dataset, we can define a config starting from the base config (found under configs/experiment/base/classification/multilabel_classification.yaml
).
# @package _global_
defaults:
- override /backbone: resnet18
- override /datamodule: base/multilabel_classification
- override /loss: asl
- override /model: multilabel_classification
- override /optimizer: adam
- override /task: classification
- override /scheduler: rop
- override /transforms: default_resize
datamodule:
num_workers: 8
batch_size: 32
test_batch_size: 32
print_config: true
core:
tag: "run"
test_after_training: true
upload_artifacts: true
name: multilabel-classification
logger:
mlflow:
experiment_name: ${core.name}
run_name: ${core.name}
backbone:
model:
pretrained: True
freeze: False
trainer:
devices: [0]
max_epochs: 300
check_val_every_n_epoch: 1
The base experiment will train a resnet18 (by default pretrained on Imagenet) for 300 epochs using Adam as optimizer and reducing the learning rate on plateaus. In we give a look inside the model configuration we will find that on top of the backbone there is a simple Linear layer mapping the output of the backbone to the number of classes.
We can define a custom experiment starting from the base one, and override the parameters that we want to change. Suppose we create a yaml configuration under configs/experiment/custom_experiment/torch_multilabel_classification.yaml
with the following content:
# @package _global_
defaults:
- base/classification/multilabel_classification
- override /backbone: vit16_tiny
- _self_
datamodule:
num_workers: 12
batch_size: 32
data_path: path/to/experiment/dataset
images_and_labels_file: ${datamodule.data_path}/samples.txt # We make use of hydra variable interpolation
class_to_idx:
class_1: 0
class_2: 1
class_3: 2
model:
classifier:
out_features: 3 # This is very important as it defines the number of classes
task:
run_test: True # Perform test evaluation at the end of training
report: False
output:
example: False
logger:
mlflow:
experiment_name: name_of_the_experiment
run_name: ${core.name}
Warning
At the current time the report generation is not supported for multilabel classification.
Run¶
Assuming that you have created a virtual environment and installed the quadra
library, you can run the experiment by running the following command:
quadra experiment=custom_experiment/torch_multilabel_classification
This should produce the following output files:
checkpoints config_resolved.yaml config_tree.txt data deployment_model main.log
Where checkpoints
contains the pytorch lightning checkpoints of the model, data
contains the joblib dump of the datamodule with its parameters and dataset split, deployment_model
contains the model in exported format (default is torchscript).