-
Notifications
You must be signed in to change notification settings - Fork 350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DRAFT] FLAIR#2 Dataset and Datamodule Integration #2394
base: main
Are you sure you want to change the base?
Conversation
…mg and msk) Updates in the custom raster dataset tutorial and the actual file documentation. The previous recommended approach (overriding `__get_item__`) is outdated. Refs: microsoft#2292 (reply in thread)
Co-authored-by: Adam J. Stewart <[email protected]>
Co-authored-by: Adam J. Stewart <[email protected]>
… type individually
Not fully functioning yet, contains copy paste from other datasets
Additionally, some small code refactors are done
…d refine plotting
Using the entire sentinel-2 image and a matplotlib patch to debug, otherwise it is really hard to find correct spot due to low resolution
…y()` for sentinel With the nested dict, it was not possible to download dynamically
md5s might change due to timestamps, this eases the process of changing md5
Thanks a lot for the PR, here are just some answers at the top of my head, others might have additional opinions.
Not sure about this one, but your proposition seems reasonable and as long as this is clearly documented, I would think it is fine.
I think that depends on how, the large sentinel tile is expected to be used/useful for a model. The very low resolution area does not seem useful intuitively. I think having the flag you implemented is nice. If you provide the entire tile, there will have to be a collate or cropping function in the datamodule, otherwise the dataloader cannot return consistent batches, as by default it tries to batch individual samples into a tensor by dict key.
I actually like that approach.
Classes should definitely be ordinally mapped to start from 0, otherwise there will be issues with the |
@@ -1,62 +1,64 @@ | |||
Dataset,Task,Source,License,# Samples,# Classes,Size (px),Resolution (m),Bands |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something seems off here, since the entire csv file changed, and not just the FLAIR2
addition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably line endings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I try to change to the original line endings, or does it not really matter?
tests/data/flair2/data.py
Outdated
from pyproj import CRS | ||
|
||
# General hyperparams | ||
IMG_SIZE = 512 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the toy data we usually use smaller image sizes like 32 just to speed up tests.
""" | ||
super().__init__(FLAIR2, batch_size, num_workers, **kwargs) | ||
|
||
self.patch_size = _to_tuple(patch_size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The definition of patch_size
is useful if there is an additional kornia Resize
augmentation under self.aug
, however, we would also have to consider how this plays with the larger sentinel tile. I am still not sure what purpose the additional Sentinel 2 should provide in terms of model performance if the high res image only covers such a tiny area.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am by no means an expert, but have been reading some papers in the domain the last year. I suppose, the increased feature dimensions provided by the hyperspectral bands of sentinel-2 have shown to increase model performance.
Furthermore, in the datapaper [p. 6] of FLAIR2 the authors argue:
The interest of the extended spatial information provided by the Sentinel-2 super-patches is particularly visible in the last two rows of Figure 4. Indeed, the location on a beach or on a lake is difficult to determine from the aerial image alone, and could easily be confused with the sea for example in the last row.
The model leveraging the additional information outperform a standard baseline model:
Model | mIoU | Building | Pervious Surface | Impervious Surface | Bare Soil | Water | Coniferous | Deciduous | Brushwood | Vineyard | Herbaceous Vegetation | Agricultural Land | Plowed Land |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
U-Net | 0.547 | 0.8009 | 0.4727 | 0.6988 | 0.3076 | 0.7985 | 0.5758 | 0.7014 | 0.2392 | 0.6012 | 0.4653 | 0.5449 | 0.3583 |
U-T&T | 0.5594 | 0.8285 | 0.4980 | 0.7204 | 0.2982 | 0.8009 | 0.6041 | 0.7189 | 0.2541 | 0.6580 | 0.4684 | 0.5478 | 0.3157 |
U-T&T best | 0.5758 | 0.8368 | 0.4995 | 0.7446 | 0.3959 | 0.7952 | 0.6339 | 0.7239 | 0.2485 | 0.6678 | 0.4750 | 0.5513 | 0.3381 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing that out, I should have looked at the paper myself... In that case, if we want to support a resize, it would be more involved, if we wont to resize the sentinel image as well but keeping the resolution difference. Or still just provide the Sentinel 2 scene as context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion would be to initialize a sentinel scaling of 0 to 1 in the model. This in turn could be injected into the loading function.
- 0 would resize the image to the exact extent of the aerial images.
- 1 would take the entire image
- anything between would linearly scale from aerial to original extent
This way, both a straight-forward streamlined model (i.e. uses sentinel as aerial extent as just another source of information) and more sophisticated models that fuse classification at a later point in time could be used. Any suggestions for improvement?
torchgeo/datamodules/flair2.py
Outdated
num_workers: Number of workers for parallel data loading. | ||
augs: Optional augmentations to apply to the dataset. | ||
**kwargs: Additional keyword arguments passed to | ||
:class:`~torchgeo.datasets.Potsdam2D`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to FLAIR2
augs: Optional augmentations to apply to the dataset. | ||
**kwargs: Additional keyword arguments passed to | ||
:class:`~torchgeo.datasets.Potsdam2D`. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add versionadded
for 0.7
use_sentinel: whether to use sentinel data in the dataset # FIXME: sentinel does not work with dataloader due to varying dimensions | ||
|
||
Raises: | ||
DatasetNotFoundError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
versionadded missing
torchgeo/datasets/flair2.py
Outdated
return (tensor - tensor.min()) / (tensor.max() - tensor.min()) | ||
|
||
# Define a colormap for the classes | ||
cmap = ListedColormap([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can go above the init in class attributes
Hi! Sorry for the late response. First of all, thanks for the review. I will get to work on the proposed changes ;-) |
FLAIR#2 dataset
The
FLAIR #2 <https://github.com/IGNF/FLAIR-2>
dataset is an extensive dataset from the French National Institute of Geographical and Forest Information (IGN) that provides a unique and rich resource for large-scale geospatial analysis.The dataset is sampled countrywide and is composed of over 20 billion annotated pixels of very high resolution aerial imagery at 0.2 m spatial resolution, acquired over three years and different months (spatio-temporal domains).
The FLAIR2 dataset is a dataset for semantic segmentation of aerial images. It contains aerial images, sentinel-2 images and masks for 13 classes.
The dataset is split into a training and test set.
Implementation Details
NonGeoDataset
,__init()__
After discussions following #2303, we decided that at least until faulty mask data are fixed the flair2 ds will be of type
NonGeoDataset
. Other than with commonNonGeoDatasets
, FLAIR2 exposes ause_toy
anduse_sentinel
argument. Theuse_toy
-flag will instead use the toy data which is a small subset of data. Theuse_sentinel
argument on the other hand decides whether a sample includes the augmented sentinel data provided by the maintainers of FLAIR2._verify
,_download
,_extract
As each of the splits/sample-types (i.e.
[train, test], [aerial, sentinel, labels]
are contained in a individual zip download, download and extraction has to happen multiple times. On the other hand, the toy dataset is contained in a singular zip. Furthermore, to map the super-patches of the sentinel data to the actual input image, aflair-2_centroids_sp_to_patch.json
is required, which has to be equally has to be downloaded as an individual zip._load_image
,_load_sentinel
,_load_target
For storage reasons, the elevation (5th band) of the image is stored as a uint. The original height thus is multiplied by 5. We decided to divide the height by 5 to get the original height, to make the trained model more usable for other data. See Questions please.
As mentioned previously, additional metadata has to be used to get from the$T \times C=10 \times W \times H$ vary both $T$ and $W$ , $H$ . This is problematic for the
sentinel.npy
to the actual area. Initially for debugging reasons, we implemented to return not the cropped image but the original data and the cropping-slices (i.e. indices). Consequently, the images can be plot in a more meaningful matter. Otherwise, the resolution is so low that one can hardly recognize features. This was crucial for debugging to find the correct logic (classic y, x instead of x, y ordering mistake). We do not know if this is smart for "production code". See Questions please.Moreover, the dimensions of the sentinel data
datamodule
. We have not done extensive research, but the varying dimensions seem to bug the module. Disabling theuse_sentinel
-flag will make the module work.The labels include values from 1 to 19. The datapaper clearly mentions grouping classes$> 13$ into one class
other
due to underrepresentation. We followed this suggestion. Furthermore, rescaling from 0 to 12 was applied. See Questions please.Questions
How shall we load/provide sentinel data? As cropped data or any other way. I do not see the current implementation as fit for production.
Shall we rescale the Classes to start from 0? Shall we group the classes as suggested in the datapaper?
Check integrity in
download_url
does not seem to work (in unit-tests), why?check_integrity
call otherwise it passes, even if md5s do not match.The github actions on the forked repo produce a magic ruff error (https://github.com/MathiasBaumgartinger/torchgeo/actions/runs/11687694109/job/32556175383#step:7:1265). Can you help me resolve this mystery?
TODOs/FIXMEs