To fine-tune a SatlasPretrain model on a custom dataset (like UCMerced) using Torchgeo, you should extend the ClassificationTask class.
In the configure_models method, you must:
- Load the model using
swin_v2_b with the Swin_V2_B_Weights.SENTINEL2_RGB_SI_SATLAS weights. - Adjust the first layer's input channels to match your task's input requirements.
- Replace the model's head with a new
torch.nn.Linear layer that matches your number of classes.
Example implementation:
from torchgeo.trainers import ClassificationTask
from torchgeo.models import Swin_V2_B_Weights, swin_v2_b
import torch
class SatlasClassificationTask(ClassificationTask):
def configure_models(self):
# Load pretrained Satlas weights
weights = Swin_V2_B_Weights.SENTINEL2_RGB_SI_SATLAS
self.model = swin_v2_b(weights)
# Replace first layer's input channels
first_layer = self.model.features[0][0]
self.model.features[0][0] = torch.nn.Conv2d(
3, # Number of input channels
first_layer.out_channels,
kernel_size=first_layer.kernel_size,
stride=first_layer.stride,
padding=first_layer.padding,
bias=(first_layer.bias is not None)
)
# Replace last layer's output features with the number of classes
self.model.head = torch.nn.Linear(
in_features=1024,
out_features=self.hparams["num_classes"],
bias=True
)
def on_validation_epoch_end(self):
# Accessing metrics logged during the current validation epoch
val_loss = self.trainer.callback_metrics.get('val_loss', 'N/A')
val_acc = self.trainer.callback_metrics.get('val_OverallAccuracy', 'N/A')
print(f"Epoch {self.current_epoch} Validation - Loss: {val_loss}, Accuracy: {val_acc}")
# Usage
task = SatlasClassificationTask(num_classes=21)
class SatlasClassificationTask(ClassificationTask):
def configure_models(self):
weights = Swin_V2_B_Weights.SENTINEL2_RGB_SI_SATLAS
self.model = swin_v2_b(weights)
first_layer = self.model.features[0][0]
self.model.features[0][0] = torch.nn.Conv2d(3,
first_layer.out_channels,
kernel_size=first_layer.kernel_size,
stride=first_layer.stride,
padding=first_layer.padding,
bias=(first_layer.bias is not None))
self.model.head = torch.nn.Linear(in_features=1024, out_features=self.hparams["num_classes"], bias=True)