Semantic segmentation ===================== .. automodule:: remote_sensing_processor.semantic :members: generate_tiles, train, test, generate_map, band_importance, confusion_matrix :show-inheritance: List of available NN models --------------------------- .. list-table:: Supported ML Models :widths: 25 50 25 :header-rows: 1 * - Model Name - Backbone - Reference * - BEiT - Not available - `Huggingface Transformers `_ * - ConditionalDETR - See Transformers backbones - `Huggingface Transformers `_ * - Data2Vec - Not available - `Huggingface Transformers `_ * - DETR - See Transformers backbones - `Huggingface Transformers `_ * - DPT - Not available - `Huggingface Transformers `_ * - EoMT - See Transformers backbones - `Huggingface Transformers `_ * - EoMT-DINOv3 - See Transformers backbones - `Huggingface Transformers `_ * - Mask2Former - See Transformers backbones - `Huggingface Transformers `_ * - MaskFormer - See Transformers backbones - `Huggingface Transformers `_ * - MobileNetV2 - Not available - `Huggingface Transformers `_ * - MobileViT - Not available - `Huggingface Transformers `_ * - MobileViTV2 - Not available - `Huggingface Transformers `_ * - OneFormer - See Transformers backbones - `Huggingface Transformers `_ * - SegFormer - Not available - `Huggingface Transformers `_ * - UperNet - See Transformers backbones - `Huggingface Transformers `_ * - DeepLabV3 - "MobileNet_V3_Large", "ResNet50", "ResNet101" - `Torchvision `_ * - FCN - "ResNet50", "ResNet101" - `Torchvision `_ * - LRASPP - Not available - `Torchvision `_ * - UNet - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - UNet++ - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - FPN - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - PSPNet - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - DeepLabV3_smp - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - DeepLabV3+ - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - Linknet - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - MAnet - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - PAN - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - UperNet_smp - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - SegFormer_smp - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - DPT_smp - `SMP `_ and `TIMM `_ - `Segmentation Models Pytorch `_ * - FarSeg - "resnet18", "resnet34", "resnet50", "resnet101" - `TorchGeo `_ Transformers backbones are: - BEiT - BiT - ConvNeXT - ConvNeXTV2 - DiNAT - DINOV2 - DINOV2WithRegisters - DINOV3ViT - DINOV3ConvNeXT - FocalNet - HGNet-V2 - Hiera - LW-DETR - MaskFormer-Swin - Pixio - PVTV2 - ResNet - RT-DETR-ResNet - Swin - SwinV2 - ViTDet - Any TIMM backbone (experimental support) You can fine-tune pre-trained model by defining ``weights``. For models from Transformers you can get available weights from `Huggingface Hub `_, for Torchvision models you just set ``weights = True``. ``rsp.segmentation.train`` also saves CSV and Tensorboard logs in directory where checkpoint file is saved. DiNAT backbone require ``natten`` library, that is not available on Windows and Mac and not available via Conda. RSP supports DiNAT backbone, but you need to install ``natten`` in your python env manually. List of available Scikit-learn models ------------------------------------- .. list-table:: Supported Scikit-Learn Models :widths: 20 40 20 20 :header-rows: 1 * - Model Name - Kernel/solver - Warm start - Reference * - Logistic Regression - "lbfgs", "liblinear", "newton-cg", "newton-cholesky", "sag", "saga" - Only for lbfgs, newton-cg, sag, saga solvers - `Scikit-learn `_ * - Ridge - Not available - Not supported - `Scikit-learn `_ * - SGD - "hinge", "log_loss", "modified_huber", "squared_hinge", "perceptron" - Supported - `Scikit-learn `_ * - Nearest Neighbors - Not available - Not supported - `Scikit-learn `_ * - Radius Neighbors - Not available - Not supported - `Scikit-learn `_ * - SVM - "rbf", "linear", "poly", "sigmoid" - Not supported - `Scikit-learn `_ * - Gaussian Process - Not available - Not supported - `Scikit-learn `_ * - Naive Bayes - "gaussian", "bernoulli", "categorical", "complement", "multinomial" - Not supported - `Scikit-learn `_ * - QDA - Not available - Not supported - `Scikit-learn `_ * - LDA - Not available - Not supported - `Scikit-learn `_ * - Decision Tree - Not available - Not supported - `Scikit-learn `_ * - Extra Tree - Not available - Not supported - `Scikit-learn `_ * - Random Forest - Not available - Supported - `Scikit-learn `_ * - Extra Trees - Not available - Supported - `Scikit-learn `_ * - AdaBoost - Not available - Not supported - `Scikit-learn `_ * - Gradient Boosting - Not available - Supported - `Scikit-learn `_ * - Multilayer Perceptron - "adam", "sgd", "lbfgs" - Supported - `Scikit-learn `_ * - XGBoost - Not available - Not supported - `XGBoost `_ * - XGB Random Forest - Not available - Not supported - `XGBoost `_ Model kernel or solver is defined with ``backbone`` argument. Models that support warm start can be fine-tuned using pre-trained models with ``checkpoint`` argument. Some models can have issues while saving, especially when trained on big datasets. Some models (like SVM) can train for a very long time or (like Gaussian process) can have memory issues with big datasets. So we recommend using Scikit-learn models only for small datasets. For Random Forest and Extra Trees models ``max_depth`` is by default set to 6, because it is unlimited by default and the training could be very slow. To train with unlimited tree depth ``set max_depth = None``. List of available losses ------------------------ .. list-table:: Supported loss functions :widths: 50 50 :header-rows: 1 * - Loss - Reference * - cross_entropy - `Torch `_ * - nll - `Torch `_ * - jaccard - `Segmentation Models Pytorch `_ * - dice - `Segmentation Models Pytorch `_ * - tversky - `Segmentation Models Pytorch `_ * - focal - `Segmentation Models Pytorch `_ * - lovasz - `Segmentation Models Pytorch `_ You can also use your custom loss. It can be useful if you want to initialize a loss with custom parameters. You also can pass any custom function as a loss. The only limit - it must inherit ``torch.nn.modules.loss._Loss``. .. code-block:: python # Here we just use one of the default losses loss = "tversky" # Here we initialize a loss that is already supported, but set the custom parameters # Don't forget to add the "mode" and "ignore_index" parameters loss = segmentation_models_pytorch.losses.FocalLoss( mode="multiclass", ignore_index=0, alpha=0.25, normalized=True, reduced_threshold=0.5, ) # And here we use the loss that is not supported by default loss = monai.losses.GeneralizedDiceFocalLoss() # And here we create our own custom loss function from torch.nn.modules.loss import _Loss class SoftBCEWithLogitsLoss(_Loss): """ Drop-in replacement for nn.BCEWithLogitsLoss with few additions: - Support of ignore_index value - Support of label smoothing Copied from https://github.com/BloodAxe/pytorch-toolbelt """ __constants__ = ["weight", "pos_weight", "reduction", "ignore_index", "smooth_factor"] def __init__( self, weight=None, ignore_index: Optional[int] = -100, reduction="mean", smooth_factor=None, pos_weight=None ): super().__init__() self.ignore_index = ignore_index self.reduction = reduction self.smooth_factor = smooth_factor self.register_buffer("weight", weight) self.register_buffer("pos_weight", pos_weight) def forward(self, input: Tensor, target: Tensor) -> Tensor: if self.smooth_factor is not None: soft_targets = ((1 - target) * self.smooth_factor + target * (1 - self.smooth_factor)).type_as(input) else: soft_targets = target.type_as(input) loss = F.binary_cross_entropy_with_logits( input, soft_targets, self.weight, pos_weight=self.pos_weight, reduction="none" ) if self.ignore_index is not None: not_ignored_mask: Tensor = target != self.ignore_index loss *= not_ignored_mask.type_as(loss) if self.reduction == "mean": loss = loss.mean() if self.reduction == "sum": loss = loss.sum() return loss loss = SoftBCEWithLogitsLoss(ignore_index=0, smooth_factor=0.5) List of available metrics ------------------------- .. list-table:: Supported metrics :widths: 40 30 30 :header-rows: 1 * - Metric - Additional parameters - Reference * - accuracy_macro - average="macro" - `Torchmetrics `_ * - accuracy_micro - average="micro" - `Torchmetrics `_ * - cohen_kappa - None - `Torchmetrics `_ * - exact_math - None - `Torchmetrics `_ * - f1_macro - average="macro" - `Torchmetrics `_ * - f1_micro - average="micro" - `Torchmetrics `_ * - hamming_distance_macro - average="macro" - `Torchmetrics `_ * - hamming_distance_micro - average="micro" - `Torchmetrics `_ * - jaccard_index_macro - average="macro" - `Torchmetrics `_ * - jaccard_index_micro - average="micro" - `Torchmetrics `_ * - matthews_correlation_coefficient - None - `Torchmetrics `_ * - negative_predictive_value_macro - average="macro" - `Torchmetrics `_ * - negative_predictive_value_micro - average="micro" - `Torchmetrics `_ * - precision_macro - average="macro" - `Torchmetrics `_ * - precision_micro - average="micro" - `Torchmetrics `_ * - recall_macro - average="macro" - `Torchmetrics `_ * - recall_micro - average="micro" - `Torchmetrics `_ * - dice_score_macro - average="macro" - `Torchmetrics `_ * - dice_score_micro - average="micro" - `Torchmetrics `_ * - generalized_dice_score - None - `Torchmetrics `_ * - mean_iou - None - `Torchmetrics `_ For most of the semantic segmentation metrics micro and macro-averaged versions are available by default. You also can use any custom metric for evaluation. The only limit - it must inherit ``torchmetrics.metric.Metric``. .. code-block:: python # A custom metric (top-2 accuracy) - a supported metric, but with custom parameter - ``top-k=2`` # Don't forget to set task, num_classes and ignore_index a_micro_2 = torchmetrics.Accuracy( task="multiclass", num_classes=10, average="micro", ignore_index=0, top_k=2, ) # A custom metric (f-beta score) - a metric, that is not supported by default # Don't forget to set task, num_classes and ignore_index f_beta = torchmetrics.FBetaScore( task="multiclass", beta=2.0, num_classes=10, average="micro", ignore_index=0, ) metrics=[ {"name": "accuracy_micro", "log": "verbose"}, # Supported metric, logged on each step and printed in the progress bar {"name": "accuracy_macro", "log": "step"}, # Supported metric, logged each step and saved to logs {"name": "mean_iou", "log": "epoch"}, # Supported metric, logged each epoch and saved to logs {"name": "accuracy_micro_2", "metric": a_micro_2, "log": "verbose"}, # A custom metric {"name": "f_beta_2", "metric": f_beta, "log": "step"}, # Another custom metric ] Supported augmentations ----------------------- .. list-table:: Supported augmentations :widths: 40 30 30 :header-rows: 1 * - Augmentation - Additional parameters - Reference * - ScaleJitter - None - `Torchvision `_ * - RandomResizedCrop - antialias=True - `Torchvision `_ * - RandomHorizontalFlip - p=0.5 - `Torchvision `_ * - RandomVerticalFlip - p=0.5 - `Torchvision `_ * - RandomZoomOut - None - `Torchvision `_ * - RandomRotation - degrees=90 - `Torchvision `_ * - RandomAffine - degrees=90, translate=(0.5, 0.5), shear=0.5 - `Torchvision `_ * - RandomPerspective - None - `Torchvision `_ * - ElasticTransform - None - `Torchvision `_ * - GaussianBlur - kernel_size=(5, 9) - `Torchvision `_ If you just pass ``augment=True``, RSP will use a default sequence of augmentations: ("RandomResizedCrop", "RandomHorizontalFlip"). You can pass your own sequence of augmentations, they will be applied to data in the given order. You can use both supported augmentation names or custom augmentations. You can use any custom augmentations, but they must inherit ``torchvision.transforms.v2.Transform``. .. code-block:: python augment = ( "RandomResizedCrop", # Supported augmentation name v2.ScaleJitter(target_size=(128, 128), scale_range=(0.5, 1.5)) # Custom augmentation - a supported one with custom parameter v2.RandomRotation(45, fill={tv_tensors.Image: 0, tv_tensors.Mask: 0}) # Custom augmentation - a supported one with custom parameter v2.RandomSolarize(), # Custom augmentation - not supported by default, works only with 3-channel images )