WSI dataset
torchmil.datasets.WSIDataset
Bases: ProcessedMILDataset
This class represents a dataset of Whole Slide Images (WSI) for Multiple Instance Learning (MIL).
MIL and WSIs. Whole Slide Images (WSIs) are high-resolution images of tissue samples used in digital pathology. Due to their large size, WSIs are usually divided into smaller patches. In the context of MIL, a WSI is considered a bag, and the patches are considered instances.
Patch and feature extraction. Different tools are available to obtain the previous directory structure from a set of WSIs. For example, given a set of WSIs in the original format (e.g., .tif extension), patches can be extracted using tools such as CLAM. This tool outputs the coordinates of the patches, which can be used to extract the patches from the WSIs. Then, a feature vector can be extracted from each patch using a pretrained model.
Binary MIL for WSIs.
In binary classification, the label \(Y\) of the WSI usually represents the presence (\(Y=1\)) or absence (\(Y=0\)) of a certain characteristic in the WSI.
This characteristic can be present in one or more patches of the WSI, but the exact location of the characteristic is unknown.
This translates into a patch having an unknown label \(y_n\), which is positive (\(y_n=1\)) if it contains the characteristic, and negative (\(y_n=0\)) otherwise.
Consequently, \(Y = \max\left\{ y_1, y_2, \ldots, y_N \right\}\), where \(N\) is the number of patches in the WSI.
This means that the WSI is positive (contains the characteristic) if at least one of its patches is positive (contains the characteristic).
In the case that the WSI has been annotated at the patch level, the instance labels \(y_n\) can be used solely for evaluation purposes.
See torchmil.datasets.BinaryClassificationDataset
for more information.
Directory structure.
It is assumed that the bags have been processed and saved as numpy files.
For more information on the processing of the bags, refer to the ProcessedMILDataset
class.
This dataset expects the following directory structure:
features_path
├── wsi1.npy
├── wsi2.npy
└── ...
labels_path
├── wsi1.npy
├── wsi2.npy
└── ...
inst_labels_path
├── wsi1.npy
├── wsi2.npy
└── ...
coords_path
├── wsi1.npy
├── wsi2.npy
└── ...
Adjacency matrix. If the coordinates of the patches are available, an adjacency matrix representing the spatial relationships between the patches is built.
where \(\mathbf{c}_i\) and \(\mathbf{c}_j\) are the coordinates of the patches \(i\) and \(j\), respectively, \(\text{dist_thr}\) is a threshold distance,
and \(\mathbf{x}_i \in \mathbb{R}^d\) and \(\mathbf{x}_j \in \mathbb{R}^d\) are the features of patches \(i\) and \(j\), respectively.
If no dist_thr
is provided, it is set to \(\sqrt{2} \times \text{patch_size}\).
__init__(features_path, labels_path, patch_labels_path=None, coords_path=None, wsi_names=None, bag_keys=['X', 'Y', 'y_inst', 'adj', 'coords'], patch_size=512, dist_thr=None, adj_with_dist=False, norm_adj=True, load_at_init=True)
Class constructor.
Parameters:
-
features_path
(str
) –Path to the directory containing the feature matrices of the WSIs.
-
labels_path
(str
) –Path to the directory containing the labels of the WSIs.
-
patch_labels_path
(str
, default:None
) –Path to the directory containing the labels of the patches.
-
coords_path
(str
, default:None
) –Path to the directory containing the coordinates of the patches.
-
wsi_names
(list
, default:None
) –List of the names of the WSIs to load. If None, all the WSIs in the
features_path
directory are loaded. -
bag_keys
(list
, default:['X', 'Y', 'y_inst', 'adj', 'coords']
) –List of keys to use for the bags. Must be in ['X', 'Y', 'y_inst', 'coords'].
-
patch_size
(int
, default:512
) –Size of the patches.
-
dist_thr
(float
, default:None
) –Distance threshold for building the adjacency matrix. If None, it is set to
sqrt(2) * patch_size
. -
adj_with_dist
(bool
, default:False
) –If True, the adjacency matrix is built using the Euclidean distance between the patches features. If False, the adjacency matrix is binary.
-
norm_adj
(bool
, default:True
) –If True, normalize the adjacency matrix.
-
load_at_init
(bool
, default:True
) –If True, load the bags at initialization. If False, load the bags on demand.
__getitem__(index)
Parameters:
-
index
(int
) –Index of the bag to retrieve.
Returns:
-
bag_dict
(TensorDict
) –Dictionary containing the keys defined in
bag_keys
and their corresponding values.- X: Features of the bag, of shape
(bag_size, ...)
. - Y: Label of the bag.
- y_inst: Instance labels of the bag, of shape
(bag_size, ...)
. - adj: Adjacency matrix of the bag. It is a sparse COO tensor of shape
(bag_size, bag_size)
. Ifnorm_adj=True
, the adjacency matrix is normalized. - coords: Coordinates of the bag, of shape
(bag_size, coords_dim)
.
- X: Features of the bag, of shape