Skip to content

Commit

Permalink
Merge branch 'main' into plotCBF
Browse files Browse the repository at this point in the history
  • Loading branch information
calebrob6 committed Mar 20, 2022
2 parents 37fd83a + d51fdfd commit 190c910
Show file tree
Hide file tree
Showing 190 changed files with 5,422 additions and 1,577 deletions.
4 changes: 3 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Do not change line endings on test data, it will change the MD5
/tests/data/*/** binary
/tests/data/*/** -text
# Test data generation files are fine though
/tests/data/**/data.py text
4 changes: 1 addition & 3 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ jobs:
if: ${{ runner.os == 'Windows' }}
- name: Install conda dependencies (Windows)
run: |
# PyTorch isn't compatible with setuptools 59.6+, pin for now until new PyTorch release
# https://github.com/pytorch/pytorch/pull/69904
conda install 'fiona>=1.5' h5py 'rasterio>=1.0.16' 'setuptools<59.6'
conda install 'fiona>=1.5' h5py 'rasterio>=1.0.16'
conda list
conda info
if: ${{ runner.os == 'Windows' }}
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ repos:
additional_dependencies: ["toml"]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
rev: v0.940
hooks:
- id: mypy
args: [--strict, --ignore-missing-imports, --show-error-codes]
additional_dependencies: [torch>=1.7, torchmetrics>=0.7, pytorch-lightning>=1.3, pytest>=6, omegaconf>=2.1, kornia>=0.6, numpy>=1.22.0]
additional_dependencies: [torch>=1.11, torchmetrics>=0.7, pytorch-lightning>=1.3, pytest>=6, omegaconf>=2.1, kornia>=0.6, numpy>=1.22.0]
exclude: (build|data|dist|logo|logs|output)/
8 changes: 6 additions & 2 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
# Required
version: 2

# Set the version of Python
build:
os: ubuntu-20.04
tools:
python: "3.9"

# Configuration of the Python environment to be used
python:
install:
- requirements: docs/requirements.txt
- method: pip
path: .
extra_requirements:
- train

# Configuration for Sphinx documentation
sphinx:
Expand Down
27 changes: 11 additions & 16 deletions benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,16 @@ def set_up_parser() -> argparse.ArgumentParser:
"--patch-size",
default=224,
type=int,
help="height/width of each patch",
metavar="SIZE",
help="height/width of each patch in pixels",
metavar="PIXELS",
)
parser.add_argument(
"-s",
"--stride",
default=112,
type=int,
help="sampling stride for GridGeoSampler",
help="sampling stride for GridGeoSampler in pixels",
metavar="PIXELS",
)
parser.add_argument(
"-w",
Expand Down Expand Up @@ -139,15 +140,11 @@ def main(args: argparse.Namespace) -> None:
length = args.num_batches * args.batch_size
num_batches = args.num_batches

# Convert from pixel coords to CRS coords
size = args.patch_size * cdl.res
stride = args.stride * cdl.res

samplers = [
RandomGeoSampler(landsat, size=size, length=length),
GridGeoSampler(landsat, size=size, stride=stride),
RandomGeoSampler(landsat, size=args.patch_size, length=length),
GridGeoSampler(landsat, size=args.patch_size, stride=args.stride),
RandomBatchGeoSampler(
landsat, size=size, batch_size=args.batch_size, length=length
landsat, size=args.patch_size, batch_size=args.batch_size, length=length
),
]

Expand Down Expand Up @@ -211,17 +208,15 @@ def main(args: argparse.Namespace) -> None:
# Benchmark model
model = resnet34()
# Change number of input channels to match Landsat
model.conv1 = nn.Conv2d( # type: ignore[attr-defined]
model.conv1 = nn.Conv2d(
len(bands), 64, kernel_size=7, stride=2, padding=3, bias=False
)

criterion = nn.CrossEntropyLoss() # type: ignore[attr-defined]
criterion = nn.CrossEntropyLoss()
params = model.parameters()
optimizer = optim.SGD(params, lr=0.0001)

device = torch.device( # type: ignore[attr-defined]
"cuda" if torch.cuda.is_available() else "cpu", args.device
)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu", args.device)
model = model.to(device)

tic = time.time()
Expand All @@ -230,7 +225,7 @@ def main(args: argparse.Namespace) -> None:
num_total_patches += args.batch_size
x = torch.rand(args.batch_size, len(bands), args.patch_size, args.patch_size)
# y = torch.randint(0, 256, (args.batch_size, args.patch_size, args.patch_size))
y = torch.randint(0, 256, (args.batch_size,)) # type: ignore[attr-defined]
y = torch.randint(0, 256, (args.batch_size,))
x = x.to(device)
y = y.to(device)

Expand Down
35 changes: 35 additions & 0 deletions docs/api/datasets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ Geospatial Datasets

:class:`GeoDataset` is designed for datasets that contain geospatial information, like latitude, longitude, coordinate system, and projection. Datasets containing this kind of information can be combined using :class:`IntersectionDataset` and :class:`UnionDataset`.

Aboveground Live Woody Biomass Density
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. autoclass:: AbovegroundLiveWoodyBiomassDensity

Aster Global Digital Evaluation Model
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. autoclass:: AsterGDEM

Canadian Building Footprints
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -32,6 +42,11 @@ Chesapeake Bay High-Resolution Land Cover Project
.. autoclass:: ChesapeakeWV
.. autoclass:: ChesapeakeCVPR

CMS Global Mangrove Canopy Dataset
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. autoclass:: CMSGlobalMangroveCanopy

Cropland Data Layer (CDL)
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -47,6 +62,16 @@ Esri2020

.. autoclass:: Esri2020

EU-DEM
^^^^^^

.. autoclass:: EUDEM

GlobBiomass
^^^^^^^^^^^

.. autoclass:: GlobBiomass

Landsat
^^^^^^^

Expand All @@ -67,6 +92,11 @@ National Agriculture Imagery Program (NAIP)

.. autoclass:: NAIP

Open Buildings
^^^^^^^^^^^^^^

.. autoclass:: OpenBuildings

Sentinel
^^^^^^^^

Expand Down Expand Up @@ -217,6 +247,11 @@ UC Merced

.. autoclass:: UCMerced

USAVars
^^^^^^^

.. autoclass:: USAVars

Vaihingen
^^^^^^^^^

Expand Down
29 changes: 27 additions & 2 deletions docs/api/samplers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ Samplers are used to index a dataset, retrieving a single query at a time. For :
from torchgeo.samplers import RandomGeoSampler
dataset = Landsat(...)
sampler = RandomGeoSampler(dataset, size=1000, length=100)
sampler = RandomGeoSampler(dataset, size=256, length=10000)
dataloader = DataLoader(dataset, sampler=sampler)
This data loader will return 256x256 px images, and has an epoch length of 10,000.

Random Geo Sampler
^^^^^^^^^^^^^^^^^^

Expand All @@ -43,10 +45,12 @@ When working with large tile-based datasets, randomly sampling patches from each
from torchgeo.samplers import RandomBatchGeoSampler
dataset = Landsat(...)
sampler = RandomBatchGeoSampler(dataset, size=1000, batch_size=10, length=100)
sampler = RandomBatchGeoSampler(dataset, size=256, batch_size=128, length=10000)
dataloader = DataLoader(dataset, batch_sampler=sampler)
This data loader will return 256x256 px images, and has a batch size of 128 and an epoch length of 10,000.

Random Batch Geo Sampler
^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -66,3 +70,24 @@ Batch Geo Sampler
^^^^^^^^^^^^^^^^^

.. autoclass:: BatchGeoSampler

Units
-----

By default, the ``size`` parameter specifies the size of the image in *pixel* units. If you would instead like to specify the size in *CRS* units, you can change the ``units`` parameter like so:

.. code-block:: python
from torch.utils.data import DataLoader
from torchgeo.datasets import Landsat
from torchgeo.samplers import RandomGeoSampler, Units
dataset = Landsat(...)
sampler = RandomGeoSampler(dataset, size=256 * 30, length=10000, units=Units.CRS)
dataloader = DataLoader(dataset, sampler=sampler)
Assuming that each pixel in the CRS is 30 m, this data loader will return 256x256 px images, and has an epoch length of 10,000.

.. autoclass:: Units
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"sphinx.ext.todo",
"sphinx.ext.viewcode",
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/trainers.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -492,13 +492,13 @@
" csv_reader = csv.DictReader(f, delimiter=',')\n",
" for i, row in enumerate(csv_reader):\n",
" try:\n",
" train_rmse.append(float(row[\"train_rmse\"]))\n",
" train_rmse.append(float(row[\"train_RMSE\"]))\n",
" train_steps.append(i)\n",
" except ValueError: # Ignore rows where train RMSE is empty\n",
" pass\n",
"\n",
" try:\n",
" val_rmse.append(float(row[\"val_rmse\"]))\n",
" val_rmse.append(float(row[\"val_RMSE\"]))\n",
" val_steps.append(i)\n",
" except ValueError: # Ignore rows where val RMSE is empty\n",
" pass"
Expand Down
17 changes: 9 additions & 8 deletions evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import pytorch_lightning as pl
import torch
from torchmetrics import Accuracy, JaccardIndex, Metric, MetricCollection
from torchmetrics import Accuracy, JaccardIndex, MetricCollection

from torchgeo.trainers import ClassificationTask, SemanticSegmentationTask
from train import TASK_TO_MODULES_MAPPING
Expand Down Expand Up @@ -85,19 +85,20 @@ def set_up_parser() -> argparse.ArgumentParser:
def run_eval_loop(
model: pl.LightningModule,
dataloader: Any,
device: torch.device, # type: ignore[name-defined]
metrics: Metric,
device: torch.device,
metrics: MetricCollection,
) -> Any:
"""Runs a standard test loop over a dataloader and records metrics.
Args:
model: the model used for inference
dataloader: the dataloader to get samples from
device: the device to put data on
metrics: a torchmetrics compatible Metric to score the output from the model
metrics: a torchmetrics compatible metric collection to score the output
from the model
Returns:
the result of ``metric.compute()``
the result of ``metrics.compute()``
"""
for batch in dataloader:
x = batch["image"].to(device)
Expand Down Expand Up @@ -158,7 +159,7 @@ def main(args: argparse.Namespace) -> None:
"loss": model.hparams["loss"],
}
elif issubclass(TASK, SemanticSegmentationTask):
val_row: Dict[str, Union[str, float]] = { # type: ignore[no-redef]
val_row = {
"split": "val",
"segmentation_model": model.hparams["segmentation_model"],
"encoder_name": model.hparams["encoder_name"],
Expand All @@ -167,7 +168,7 @@ def main(args: argparse.Namespace) -> None:
"loss": model.hparams["loss"],
}

test_row: Dict[str, Union[str, float]] = { # type: ignore[no-redef]
test_row = {
"split": "test",
"segmentation_model": model.hparams["segmentation_model"],
"encoder_name": model.hparams["encoder_name"],
Expand All @@ -179,7 +180,7 @@ def main(args: argparse.Namespace) -> None:
raise ValueError(f"{TASK} is not supported")

# Compute metrics
device = torch.device("cuda:%d" % (args.gpu)) # type: ignore[attr-defined]
device = torch.device("cuda:%d" % (args.gpu))
model = model.to(device)

if args.task == "etci2021": # Custom metric setup for testing ETCI2021
Expand Down
Binary file added tests/data/agb_live_woody_density/00N_000E.tif
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"type": "FeatureCollection", "name": "Aboveground_Live_Woody_Biomass_Density", "crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}}, "features": [{"type": "Feature", "properties": {"tile_id": "00N_000E", "download": "tests/data/agb_live_woody_density/00N_000E.tif", "ObjectId": 1, "Shape__Area": 1245542622548.87, "Shape__Length": 4464169.76558139}, "geometry": {"type": "Polygon", "coordinates": [[[0.0, 0.0], [10.0, 0.0], [10.0, -10.0], [0.0, -10.0], [0.0, 0.0]]]}}]}
Loading

0 comments on commit 190c910

Please sign in to comment.