Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
b6150da
add RegressionSystem
Zathimo Jul 25, 2024
c4bd970
add poverty example
Zathimo Jul 25, 2024
701edbc
add datasets and outputs to gitignore
Zathimo Jul 25, 2024
06a5518
change description project poverty
LilBabines Jul 31, 2024
5dc5159
add datset landsat
LilBabines Jul 31, 2024
092d882
add datset_poverty modif
LilBabines Jul 31, 2024
7cf0c8e
add datset , .tiff
LilBabines Jul 31, 2024
f446276
display poverty images / bands
LilBabines Jul 31, 2024
19d22c7
modif MSDataset
LilBabines Jul 31, 2024
4af7c49
add label.csv
LilBabines Jul 31, 2024
5e08b87
remove dataset from ignore
LilBabines Jul 31, 2024
4574e1a
write LightningDataModule
LilBabines Jul 31, 2024
9eeca80
add main test
LilBabines Jul 31, 2024
1dfcc81
add observation
LilBabines Jul 31, 2024
71bf40d
rename
LilBabines Jul 31, 2024
38f8725
update description
LilBabines Jul 31, 2024
2572ea9
modifications test_dataset
Zathimo Aug 1, 2024
87fe8f1
add *.tif, landsat_tiles
LilBabines Aug 1, 2024
fed4d58
avancement
LilBabines Aug 1, 2024
51a5511
test
LilBabines Aug 1, 2024
b2f94d5
changes
LilBabines Aug 1, 2024
f583e0d
uptade impot __init__
LilBabines Aug 1, 2024
8925b22
add config
LilBabines Aug 1, 2024
7572e64
works ?
LilBabines Aug 1, 2024
29d7517
changes
LilBabines Aug 1, 2024
87f02ff
add torchmetrics import
LilBabines Aug 2, 2024
8a01f14
add print debugg
LilBabines Aug 2, 2024
6b508d5
add sys.path.append to work with malpolon root package
LilBabines Aug 2, 2024
e0b71ec
changes
LilBabines Aug 2, 2024
594117c
works ??
LilBabines Aug 2, 2024
e2862b9
changes
LilBabines Aug 2, 2024
194f0d4
test
LilBabines Aug 2, 2024
a681826
duplicate data to debugg
LilBabines Aug 2, 2024
61f3980
debugg add print
LilBabines Aug 2, 2024
043f4ec
ca marche pas
LilBabines Aug 2, 2024
7a09c28
remove sample_data
LilBabines Aug 5, 2024
a803476
changes
LilBabines Aug 5, 2024
119e6c4
add normalize mean std
LilBabines Aug 5, 2024
9c3c459
clean main
LilBabines Aug 5, 2024
e1f8e45
clean config
LilBabines Aug 5, 2024
6168e7d
add normalizer transform
LilBabines Aug 5, 2024
e6f89f6
clean print
LilBabines Aug 5, 2024
11dc58f
chabge files names
LilBabines Aug 6, 2024
db17b35
k folds
Zathimo Aug 8, 2024
df1fa9b
k folds merge
Zathimo Aug 8, 2024
7459bfd
train dans la boucle
Zathimo Aug 9, 2024
941ff4a
update de plantnet
Zathimo Aug 9, 2024
ea4d698
sΓ©paration des folds dans le logging
Zathimo Aug 9, 2024
e85835f
add jitter
LilBabines Aug 19, 2024
fdfd415
try debugg jitter
LilBabines Aug 20, 2024
9f57470
launch for distance server
Zathimo Aug 21, 2024
b2b283f
test link with Marbec Data
Zathimo Aug 21, 2024
0283864
k folds with test dataset
Zathimo Aug 21, 2024
096ca76
test new lr and fix example sentinel
Zathimo Aug 22, 2024
39adf00
random split and AdamW optimizer with scheduler
Zathimo Aug 26, 2024
75ef082
random split and DHS fold + test_split
Zathimo Aug 27, 2024
4ea51f6
scheduler CyclicLR
Zathimo Aug 27, 2024
008e0f1
PovertyDataModule inherits BaseDataModule
Zathimo Aug 29, 2024
aa75d08
export_predict_csv
Zathimo Aug 29, 2024
5061221
change metrics name (loss/val to loss_val)
Zathimo Aug 30, 2024
8bf2538
plot results for all 5 folds
Zathimo Aug 30, 2024
f2bd221
Merge branch 'refs/heads/main' into Poverty
Zathimo Sep 9, 2024
b81d9e2
correction bug merge
Zathimo Sep 9, 2024
213459d
additional documentation for PR
Zathimo Sep 11, 2024
ec35bcf
remove / in where="./"
Zathimo Sep 17, 2024
99a68ae
remove the sys path changes
Zathimo Sep 17, 2024
ef68619
swap long/lat columns in observation file
Zathimo Sep 20, 2024
2a5b635
example with no cross-val for PR
Zathimo Oct 10, 2024
1785b4e
adjusted documentation
Zathimo Oct 11, 2024
c8eb216
deleted unnecessary imports
Zathimo Oct 11, 2024
8ee2f21
Merge branch 'poverty' into PR
tlarcher Nov 8, 2024
7fe8257
change request
Zathimo Nov 12, 2024
2f47792
remove poverty example
Zathimo Nov 12, 2024
a3f2b1f
Merge branch 'plantnet:main' into PR
Zathimo Nov 13, 2024
0b087be
Updated glc24_pre_extracted pretrained weights link to address pos_we…
tlarcher Nov 14, 2024
7662e16
Updated setup.py for v2.1.1
tlarcher Nov 14, 2024
4687bf1
Merge pull request #72 from plantnet/dev
tlarcher Nov 14, 2024
8a58c3a
Update README.md
tlarcher Nov 14, 2024
1f41877
Merge branch 'dev'
tlarcher Nov 14, 2024
0d6294a
Fixed broken links in root Reamde
tlarcher Nov 15, 2024
194a18e
git push
tlarcher Nov 15, 2024
a8fd4ed
delete data.to(device)
Zathimo Nov 20, 2024
abc1004
Merge remote-tracking branch 'origin/PR' into PR
Zathimo Nov 20, 2024
a377812
Merge branch 'plantnet:main' into PR
Zathimo Nov 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ examples/benchmarks/cifar-10/outputs/*
dist/
build/

# Training / Inference outputs
outputs/

# Resources
docs/resources/Amap_logo.png
docs/resources/Malpolon_python_v2_image.png
Expand All @@ -48,4 +51,7 @@ examples/custom_train/sentinel-2a-rgbnir/test_bug_rasterio.md
# Miscellaneous
packages_malpolon.png
classes_malpolon.png
classes_yourpackage.png
classes_yourpackage.png

*.tif
landsat_tiles/
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<p align="center">
<a href="https://arxiv.org/abs/2409.18102"><img src="https://img.shields.io/badge/arXiv-2409.18102-f9f107.svg" alt="arxiv paper"></a>
<a href="https://pypi.org/project/malpolon/"><img src="https://img.shields.io/pypi/v/malpolon" alt="Python version"></a>
<a href="https://www.python.org/downloads/release/python-3100/"><img src="https://img.shields.io/pypi/pyversions/malpolon" alt="Python version"></a>
<a href="https://github.com/plantnet/malpolon/issues"><img src="https://img.shields.io/github/issues/plantnet/malpolon" alt="GitHub issues"></a>
Expand Down Expand Up @@ -32,9 +33,9 @@ Here is a list of the currently available scenarios:

- [**Benchmarks**](examples/benchmarks/) : I want to compare the performance of different models on a given known dataset;\
or I am a potential kaggle participant on the GeoLifeClef challenge. I want to train a model on the provided datasets without having to worry about the data loading, starting from a plug-and-play example.
- [<u>GeoLifeClef2022</u>](examples/benchmarks/geolifeclef2022/) : contains a fully functional example of a model training on the GeoLifeClef2022 dataset, from data download, to training and prediction.
- [<u>GeoLifeClef2023</u>](examples/benchmarks/geolifeclef2023/) : contains dataloaders for the GeoLifeClef2023 dataset (different from the GLC2022 dataloaders). The training and prediction scripts are not provided.
- [<u>GeoLifeClef2024 (pre-extracted)</u>](examples/benchmarks/geolifeclef2024_pre_extracted/) : contains a fully functional example of a multimodal ensemble model used to provide a strong baseline for the [GeoLifeClef2024 kaggle competition](https://www.kaggle.com/competitions/geolifeclef-2024). The example uses unique dataloaders and models to handle pre-extracted values from satellite patches, satellite time series and bioclimatic time series.
- [<u>GeoLifeClef2022</u>](examples/benchmarks/geolifeclef/geolifeclef2022/) : contains a fully functional example of a model training on the GeoLifeClef2022 dataset, from data download, to training and prediction.
- [<u>GeoLifeClef2023</u>](examples/benchmarks/geolifeclef/geolifeclef2023/) : contains dataloaders for the GeoLifeClef2023 dataset (different from the GLCgeolifeclef/2022 dataloaders). The training and prediction scripts are not provided.
- [<u>GeoLifeClef2024 (pre-extracted)</u>](examples/benchmarks/geolifeclef/geolifeclef2024_pre_extracted/) : contains a fully functional example of a multimodal ensemble model used to provide a strong baseline for the [GeoLifeClef2024 kaggle competition](https://www.kaggle.com/competitions/geolifeclef-2024). The example uses unique dataloaders and models to handle pre-extracted values from satellite patches, satellite time series and bioclimatic time series.
- [**Train (custom datasets)**](examples/custom_train/) : I have a dataset of my own and I want to train a model on it. I want to be able to easily customize the training process and the model architecture.
- <u>Drop and play</u> : I have an observations file (.csv) and I want to train a model on different environmental variables (rasters, satellite imagery) without having to worry about the data loading.
- <u>Custom dataset</u> : I have my own dataset consisting of pre-extracted image patches and/or rasters and I want to train a model on it.
Expand Down
Binary file added docs/resources/angola_2015.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
outputs

landsat_tiles
*.tif
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

from __future__ import annotations

import os

import hydra
import pytorch_lightning as pl
from omegaconf import DictConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trainer:
# gpus: 1 # Deprecated since pytorchlightning 1.7, removed in 2.0. Replaced by the 2 next attributes
accelerator: "gpu"
devices: 1
max_epochs: 3
max_epochs: 10
# val_check_interval: 2
check_val_every_n_epoch: 1
log_every_n_steps: 10
Expand Down Expand Up @@ -78,6 +78,6 @@ optim:
# kwargs:
# num_classes: *num_classes
multilabel_accuracy:
# callable: 'Fmetrics.classification.multilabel_accuracy'
callable: 'Fmetrics.classification.multilabel_accuracy'
kwargs:
num_labels: ${data.num_classes}
1 change: 0 additions & 1 deletion malpolon/data/datasets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from .torchgeo_datasets import RasterTorchGeoDataset
from .torchgeo_sentinel2 import RasterSentinel2
from .torchgeo_concat import ConcatPatchRasterDataset

__all__ = [
"GeoLifeCLEF2022Dataset",
"MiniGeoLifeCLEF2022Dataset",
Expand Down
2 changes: 2 additions & 0 deletions malpolon/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .standard_prediction_systems import (ClassificationSystem,
RegressionSystem,
GenericPredictionSystem)

__all__ = [ # noqa: F405
"GenericPredictionSystem",
"RegressionSystem"
"ClassificationSystem",
]
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ def __init__(
loss_kwargs['pos_weight'] = Tensor([loss_kwargs['pos_weight']] * num_classes)
super().__init__(model, optimizer=optimizer, metrics=metrics, task=task, loss_kwargs=loss_kwargs, hparams_preprocess=hparams_preprocess, checkpoint_path=checkpoint_path)
if self.model.pretrained and not self.checkpoint_path:
self.download_weights("https://lab.plantnet.org/seafile/f/d780d4ab7f6b419194f9/?dl=1",
self.download_weights("https://lab.plantnet.org/seafile/f/755f49a508db4552b7db/?dl=1",
weights_dir,
filename="pretrained.ckpt",
md5="69111dd8013fcd8e8f4504def774f3a5")
md5="3c2c17d0781016cf71c231761ae73dcc")

def forward(self, x, y, z): # noqa: D102 pylint: disable=C0116
return self.model(x, y, z)
Expand Down
114 changes: 88 additions & 26 deletions malpolon/models/standard_prediction_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@

from pathlib import Path
from typing import TYPE_CHECKING
import json

import pytorch_lightning as pl
import torch
import torchmetrics.functional as Fmetrics
from torchvision.datasets.utils import (download_and_extract_archive,
download_url)
download_url, extract_archive)
import torchvision.models

from torchmetrics.regression import R2Score
from malpolon.models.utils import check_metric

from .utils import check_loss, check_model, check_optimizer, check_scheduler
Expand All @@ -28,38 +31,34 @@
class GenericPredictionSystem(pl.LightningModule):
"""Generic prediction system providing standard methods.


Parameters
----------
model: torch.nn.Module
Model to use.
loss: torch.nn.modules.loss._Loss
Loss used to fit the model.
optimizer : Union[torch.optim.Optimizer, Mapping]
Optimization algorithm(s) used to train the model. There can be
several optimizers passed as an Omegaconf mapping.
scheduler : Union[torch.optim.Optimizer, Mapping], optional
Learning rate scheduler(s) used to train the model. There can be
several schedulers passed as an Omegaconf mapping., by default None
metrics: dict
Dictionary containing the metrics to monitor during the training and
to compute at test time.
save_hyperparameters: bool
Save arguments to hparams attribute.
"""

def __init__(
self,
model: Union[torch.nn.Module, Mapping],
loss: torch.nn.modules.loss._Loss,
optimizer: Union[torch.optim.Optimizer, Mapping],
optimizer: torch.optim.Optimizer,
scheduler: Union[torch.optim.Optimizer] = None,
metrics: Optional[dict[str, Callable]] = None,
save_hyperparameters: Optional[bool] = True,
):
"""Class constructor.

Parameters
----------
model : Union[torch.nn.Module, Mapping]
Model to use.
loss : torch.nn.modules.loss._Loss
Loss used to fit the model.
optimizer : Union[torch.optim.Optimizer, Mapping]
Optimization algorithm(s) used to train the model. There can be
several optimizers passed as an Omegaconf mapping.
scheduler : Union[torch.optim.Optimizer, Mapping], optional
Learning rate scheduler(s) used to train the model. There can be
several schedulers passed as an Omegaconf mapping., by default None
metrics : Optional[dict[str, Callable]], optional
Dictionary containing the metrics to monitor during the training and
to compute at test time., by default None
save_hyperparameters : Optional[bool], optional
Save arguments to hparams attribute., by default True
"""
if save_hyperparameters:
self.save_hyperparameters(ignore=['model', 'loss'])
# Must be placed before the super call (or anywhere in other inheriting
Expand Down Expand Up @@ -159,12 +158,13 @@ def _step(
x, y = batch
y_hat = self(x)

loss = self.loss(y_hat, self._cast_type_to_loss(y)) # Shape mismatch for binary: need to 'y = y.unsqueeze(1)' (or use .reshape(2)) to cast from [2] to [2,1] and cast y to float with .float()
loss = self.loss(y_hat, self._cast_type_to_loss(
y)) # Shape mismatch for binary: need to 'y = y.unsqueeze(1)' (or use .reshape(2)) to cast from [2] to [2,1] and cast y to float with .float()
self.log(f"loss/{split}", loss, **log_kwargs)

for metric_name, metric_func in self.metrics.items():
if isinstance(metric_func, dict):
score = metric_func['callable'](y_hat, y, **metric_func['kwargs'])
score = metric_func['callable'](y_hat, y, metric_func.get('kwargs', {}))
else:
score = metric_func(y_hat, y)
self.log(f"{metric_name}/{split}", score, **log_kwargs)
Expand Down Expand Up @@ -448,4 +448,66 @@ def __init__(
'kwargs': {}}
}

super().__init__(model, loss, optimizer, metrics=metrics)
super().__init__(model, loss, optimizer, metrics)


class RegressionSystem(GenericPredictionSystem):
"""Regression task class."""
def __init__(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some arguments (optimizer kwargs) are not used because incompatible with the proposed default optimizer. I suggest replacing them with the default optimizer's; or simply removing them.

Please update the docstring accordingly too

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the kwargs

self,
model: Union[torch.nn.Module, Mapping],
optimizer: Union[torch.nn.Module, Mapping] = None,
lr: float = 1e-2,
weight_decay: float = 0,
metrics: Optional[dict[str, Callable]] = None,
task: str = 'regression',
hparams_preprocess: bool = True,
):
"""Class constructor.

Parameters
----------
model : dict
model to use
lr : float
learning rate
weight_decay : float
weight decay
metrics : dict
dictionnary containing the metrics to compute.
Keys must match metrics' names and have a subkey with each
metric's functional methods as value. This subkey is either
created from the `malpolon.models.utils.FMETRICS_CALLABLES`
constant or supplied, by the user directly.
task : str, optional
Machine learning task (used to format labels accordingly),
by default 'regression'. The value determines
the loss to be selected.
hparams_preprocess : bool, optional
if True performs preprocessing operations on the hyperparameters,
by default True
"""
if hparams_preprocess:
assert task == 'regression', "Regression task must be specified."
metrics = check_metric(metrics)

self.lr = lr
self.weight_decay = weight_decay

model = check_model(model)

if optimizer is None:
print(f'[INFO] No optimizer provided: using AdamW with lr={lr}, weight_decay={weight_decay}')
optimizer = torch.optim.AdamW(model.parameters(),
lr=lr,
weight_decay=weight_decay)

loss = torch.nn.MSELoss()

if metrics is None:
metrics = {
"regression_R2score": {'callable': Fmetrics.regression.r2_score,
'kwargs': {}}
}

super().__init__(model, loss, optimizer, metrics)
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from setuptools import find_packages, setup

setup(name="malpolon",
version="2.1.0",
description="Malpolon v2.1.0",
version="2.1.1",
description="Malpolon v2.1.1",
author="Theo Larcher, Titouan Lorieul, Benjamin Deneu, Lukas Picek",
author_email="theo.larcher@inria.fr, titouan.lorieul@gmail.com, benjamin.deneu@wsl.ch, lukas.picek@inria.fr",
url="https://github.com/plantnet/malpolon",
Expand All @@ -22,7 +22,7 @@
"Topic :: Scientific/Engineering :: GIS"
],
packages=find_packages(
where="./",
where=".",
include="malpolon*",
exclude="malpolon.tests"),
package_data={'malpolon.data.datasets._data': ['minigeolifeclef2022_species_details.csv']},
Expand Down