SSL4EO-S12 v1.1

March 24, 2026 ยท View on GitHub

arXiv HuggingFace

SSL4EO-S12 v1.1

SSL4EO-S12 v1.1 is an updated multimodal version of the popular EO pre-training dataset SSL4EO-S12. Read more about the reasons behind our update and further improvements in our technical report on arXiv.

NEWS

Data

The dataset includes 246,144 locations with four timestamps each from the modalities S2L1C, S2L2A, S1GRD, S2RGB, NDVI, LULC, and a single timestamp DEM. We refer to our technical report for details.

Sentinel-2 and Sentinel-1 time series examples with four seasonal images:

ssl4eos12_timeseries.png

Modality examples in SSL4EO-S12 v1.1:

ssl4eoS12_modalities.png

Download

You can download the dataset via the Hugging Face CLI (pip install huggingface_hub). Please note that the full dataset requires 2.3TB of storage.

hf download embed2scale/SSL4EO-S12-v1.1 --repo-type dataset --local-dir data/SSL4EOS12

If you like to download only a subset of the data, you can specify it with --include.

# Only download val data
hf download embed2scale/SSL4EO-S12-v1.1 --repo-type dataset --include "val/*" --local-dir data/SSL4EOS12

# Only download a single modality (e.g., S2L2A)
hf download embed2scale/SSL4EO-S12-v1.1 --repo-type dataset --include "*/S2L2A/*" --local-dir data/SSL4EOS12

For development, webdataset supports data streaming and does not need any local data.

Usage

Set up your env with

pip install -r requirements.txt

# or install the packages manually via
pip install huggingface_hub webdataset zarr==2.18.0 numcodecs==0.15.1 torch numpy albumentations fsspec braceexpand 

We provide code for a PyTorch dataloader in ssl4eos12_dataset.py which you can download with

wget https://raw.githubusercontent.com/DLR-MF-DAS/SSL4EO-S12-v1.1/refs/heads/main/ssl4eos12_dataset.py

You can use the build_ssl4eos12_dataset function to initialize a dataset, which uses the WebDataset package to load samples from the shard files. You can stream the data from Hugging Face using the urls or download the full dataset and pass a local path (e.g, data/SSL4EOS12/).

from ssl4eos12_dataset import build_ssl4eos12_dataset
from torch.utils.data import DataLoader

# If you only pass one modality, the modality is loaded with the "image" key
dataset = build_ssl4eos12_dataset(
    path="https://huggingface.co/datasets/embed2scale/SSL4EO-S12-v1.1/resolve/main/",  # Streaming or local path
    modalities=["S2L2A"], 
    split="val",
    batch_size=8
)
# Batch keys: ["__key__", "__url__", "image"]

# If you pass multiple modalities, the modalities are returned using the modality names as keys
dataset = build_ssl4eos12_dataset(
    path="https://huggingface.co/datasets/embed2scale/SSL4EO-S12-v1.1/resolve/main/",  # Streaming or local path
    modalities=["S2L2A", "S2L1C", "S2RGB", "S1GRD", "DEM", "NDVI", "LULC"], 
    split="val",
    batch_size=8,    
)

# Set batch size to None because batching is handled by WebDataset.
dataloader = DataLoader(dataset, batch_size=None, num_workers=4, persistent_workers=True, prefetch_factor=1)

# Iterate over the dataloader
for batch in dataloader:
    print("Batch keys:", list(batch.keys()))
    # Batch keys: ["__key__", "__url__", "S2L2A", "S2L1C", "S2RGB", "S1GRD", "DEM", "NDVI", "LULC"]

    print("Data shape:", batch["S2L2A"].shape)
    # Data shape: torch.Size([8, 4, 12, 264, 264]
    # Dimensions [batch, time, channel, h, w]
    break

The data in SSL4EO-S12 v1.1 is sorted by date, meaning that each timestep can be from any season. If you like to load the data with fixed seasons, pass reindex_seasonal=True to build_ssl4eos12_dataset() and the loaded data is sorted by season while ignoring the year. I.e., the first timestamp is from the first yearly quartal, followed by the second and so on.

Data transform

We provide some additional code for wrapping albumentations transform functions. We recommend albumentations because parameters are shared between all image modalities (e.g., same random crop). However, it requires some code wrapping to bring the data into the expected shape.

import albumentations as A
from albumentations.pytorch import ToTensorV2
from ssl4eos12_dataset import (build_ssl4eos12_dataset, Transpose, MultimodalTransforms, MultimodalNormalize, 
                               FlattenTemporalIntoChannels, UnflattenTemporalFromChannels, statistics)

# Define all image modalities
modalities = ["S2L2A", "S2L1C", "S2RGB", "S1GRD", "DEM", "NDVI", "LULC"]

# Define multimodal transform function that converts the data into the expected shape from albumentations
val_transform = MultimodalTransforms(
    transforms=A.Compose([  # We use albumentations because of the shared transform between image modalities
        Transpose([0, 2, 3, 1]),  # Convert data to channel last (expected shape from albumentations)
        MultimodalNormalize(mean=statistics["mean"], std=statistics["std"]),
        # CenterCrop other transformations cannot handle temporal data. Needs to be applied after MultimodalNormalize
        FlattenTemporalIntoChannels(),
        A.CenterCrop(224, 224),  # Use center crop in val split
        # A.RandomCrop(224, 224),  # Use random crop in train split
        # A.D4(),  # Optionally, use random flipping and rotation for the train split
        ToTensorV2(),  # Convert to tensor and back to channel first
        UnflattenTemporalFromChannels(n_timesteps=4), # Add time dim back, apply after ToTensorV2()
    ],
        is_check_shapes=False,  # Not needed because of aligned data in TerraMesh
        additional_targets={m: "image" for m in modalities}
    ),
    non_image_modalities=["__key__", "__url__"],  # Additional non-image keys
)

dataset = build_ssl4eos12_dataset(
    path="https://huggingface.co/datasets/embed2scale/SSL4EO-S12-v1.1/resolve/main/",
    modalities=modalities,
    split="val",
    transform=val_transform,
    batch_size=8,
)

If you only use a single modality, you don't need to specify additional_targets but you need to change the normalization to:

`        MultimodalNormalize(
            mean={"image": statistics["mean"]["<modality>"]},
            std={"image": statistics["std"]["<modality>"]}
        ),`

Returning metadata

You can pass return_metadata=True to build_ssl4eos12_dataset() to load center longitude and latitude, timestamps, and the S2 cloud mask as additional metadata.

The resulting batch keys include: ["__key__", "__url__", "S2L2A", "S1GRD", ..., "center_lon", "center_lat", "cloud_mask", "time_S2L2A", "time_S1GRD", ...].

If you are using the cloud_mask, update additional_targets in your transform:

val_transform = MultimodalTransforms(
    transforms=A.Compose([...],
        additional_targets={m: "image" for m in modalities + ["cloud_mask"]}
        # additional_targets={"cloud_mask": "image"}  # Setting for a single modality dataset 
    ),
)

Note that center points are not updated when random crop is used. The cloud mask provides the classes land (0), water (1), snow (2), thin cloud (3), thick cloud (4), cloud shadow (5), and no data (6). DEM does not return a time value while LULC uses the S2 timestamp because of the augmentation using the S2 cloud and ice mask. Time values are returned as integer values but can be converted back to datetime with

batch["time_S2L2A"].numpy().astype("datetime64[ns]")

Metadata

We provide metadata Parquet files per split at Hugging Face with the following columns:

tar                                     ssl4eos12_shard_000001.tar
zarr                  ssl4eos12_val_seasonal_data_0000001.zarr.zip
sample_id                                                  0080717
split                                                          val
center_lon                                              125.637763
center_lat                                               42.659342
crs                                                          32651
bounds                  [714870.0, 4725040.0, 717510.0, 4727680.0]
geometry         POLYGON ((125.65334657340223 42.64709631345207...
S2_time_0                                      2020-11-16 02:30:01
S2_time_1                                      2021-03-04 02:36:09
S2_time_2                                      2021-05-18 02:35:51
S2_time_3                                      2021-08-08 02:25:49
S1_time_0                                      2020-11-27 21:46:46
S1_time_1                                      2021-02-26 21:38:39
S1_time_2                                      2021-05-26 21:46:46
S1_time_3                                      2021-08-30 21:46:51
cloud_cover_0                                                  0.0
cloud_cover_1                                                  0.0
cloud_cover_2                                                  0.0
cloud_cover_3                                               0.0011

The sample_id is similar to the v1 dataset. The S2_time_{i} are shared between S2L1C, S2L2A, S2RGB, and NDVI. LULC is augmented with the clouds and ice/snow at that timestamp.

Zarr chunk file version

We released a previous version of SSL4EO-S12 v1.1 using Zarr chunk files with 64 samples each. The version ist still available at embed2scale/SSL4EO-S12-v1.1-Zarr. We moved on to a webdataset version for better usability.

zarr_dataset.py provides data loading code for previous version and the chunk file version is directly compatible with TerraTorch's GenericMultiModalDataModule which is showcased in the config terratorch_zarr_ssl4eos12.yaml.

License

This repository is released under the Apache 2.0 license. The dataset is released under the CC-BY-4.0 license.

Citation

If you use this dataset in your work, please cite:

@article{blumenstiel2025ssl4eos12,
  title={{SSL4EO-S12} v1.1: A Multimodal, Multiseasonal Dataset for Pretraining, Updated},
  author={Blumenstiel, Benedikt and Ait Ali Braham, Nassim and Albrecht, Conrad M and Maurogiovanni, Stefano and Fraccaro, Paolo},
  journal={arXiv preprint arXiv:2503.00168},
  year={2025}
}

This dataset is an updated version of:

@article{wang2022ssl4eo,
  title={{SSL4EO-S12}: A large-scale multimodal, multitemporal dataset for self-supervised learning in Earth observation [Software and Data Sets]},
  author={Wang, Yi and Ait Ali Braham, Nassim and Xiong, Zhitong and Liu, Chenying and Albrecht, Conrad M and Zhu, Xiao Xiang},
  journal={IEEE Geoscience and Remote Sensing Magazine},
  volume={11},
  number={3},
  pages={98--106},
  year={2023},
  publisher={IEEE}
}