### Install TorchGeo from Git Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Install the torchgeo package from its GitHub repository to ensure you have the latest version, which is necessary for Satlas weights. ```bash pip install git+https://github.com/microsoft/torchgeo ``` -------------------------------- ### Multi-label Classification Head Example Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Shows how to initialize a model with a multi-label classification head using a pretrained Aerial SwinB model. Targets are provided as multi-hot binary vectors. ```python from satlaspretrain_models.utils import Head import satlaspretrain_models, torch weights_manager = satlaspretrain_models.Weights() # Multi-label classification head example model = weights_manager.get_pretrained_model( "Aerial_SwinB_SI", fpn=True, head=Head.MULTICLASSIFY, num_categories=17 ) tensor = torch.rand((2, 3, 512, 512)) # Targets: multi-hot binary vectors (float) targets = torch.zeros((2, 17), dtype=torch.float32) targets[0, [3, 7]] = 1.0 model.train() output, loss = model(tensor, targets) print(output.shape) # torch.Size([2, 17]) — sigmoid probabilities per class ``` -------------------------------- ### Initiate Model Training Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Starts the model training process using the specified task and datamodule. This is the primary command to begin the training loop. ```python trainer.fit(model=task, datamodule=datamodule) ``` -------------------------------- ### Instance Segmentation Head Example Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Demonstrates initializing a model with an instance segmentation head using a pretrained Sentinel-2 SwinB model. The model is trained with bounding boxes, labels, and masks. ```python from satlaspretrain_models.utils import Head import satlaspretrain_models, torch weights_manager = satlaspretrain_models.Weights() # Instance segmentation head example model = weights_manager.get_pretrained_model( "Sentinel2_SwinB_SI_RGB", fpn=True, head=Head.INSTANCE, num_categories=3 ) tensor = torch.rand((1, 3, 512, 512)) targets = [{ 'boxes': torch.tensor([[50., 50., 100., 100.]]), 'labels': torch.tensor([1]), 'masks': torch.zeros((1, 512, 512), dtype=torch.uint8) }] model.train() detections, loss = model(tensor, targets) print(detections[0].keys()) # dict_keys(['boxes', 'labels', 'scores', 'masks']) print(loss.item()) ``` -------------------------------- ### Install SatlasPretrain Models Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Install the SatlasPretrain Models library using conda and pip. Ensure you are using Python 3.9. ```bash conda create --name satlaspretrain python==3.9 conda activate satlaspretrain pip install satlaspretrain-models ``` -------------------------------- ### Import Necessary Libraries Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Imports essential libraries for data handling, model training, and visualization. Ensure these are installed before running the code. ```python import io import os import torch import zipfile import requests import torch.nn import torchvision from torch.utils.data import Dataset, DataLoader import satlaspretrain_models ``` -------------------------------- ### Initialize Adam Optimizer Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Sets up the Adam optimizer for model training. The learning rate is set to 0.0001. ```python # Optimizer optimizer = torch.optim.Adam(model.parameters(), lr=0.0001) ``` -------------------------------- ### Initialize PyTorch Lightning Trainer Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Configure and initialize the PyTorch Lightning `Trainer` with appropriate settings for acceleration (GPU or CPU), logging directory, and training epochs. `fast_dev_run` is set to False for a full run. ```python # Initialize the training code. accelerator = "gpu" if torch.cuda.is_available() else "cpu" default_root_dir = os.path.join(tempfile.gettempdir(), "experiments") trainer = Trainer( accelerator=accelerator, default_root_dir=default_root_dir, fast_dev_run=fast_dev_run, log_every_n_steps=1, min_epochs=1, max_epochs=max_epochs, ) ``` -------------------------------- ### Import Necessary Libraries Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Import required modules from PyTorch, TorchGeo, and Lightning for model training and data handling. ```python import os import torch import tempfile from typing import Optional from lightning.pytorch import Trainer from torchgeo.models import Swin_V2_B_Weights, swin_v2_b from torchgeo.datamodules import UCMercedDataModule from torchgeo.trainers import ClassificationTask ``` -------------------------------- ### Initialize Model with Backbone, FPN, and Segmentation Head Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Initializes a model with a Swin Transformer Base backbone, FPN, and a segmentation head. The model is configured for random initialization and trained with segmentation targets. ```python model = Model( num_channels=3, multi_image=False, backbone=Backbone.SWINB, fpn=True, head=Head.SEGMENT, num_categories=6, # 6 land-cover classes weights=None # random initialization ) tensor = torch.rand((2, 3, 512, 512)) seg_targets = torch.zeros((2, 512, 512), dtype=torch.long) # per-pixel class indices model.train() output, loss = model(tensor, seg_targets) print(output.shape) # torch.Size([2, 6, 512, 512]) — softmax class probabilities print(loss.item()) # cross-entropy loss value ``` -------------------------------- ### Initialize Model with Random Weights Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Construct a `Model` instance with randomly initialized weights. This is useful for custom training pipelines where pretrained weights are not required. ```python import satlaspretrain_models from satlaspretrain_models.model import Model from satlaspretrain_models.utils import Backbone, Head import torch ``` -------------------------------- ### Initialize Pretrained Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Initializes a pretrained SatlasPretrain model using Swin-v2-Base Sentinel-2 image weights for the EuroSAT classification task. ```python # Initialize a pretrained model, using the SatlasPretrain single-image Swin-v2-Base Sentinel-2 image model weights ``` -------------------------------- ### Initialize Weights Manager Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Instantiate the Weights manager to load pretrained models. This is the first step before specifying a model identifier. ```python import satlaspretrain_models import torch weights_manager = satlaspretrain_models.Weights() ``` -------------------------------- ### Load Backbone + FPN + Detection Head Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Load a pretrained model with FPN and a detection head for Landsat multi-image input. Input is normalized Landsat B1-B11. The output includes bounding boxes, labels, and scores, along with a scalar training loss. ```python import satlaspretrain_models import torch weights_manager = satlaspretrain_models.Weights() # --- Backbone + FPN + detection head (Landsat multi-image) --- model = weights_manager.get_pretrained_model( "Landsat_SwinB_MI", fpn=True, head=satlaspretrain_models.Head.DETECT, num_categories=5 ) # Landsat B1-B11, 8 images, normalized: (pixel_value - 4000) / 16320, clipped to [0, 1] tensor = torch.zeros((1, 8 * 11, 512, 512), dtype=torch.float32) targets = [{ 'boxes': torch.tensor([[100., 100., 150., 150.]], dtype=torch.float32), 'labels': torch.tensor([2], dtype=torch.int64) }] model.train() output, loss = model(tensor, targets) print(output) # list of dicts with 'boxes', 'labels', 'scores' per image print(loss) # scalar training loss ``` -------------------------------- ### Initialize Pretrained Model with Classification Head Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Initializes a pre-trained model with a backbone and FPN, and a randomly initialized classification head. Use this for fine-tuning on downstream classification tasks. ```python model = weights_manager.get_pretrained_model(MODEL_CHECKPOINT_ID, fpn=True, head=satlaspretrain_models.Head.CLASSIFY, num_categories=2) ``` -------------------------------- ### Load and Use Pretrained Landsat Detection Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Loads a pre-trained multi-image Landsat model with backbone, FPN, and detection head. Input should be stacked Landsat B1-B11 images, normalized. The head requires fine-tuning and outputs bounding box detections. ```python # num_categories is the number of bounding box detection categories. # All heads are randomly initialized and provided only for convenience for fine-tuning. model = weights_manager.get_pretrained_model("Landsat_SwinB_MI", fpn=True, head=satlaspretrain_models.Head.DETECT, num_categories=5) # Expected input is Landsat B1-B11 stacked in order. # This multi-image model is trained to input 8 images but should perform well with different numbers of images. # The 16-bit pixel values are normalized as follows: # landsat_images = torch.stack([landsat_image1, landsat_image2], dim=0) # tensor = torch.clip(landsat_images[None, :, :, :, :]-4000)/16320, 0, 1) tensor = torch.zeros((1, 8, 11, 512, 512), dtype=torch.float32) # The head needs to be fine-tuned on a downstream object detection task. # It outputs bounding box detections. model.eval() output = model(tensor.reshape(1, 8*11, 512, 512)) print(output) #[{'boxes': tensor([[ 67.0772, 239.2646, 95.6874, 16.3644], ...]), # 'labels': tensor([3, ...]), # 'scores': tensor([0.5443, ...])}] ``` -------------------------------- ### Initialize UCMerced DataModule Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Initialize the UCMerced dataset using TorchGeo's datamodule, specifying the root directory, batch size, and number of workers. The dataset will be downloaded if it doesn't exist. ```python # Torchgeo lightning datamodule to initialize dataset root = os.path.join(tempfile.gettempdir(), "ucm") datamodule = UCMercedDataModule( root=root, batch_size=batch_size, num_workers=num_workers, download=True ) ``` -------------------------------- ### Initialize Sentinel-2 RGB Multi-image Model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Initializes a pretrained Sentinel-2 SwinB model configured for multi-image input with FPN. The input normalization for TCI (0-255) to [0, 1] is mentioned. ```python import satlaspretrain_models, torch weights_manager = satlaspretrain_models.Weights() # --- Sentinel-2 RGB multi-image (2 captures) --- # Normalize TCI (0-255) → [0, 1] model = weights_manager.get_pretrained_model("Sentinel2_SwinB_MI_RGB", fpn=True) ``` -------------------------------- ### Set Experiment Arguments Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Configures experiment parameters including the device, number of epochs, loss function, validation step frequency, and the path for saving model weights. ```python # Experiment arguments. device = torch.device('cpu') num_epochs = 1 criterion = torch.nn.CrossEntropyLoss() val_step = 1 # evaluate every val_step epochs save_path = 'weights/' # where to save model weights os.makedirs(save_path, exist_ok=True) ``` -------------------------------- ### Perform Inference with SatlasPretrain Model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt This snippet demonstrates how to perform inference using a pretrained SatlasPretrain model. Ensure the model and sample data are on the correct device. ```python model.eval() with torch.no_grad(): sample = torch.rand(4, 3, 64, 64).to(device) probs, _ = model(sample, None) predicted_classes = probs.argmax(dim=1) print("Predicted classes:", predicted_classes.tolist()) # e.g. Predicted classes: [3, 7, 1, 5] ``` -------------------------------- ### Download and Extract EuroSAT Dataset Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Downloads the EuroSAT_RGB dataset from Zenodo if it does not already exist locally. The dataset is extracted into the current directory. ```python # Download the EuroSAT_RGB dataset. # Only go through the downloading and unzipping process if it hasn't been done before. if not os.path.exists('EuroSAT_RGB/'): # Download the EuroSAT_RGB dataset. This is a zip file. zip_file_url = 'https://zenodo.org/records/7711810/files/EuroSAT_RGB.zip?download=1' # Send a GET request to the EuroSAT_RGB Zenodo download URL. response = requests.get(zip_file_url) # Check if the request was successful. if response.status_code == 200: # Use BytesIO for the zip file content. zip_file = io.BytesIO(response.content) # Open the zip file. You should see the EuroSAT_RGB/ folder in this directory. with zipfile.ZipFile(zip_file) as zfile: # Extract all the contents into the current directory zfile.extractall('.') print("Zip file extracted successfully.") else: print(f"Failed to download the zip file. Status code: {response.status_code}") ``` -------------------------------- ### Initialize Model as Feature Extractor with ResNet-50 Backbone Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Initializes a model with a ResNet-50 backbone, without FPN or a head, to be used as a feature extractor. This configuration is suitable for multispectral imagery. ```python model = Model( num_channels=9, # Sentinel-2 multispectral (9 bands) multi_image=False, backbone=Backbone.RESNET50, fpn=False, head=None, weights=None ) tensor = torch.rand((4, 9, 256, 256)) features = model(tensor) print([f.shape for f in features]) # [torch.Size([4, 256, 64, 64]), torch.Size([4, 512, 32, 32]), # torch.Size([4, 1024, 16, 16]), torch.Size([4, 2048, 8, 8])] ``` -------------------------------- ### Load and Use Pretrained Aerial Classification Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Loads a pre-trained multi-image aerial model with backbone, FPN, and classification head. Input images should be 0-1 normalized. The head requires fine-tuning and outputs classification probabilities. ```python # num_categories is the number of categories to predict. # All heads are randomly initialized and provided only for convenience for fine-tuning. model = weights_manager.get_pretrained_model("Aerial_SwinB_MI", fpn=True, head=satlaspretrain_models.Head.CLASSIFY, num_categories=2) # Expected input is 8-bit (0-255) aerial images at 0.5 - 2 m/pixel. # The 0-255 pixel values should be divided by 255 so they are 0-1. # This multi-image model is trained to input 4 images but should perform well with different numbers of images. # tensor = torch.stack([rgb_image1, rgb_image2], dim=0)[None, :, :, :, :] / 255 tensor = torch.zeros((1, 4, 3, 512, 512), dtype=torch.float32) # The head needs to be fine-tuned on a downstream classification task. # It outputs classification probabilities. model.eval() output = model(tensor.reshape(1, 4*3, 512, 512)) print(output) # tensor([[0.0266, 0.9734]]) ``` -------------------------------- ### Initialize DataLoaders Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Initializes the training and validation datasets using the custom Dataset class and creates DataLoaders for batching and shuffling data during training. ```python # Initialize the train and validation datasets. train_dataset = Dataset('EuroSAT_RGB/') val_dataset = Dataset('EuroSAT_RGB/', val=True) # Dataloaders. train_dataloader = DataLoader( train_dataset, batch_size=16, shuffle=True, num_workers=0 ) val_dataloader = DataLoader( val_dataset, batch_size=16, shuffle=False, num_workers=0 ) ``` -------------------------------- ### Initialize Classification Task Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Instantiate the custom `SatlasClassificationTask` with the specified number of output classes for the UCMerced dataset. ```python # Initialize the Classifcation Task task = SatlasClassificationTask(num_classes=21) ``` -------------------------------- ### Weights.get_pretrained_model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Downloads the checkpoint for the given model_identifier and initializes a Model with pretrained backbone (and optionally FPN) weights. It supports various configurations including backbone-only, backbone + FPN, and backbone + FPN + task head. ```APIDOC ## Weights.get_pretrained_model ### Description Downloads the checkpoint for the given `model_identifier` and initializes a `Model` with pretrained backbone (and optionally FPN) weights. Raises `ValueError` for invalid identifiers or if `head` is specified without `num_categories`. Raises `Exception` if the checkpoint download fails. ### Method ```python weights_manager.get_pretrained_model(model_identifier: str, fpn: bool = False, head: Optional[Head] = None, num_categories: Optional[int] = None) ``` ### Parameters #### Path Parameters - **model_identifier** (str) - Required - Identifier string for the pretrained model. - **fpn** (bool) - Optional - Whether to include a Feature Pyramid Network. Defaults to `False`. - **head** (Head) - Optional - The type of task head to attach (e.g., `CLASSIFY`, `DETECT`). Requires `num_categories`. - **num_categories** (int) - Optional - The number of output categories for the task head. Required if `head` is specified. ### Request Example ```python import satlaspretrain_models import torch weights_manager = satlaspretrain_models.Weights() # Backbone only (Sentinel-2 RGB, single-image, Swin-v2-Base) model = weights_manager.get_pretrained_model(model_identifier="Sentinel2_SwinB_SI_RGB") # Input: (batch, 3, H, W), pixel values normalized to [0, 1] tensor = torch.zeros((1, 3, 512, 512), dtype=torch.float32) output = model(tensor) # Returns list of 4 multi-scale feature maps from the backbone print([f.shape for f in output]) # [torch.Size([1, 128, 128, 128]), torch.Size([1, 256, 64, 64]), # torch.Size([1, 512, 32, 32]), torch.Size([1, 1024, 16, 16])] # Backbone + FPN (Sentinel-1 VH+VV, single-image) model = weights_manager.get_pretrained_model("Sentinel1_SwinB_SI", fpn=True) # Input: (batch, 2, H, W) stacked [VH, VV], 16-bit values / 255, clipped to [0, 1] tensor = torch.zeros((1, 2, 512, 512), dtype=torch.float32) output = model(tensor) # FPN normalizes all feature maps to 128 channels print([f.shape for f in output]) # [torch.Size([1, 128, 128, 128]), torch.Size([1, 128, 64, 64]), # torch.Size([1, 128, 32, 32]), torch.Size([1, 128, 16, 16])] # Backbone + FPN + classification head (aerial multi-image) model = weights_manager.get_pretrained_model( "Aerial_SwinB_MI", fpn=True, head=satlaspretrain_models.Head.CLASSIFY, num_categories=10 ) # Multi-image input: stack N images along dim=1 and flatten channels # Shape: (batch, N*channels, H, W) tensor = torch.zeros((1, 4 * 3, 512, 512), dtype=torch.float32) # 4 images × 3 RGB channels model.eval() output, loss = model(tensor, targets=None) print(output.shape) # torch.Size([1, 10]) — class probabilities # Backbone + FPN + detection head (Landsat multi-image) model = weights_manager.get_pretrained_model( "Landsat_SwinB_MI", fpn=True, head=satlaspretrain_models.Head.DETECT, num_categories=5 ) # Landsat B1-B11, 8 images, normalized: (pixel_value - 4000) / 16320, clipped to [0, 1] tensor = torch.zeros((1, 8 * 11, 512, 512), dtype=torch.float32) targets = [{ 'boxes': torch.tensor([[100., 100., 150., 150.]], dtype=torch.float32), 'labels': torch.tensor([2], dtype=torch.int64) }] model.train() output, loss = model(tensor, targets) print(output) # list of dicts with 'boxes', 'labels', 'scores' per image print(loss) # scalar training loss ``` ### Response #### Success Response (200) - **model** (Model) - A `Model` instance configured with the specified weights and architecture. - **output** (Tensor or List[Tensor] or List[Dict]) - Model output, varies based on the attached head. - **loss** (Tensor) - Training loss, returned when targets are provided during training. #### Response Example ```json { "example": "[torch.Size([1, 10])]" } ``` ``` -------------------------------- ### Load Backbone + FPN + Classification Head Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Load a pretrained model with FPN and a classification head for aerial multi-image input. The input tensor shape is (batch, N*channels, H, W). The output is class probabilities. ```python import satlaspretrain_models import torch weights_manager = satlaspretrain_models.Weights() # --- Backbone + FPN + classification head (aerial multi-image) --- model = weights_manager.get_pretrained_model( "Aerial_SwinB_MI", fpn=True, head=satlaspretrain_models.Head.CLASSIFY, num_categories=10 ) # Multi-image input: stack N images along dim=1 and flatten channels # Shape: (batch, N*channels, H, W) tensor = torch.zeros((1, 4 * 3, 512, 512), dtype=torch.float32) # 4 images × 3 RGB channels model.eval() output, loss = model(tensor, targets=None) print(output.shape) # torch.Size([1, 10]) — class probabilities ``` -------------------------------- ### Load Sentinel-2 RGB Backbone Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Loads a pretrained Swin-v2-Base backbone for single-image Sentinel-2 RGB input. The model outputs feature maps. Input pixel values should be normalized to 0-1. ```python model = weights_manager.get_pretrained_model(model_identifier="Sentinel2_SwinB_SI_RGB") # Expected input is a portion of a Sentinel-2 L1C TCI image. # The 0-255 pixel values should be divided by 255 so they are 0-1. # tensor = tci_image[None, :, :, :] / 255 tensor = torch.zeros((1, 3, 512, 512), dtype=torch.float32) # Since we only loaded the backbone, it outputs feature maps from the Swin-v2-Base backbone. output = model(tensor) print([feature_map.shape for feature_map in output]) ``` -------------------------------- ### Load and use Sentinel-1 multi-image model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Loads a pretrained Sentinel-1 model for multi-image analysis with FPN. Input data should be 16-bit VH/VV, clipped and normalized to the range [0, 1]. ```python model = weights_manager.get_pretrained_model("Sentinel1_SwinB_MI", fpn=True) # 16-bit VH/VV: clip(value / 255, 0, 1) vh1 = torch.clip(torch.rand(512, 512) * 512 / 255, 0, 1) vv1 = torch.clip(torch.rand(512, 512) * 512 / 255, 0, 1) vh2 = torch.clip(torch.rand(512, 512) * 512 / 255, 0, 1) vv2 = torch.clip(torch.rand(512, 512) * 512 / 255, 0, 1) img1 = torch.stack([vh1, vv1], dim=0) # (2, 512, 512) img2 = torch.stack([vh2, vv2], dim=0) tensor = torch.stack([img1, img2], dim=0)[None].reshape(1, 4, 512, 512) output = model(tensor) ``` -------------------------------- ### Load Pre-trained Model for Classification Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Loads a pre-trained Sentinel2 SwinB model with an FPN and a classification head. Ensure the device is set correctly. ```python weights_manager = satlaspretrain_models.Weights() model = weights_manager.get_pretrained_model("Sentinel2_SwinB_SI_RGB", fpn=True, head=satlaspretrain_models.Head.CLASSIFY, num_categories=10, device='cpu') model = model.to(device) ``` -------------------------------- ### Define Experiment Arguments Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Set hyperparameters for the training experiment, including batch size, number of workers, and maximum epochs. ```python # Experiment Arguments batch_size = 8 num_workers = 2 max_epochs = 10 fast_dev_run = False ``` -------------------------------- ### Load and use Landsat 8/9 multi-image model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Loads a pretrained Landsat model for multi-image analysis with FPN. Input bands are expected to be 16-bit and are normalized using the formula: clip((value - 4000) / 16320, 0, 1). ```python model = weights_manager.get_pretrained_model("Landsat_SwinB_MI", fpn=True) # 16-bit bands: clip((value - 4000) / 16320, 0, 1) raw = torch.randint(4000, 20000, (2, 11, 512, 512)).float() tensor = torch.clip((raw - 4000) / 16320, 0, 1)[None].reshape(1, 22, 512, 512) output = model(tensor) print([f.shape for f in output]) ``` -------------------------------- ### Visualize Random Training Samples Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Visualizes a grid of random samples from the training dataset using Matplotlib. Each subplot displays an image and its corresponding class title. ```python # Visualize a couple datapoints, pulled randomly from the training set. import random import matplotlib.pyplot as plt shuffled_indices = torch.randperm(train_dataset.__len__()).tolist() random_samples = [train_dataset[x] for x in shuffled_indices] fig, axs = plt.subplots(5, 5, figsize=(15, 15)) for i, ax in enumerate(axs.flat): data, target = random_samples[i] image = data.cpu().numpy() target = int(target.cpu().numpy()) image = image.transpose(1, 2, 0) ax.set_title(int_to_class[target], fontsize=10) ax.imshow(image) ax.axis('off') plt.show() ``` -------------------------------- ### List available pretrained model identifiers Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Iterates through all available pretrained model identifiers and prints their metadata, including the number of channels and whether they support multi-image input. ```python from satlaspretrain_models.utils import SatlasPretrain_weights # Print all available model IDs with their metadata for model_id, info in SatlasPretrain_weights.items(): print(f"{model_id:40s} channels={info['num_channels']:2d} multi_image={info['multi_image']}") ``` -------------------------------- ### Map Class Names to Integers Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Gathers class names from the dataset directory and creates mappings between class labels and unique integers for later use, such as in visualization. ```python # Gather the EuroSAT class names. classes = os.listdir('EuroSAT_RGB/') # Create a mapping from class label to a unique integer. For later visualization. cls_to_int = {label: idx for idx, label in enumerate(set(classes))} int_to_class = {v: k for k, v in cls_to_int.items()} print("Classes mapped to integers:", cls_to_int) ``` -------------------------------- ### Load Backbone + FPN Model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Load a pretrained backbone and FPN model for Sentinel-1 VH+VV images. Input should be (batch, 2, H, W) with values normalized to [0, 1]. FPN normalizes all feature maps to 128 channels. ```python import satlaspretrain_models import torch weights_manager = satlaspretrain_models.Weights() # --- Backbone + FPN (Sentinel-1 VH+VV, single-image) --- model = weights_manager.get_pretrained_model("Sentinel1_SwinB_SI", fpn=True) # Input: (batch, 2, H, W) stacked [VH, VV], 16-bit values / 255, clipped to [0, 1] tensor = torch.zeros((1, 2, 512, 512), dtype=torch.float32) output = model(tensor) # FPN normalizes all feature maps to 128 channels print([f.shape for f in output]) # [torch.Size([1, 128, 128, 128]), torch.Size([1, 128, 64, 64]), # torch.Size([1, 128, 32, 32]), torch.Size([1, 128, 16, 16])] ``` -------------------------------- ### Process RGB image tensor with a pretrained model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Initializes a pretrained model for RGB images and processes a randomly generated tensor. The input tensor shape is (batch_size, channels, height, width). ```python tci1 = torch.randint(0, 256, (3, 512, 512)).float() / 255 tci2 = torch.randint(0, 256, (3, 512, 512)).float() / 255 tensor = torch.stack([tci1, tci2], dim=0)[None] # (1, 2, 3, 512, 512) tensor = tensor.reshape(1, 2 * 3, 512, 512) # flatten: (1, 6, 512, 512) output = model(tensor) print([f.shape for f in output]) ``` -------------------------------- ### Training and Validation Loop Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Implements a training loop that iterates over epochs, processes data, calculates loss, performs backpropagation, and updates weights. Includes a validation step to evaluate model performance and accuracy, saving checkpoints periodically. ```python # Training loop. for epoch in range(num_epochs): print("Starting Epoch...", epoch) for data, target in train_dataloader: data = data.to(device) target = target.to(device) output, loss = model(data, target) print("Train Loss = ", loss) loss.backward() optimizer.step() optimizer.zero_grad() break # Validation. if epoch % val_step == 0: model.eval() for val_data, val_target in val_dataloader: val_data = val_data.to(device) val_target = val_target.to(device) val_output, val_loss = model(val_data, val_target) val_accuracy = (val_output.argmax(dim=1) == val_target).float().mean().item() print("Validation accuracy = ", val_accuracy) # Save the model checkpoint at the end of each epoch. torch.save(model.state_dict(), save_path + str(epoch) + '_model_weights.pth') ``` -------------------------------- ### Load Backbone Only Model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Load a pretrained backbone model for Sentinel-2 RGB images. The input tensor should be of shape (batch, 3, H, W) with pixel values normalized to [0, 1]. ```python import satlaspretrain_models import torch weights_manager = satlaspretrain_models.Weights() # --- Backbone only (Sentinel-2 RGB, single-image, Swin-v2-Base) --- model = weights_manager.get_pretrained_model(model_identifier="Sentinel2_SwinB_SI_RGB") # Input: (batch, 3, H, W), pixel values normalized to [0, 1] tensor = torch.zeros((1, 3, 512, 512), dtype=torch.float32) output = model(tensor) # Returns list of 4 multi-scale feature maps from the backbone print([f.shape for f in output]) # [torch.Size([1, 128, 128, 128]), torch.Size([1, 256, 64, 64]), # torch.Size([1, 512, 32, 32]), torch.Size([1, 1024, 16, 16])] ``` -------------------------------- ### Iterate Through Backbone Architectures and Extract Features Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Iterates through different backbone architectures (SwinB, Swint, ResNet50, ResNet152) and prints the shape of the features extracted by each. This helps understand the output dimensions for each backbone. ```python from satlaspretrain_models.utils import Backbone from satlaspretrain_models.model import Model import torch # Backbone.SWINB — Swin Transformer v2 Base (out_channels: 128/256/512/1024) # Backbone.SWINT — Swin Transformer v2 Tiny (out_channels: 96/192/384/768) # Backbone.RESNET50 — ResNet-50 (out_channels: 256/512/1024/2048) # Backbone.RESNET152— ResNet-152 (out_channels: 256/512/1024/2048) for arch in [Backbone.SWINB, Backbone.SWINT, Backbone.RESNET50, Backbone.RESNET152]: model = Model(num_channels=3, multi_image=False, backbone=arch, fpn=False, weights=None) x = torch.rand((1, 3, 256, 256)) features = model(x) print(arch.name, [list(f.shape) for f in features]) # SWINB [[1, 128, 64, 64], [1, 256, 32, 32], [1, 512, 16, 16], [1, 1024, 8, 8]] # SWINT [[1, 96, 64, 64], [1, 192, 32, 32], [1, 384, 16, 16], [1, 768, 8, 8]] # RESNET50 [[1, 256, 64, 64], [1, 512, 32, 32], [1, 1024, 16, 16],[1, 2048, 8, 8]] # RESNET152[[1, 256, 64, 64], [1, 512, 32, 32], [1, 1024, 16, 16],[1, 2048, 8, 8]] ``` -------------------------------- ### Model Summary Output Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Displays a summary of the model's architecture, including the number of trainable and non-trainable parameters, and estimated memory size. This output is typically generated by a training utility. ```text | Name | Type | Params --------------------------------------------------- 0 | criterion | CrossEntropyLoss | 0 1 | train_metrics | MetricCollection | 0 2 | val_metrics | MetricCollection | 0 3 | test_metrics | MetricCollection | 0 4 | model | SwinTransformer | 86.9 M --------------------------------------------------- 86.9 M Trainable params 0 Non-trainable params 86.9 M Total params 347.709 Total estimated model params size (MB) ``` -------------------------------- ### KeyboardInterrupt Handling Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Logs a message indicating that a KeyboardInterrupt (e.g., Ctrl+C) was detected and a graceful shutdown is being attempted. This is part of the trainer's robustness features. ```text /Users/piperw/opt/anaconda3/envs/torchgeotest/lib/python3.12/site-packages/lightning/pytorch/trainer/call.py:54: Detected KeyboardInterrupt, attempting graceful shutdown... ``` -------------------------------- ### Fine-tune Sentinel-2 model for EuroSAT classification Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Demonstrates end-to-end fine-tuning of a pretrained Sentinel-2 backbone with an FPN and a classification head for the EuroSAT dataset. The backbone is frozen, and only the classification head is trained. ```python import satlaspretrain_models import torch import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset # Setup weights_manager = satlaspretrain_models.Weights() device = 'cuda' if torch.cuda.is_available() else 'cpu' # Load backbone+FPN with classification head (10 EuroSAT classes) model = weights_manager.get_pretrained_model( "Sentinel2_SwinB_SI_RGB", fpn=True, head=satlaspretrain_models.Head.CLASSIFY, num_categories=10, device=device ).to(device) # Freeze backbone, only train the head for name, param in model.named_parameters(): if 'head' not in name: param.requires_grad = False optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=1e-4) # Synthetic dataset: 64 samples, RGB 64×64 patches, 10 classes X = torch.rand(64, 3, 64, 64) # normalized Sentinel-2 TCI / 255 y = torch.randint(0, 10, (64,)) loader = DataLoader(TensorDataset(X, y), batch_size=8, shuffle=True) # Training loop model.train() for epoch in range(3): epoch_loss = 0.0 for imgs, labels in loader: imgs, labels = imgs.to(device), labels.to(device) optimizer.zero_grad() logits, loss = model(imgs, labels) loss.backward() optimizer.step() epoch_loss += loss.item() print(f"Epoch {epoch+1}: loss={epoch_loss/len(loader):.4f}") ``` -------------------------------- ### Load Sentinel-1 Backbone + FPN Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Loads a pretrained Swin-v2-Base model for single-image Sentinel-1 VH+VV input, including the Feature Pyramid Network (FPN). Input pixel values should be normalized to 0-1 and clipped. The model outputs feature maps from the FPN. ```python model = weights_manager.get_pretrained_model("Sentinel1_SwinB_SI", fpn=True) # Expected input is a portion of a Sentinel-1 vh+vv image (in that order). # The 16-bit pixel values should be divided by 255 and clipped to 0-1 (any pixel values greater than 255 become 1). # tensor = torch.clip(torch.stack([vh_image, vv_image], dim=0)[None, :, :, :] / 255, 0, 1) tensor = torch.zeros((1, 2, 512, 512), dtype=torch.float32) # The model outputs feature maps from the FPN. output = model(tensor) print([feature_map.shape for feature_map in output]) ``` -------------------------------- ### Load and use Sentinel-2 multispectral model Source: https://context7.com/allenai/satlaspretrain_models/llms.txt Loads a pretrained Sentinel-2 model for multispectral imagery and processes a random tensor. Assumes input is normalized between 0 and 1. ```python model = weights_manager.get_pretrained_model("Sentinel2_SwinB_SI_MS") # 9-band input normalized 0-255 -> [0, 1] tensor = torch.rand((1, 9, 512, 512)) output = model(tensor) print([f.shape for f in output]) ``` -------------------------------- ### Load Pretrained Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/README.md Load a pretrained SatlasPretrain model using its checkpoint ID. The `fpn` argument can be set to True to include the Feature Pyramid Network. ```python MODEL_CHECKPOINT_ID = "Sentinel2_SwinB_SI_RGB" model = weights_manager.get_pretrained_model(MODEL_CHECKPOINT_ID) model = weights_manager.get_pretrained_model(MODEL_CHECKPOINT_ID, fpn=True) ``` -------------------------------- ### Training Epoch Progress Bar Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Displays the progress bar for a training epoch, showing the percentage completed, number of batches processed, time elapsed, and estimated time remaining. It also includes the current validation metric value. ```text Epoch 0: 78%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▋ | 124/158 [10:06<02:46, 0.20it/s, v_num=1] ``` -------------------------------- ### Load Model State Dictionary Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb Loads previously saved model weights into the current model. This is useful for resuming training or for inference. ```python # Example of loading pre-trained weights into the model. recent_weights = torch.load(save_path + str(epoch) + '_model_weights.pth') pretrained_model = model.load_state_dict(recent_weights) ``` -------------------------------- ### Custom Classification Task for SatlasPretrain Model Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Define a custom `ClassificationTask` that loads the SatlasPretrain model (Swin_V2_B_Weights.SENTINEL2_RGB_SI_SATLAS). This class overrides `configure_models` to replace the model's first and last layers to match the dataset's input channels and number of classes, respectively. It also includes a callback for logging validation metrics. ```python # Custom ClassificationTask to load in the SatlasPretrain model class SatlasClassificationTask(ClassificationTask): def configure_models(self): weights = Swin_V2_B_Weights.SENTINEL2_RGB_SI_SATLAS self.model = swin_v2_b(weights) # Replace first layer's input channels with the task's number input channels. 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)) # Replace last layer's output features with the number 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}") 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}") ``` -------------------------------- ### Validation Progress Log Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb Logs the progress of the validation step during training, showing the loss and accuracy. This output indicates the model's performance on the validation set after an epoch. ```text Output: Sanity Checking DataLoader 0: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:03<00:00, 0.60it/s]Epoch 0 Validation - Loss: 3.1346988677978516, Accuracy: 0.0 ``` -------------------------------- ### Define EuroSAT Dataset Class Source: https://github.com/allenai/satlaspretrain_models/blob/main/demo.ipynb A custom PyTorch Dataset class for the EuroSAT dataset. It loads images and their corresponding class labels, splitting data into training and validation sets. ```python # Define a dataset class that takes in the path to the EuroSAT_RGB path and returns datapoints, # each with a torch tensor containing the image data and a corresponding target class. class Dataset(Dataset): def __init__(self, dataset_path, val=False): self.datapoints = [] # The subdirectories in the dataset folder are named by class. classes = os.listdir(dataset_path) # Create a mapping from class label to a unique integer. cls_to_int = {label: idx for idx, label in enumerate(set(classes))} # For each class, use 80% of the images for training and the rest for validation. for cls in classes: cls_int = cls_to_int[cls] cls_imgs = os.listdir(dataset_path + '/' + cls + '/') if val: cls_datapoints = [(dataset_path + '/' + cls + '/' + img, cls_int) for img in cls_imgs[2400:]] else: cls_datapoints = [(dataset_path + '/' + cls + '/' + img, cls_int) for img in cls_imgs[:2400]] self.datapoints += cls_datapoints print("Loaded ", len(self.datapoints), " datapoints.") def __getitem__(self, idx): img_path, cls_int = self.datapoints[idx] img = torchvision.io.read_image(img_path) # load image directly into a [3, 64, 64] tensor img = img.float() / 255 # normalize input to be between 0-1 target = torch.tensor(cls_int) # convert class index into a torch tensor return img, target def __len__(self): return len(self.datapoints) ``` -------------------------------- ### DataLoader Persistent Workers Warning Source: https://github.com/allenai/satlaspretrain_models/blob/main/torchgeo_demo.ipynb A warning message suggesting to set `persistent_workers=True` in the dataloader configuration to potentially speed up worker initialization. This is a common optimization tip for PyTorch DataLoaders. ```text /Users/piperw/opt/anaconda3/envs/torchgeotest/lib/python3.12/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:436: Consider setting `persistent_workers=True` in 'train_dataloader' to speed up the dataloader worker initialization. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.