{"id":6312,"name":"cultionet","description":"A library for semantic segmentation of cultivated land using a neural network.","url":"https://github.com/jgrss/cultionet","last_synced_at":"2026-04-14T18:00:21.681Z","repository":{"id":37023472,"uuid":"471170542","full_name":"jgrss/cultionet","owner":"jgrss","description":"Image segmentation of cultivated land","archived":false,"fork":false,"pushed_at":"2024-09-23T11:12:50.000Z","size":57809,"stargazers_count":31,"open_issues_count":7,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-12T17:02:30.314Z","etag":null,"topics":["agriculture","cropland","crops","deep-learning","fields","land-cover","pytorch","pytorch-lightning","remote-sensing","satellite"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jgrss.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-17T23:10:24.000Z","updated_at":"2026-01-25T08:43:05.000Z","dependencies_parsed_at":"2023-09-21T19:14:22.082Z","dependency_job_id":"c33e46c3-6d87-41b6-94ec-f18bac9de440","html_url":"https://github.com/jgrss/cultionet","commit_stats":{"total_commits":112,"total_committers":5,"mean_commits":22.4,"dds":0.2767857142857143,"last_synced_commit":"b51ca732fad394933c78cc25b24c580a56cf8c6c"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/jgrss/cultionet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgrss","download_url":"https://codeload.github.com/jgrss/cultionet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31808518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T11:13:53.975Z","status":"ssl_error","status_checked_at":"2026-04-14T11:13:53.299Z","response_time":153,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"owner":{"login":"jgrss","name":"Jordan Graesser","uuid":"6633570","kind":"user","description":"","email":"","website":"https://jgrss.github.io","location":null,"twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/6633570?u=51083118b999bed0a51c312b3c59eee5e3b3d731\u0026v=4","repositories_count":19,"last_synced_at":"2024-04-24T06:22:06.779Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/jgrss","funding_links":[],"total_stars":285,"followers":75,"following":11,"created_at":"2022-11-14T07:34:33.641Z","updated_at":"2024-04-24T06:22:10.775Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgrss","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgrss/repositories"},"packages":[],"commits":{"id":1322752,"full_name":"jgrss/cultionet","default_branch":"main","total_commits":112,"total_committers":4,"total_bot_commits":0,"total_bot_committers":0,"mean_commits":28.0,"dds":0.044642857142857095,"past_year_total_commits":0,"past_year_total_committers":0,"past_year_total_bot_commits":0,"past_year_total_bot_committers":0,"past_year_mean_commits":0.0,"past_year_dds":0.0,"last_synced_at":"2026-04-14T08:27:43.545Z","last_synced_commit":"b51ca732fad394933c78cc25b24c580a56cf8c6c","created_at":"2023-09-11T15:24:30.102Z","updated_at":"2026-04-14T08:27:41.525Z","committers":[{"name":"Jordan Graesser","email":"jgrss","login":"jgrss","count":107},{"name":"Michael Mann","email":"mmann1123@gmail.com","login":"mmann1123","count":2},{"name":"MatthewPierson90","email":"76757690+MatthewPierson90","login":"MatthewPierson90","count":2},{"name":"nnguyen622","email":"67288443+nnguyen622","login":"nnguyen622","count":1}],"past_year_committers":[],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-14T00:00:07.982Z","repositories_count":6213305,"commits_count":903405131,"contributors_count":34927098,"owners_count":1144355,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"jgrss/cultionet","html_url":"https://github.com/jgrss/cultionet","last_synced_at":"2026-02-06T09:01:04.482Z","status":"error","issues_count":19,"pull_requests_count":72,"avg_time_to_close_issue":15425928.2,"avg_time_to_close_pull_request":994719.304347826,"issues_closed_count":15,"pull_requests_closed_count":69,"pull_request_authors_count":4,"issue_authors_count":4,"avg_comments_per_issue":7.105263157894737,"avg_comments_per_pull_request":0.08333333333333333,"merged_pull_requests_count":63,"bot_issues_count":0,"bot_pull_requests_count":0,"past_year_issues_count":0,"past_year_pull_requests_count":16,"past_year_avg_time_to_close_issue":null,"past_year_avg_time_to_close_pull_request":3680.3125,"past_year_issues_closed_count":0,"past_year_pull_requests_closed_count":16,"past_year_pull_request_authors_count":1,"past_year_issue_authors_count":0,"past_year_avg_comments_per_issue":null,"past_year_avg_comments_per_pull_request":0.0,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":14,"created_at":"2023-09-11T15:25:04.546Z","updated_at":"2026-02-06T09:01:04.482Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgrss%2Fcultionet/issues","issue_labels_count":{"documentation":2,"enhancement":1,"bug":1},"pull_request_labels_count":{"bug":17,"enhancement":11,"documentation":8},"issue_author_associations_count":{"CONTRIBUTOR":14,"OWNER":3,"NONE":1},"pull_request_author_associations_count":{"OWNER":72,"CONTRIBUTOR":7,"COLLABORATOR":1},"issue_authors":{"MatthewPierson90":10,"mmann1123":4,"jgrss":3,"varunshah111":1},"pull_request_authors":{"jgrss":72,"MatthewPierson90":5,"mmann1123":2,"nnguyen622":1},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-06T00:00:09.270Z","repositories_count":14106272,"issues_count":34454647,"pull_requests_count":112472246,"authors_count":11227558,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{},"past_year_pull_request_labels_count":{},"past_year_issue_author_associations_count":{},"past_year_pull_request_author_associations_count":{},"past_year_issue_authors":{},"past_year_pull_request_authors":{},"maintainers":[{"login":"jgrss","count":75,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jgrss"},{"login":"nnguyen622","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/nnguyen622"}],"active_maintainers":[]},"events":{"total":{"WatchEvent":2},"last_year":{"WatchEvent":1}},"keywords":["agriculture","cropland","crops","deep-learning","fields","land-cover","pytorch","pytorch-lightning","remote-sensing","satellite"],"dependencies":[{"ecosystem":"pypi","filepath":"docs/requirements.txt","sha":null,"kind":"manifest","created_at":"2022-09-11T01:13:08.926Z","updated_at":"2022-09-11T01:13:08.926Z","repository_link":"https://github.com/jgrss/cultionet/blob/main/docs/requirements.txt","dependencies":[{"id":4442447392,"package_name":"attrs","ecosystem":"pypi","requirements":"\u003e=21.","direct":true,"kind":"runtime","optional":false},{"id":4442447393,"package_name":"frozendict","ecosystem":"pypi","requirements":"\u003e=2.2.","direct":true,"kind":"runtime","optional":false},{"id":4442447394,"package_name":"frozenlist","ecosystem":"pypi","requirements":"\u003e=1.3.","direct":true,"kind":"runtime","optional":false},{"id":4442447395,"package_name":"numpy","ecosystem":"pypi","requirements":"\u003c=1.21.0","direct":true,"kind":"runtime","optional":false},{"id":4442447396,"package_name":"scipy","ecosystem":"pypi","requirements":"\u003e=1.2.","direct":true,"kind":"runtime","optional":false},{"id":4442447397,"package_name":"pandas","ecosystem":"pypi","requirements":"\u003c=1.3.5","direct":true,"kind":"runtime","optional":false},{"id":4442447398,"package_name":"geopandas","ecosystem":"pypi","requirements":"\u003e=0.10.","direct":true,"kind":"runtime","optional":false},{"id":4442447399,"package_name":"rasterio","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":4442447400,"package_name":"shapely","ecosystem":"pypi","requirements":"\u003e=1.8.","direct":true,"kind":"runtime","optional":false},{"id":4442447401,"package_name":"scikit-image","ecosystem":"pypi","requirements":"\u003e=0.19.","direct":true,"kind":"runtime","optional":false},{"id":4442447402,"package_name":"xarray","ecosystem":"pypi","requirements":"\u003e=0.21.","direct":true,"kind":"runtime","optional":false},{"id":4442447403,"package_name":"opencv-python","ecosystem":"pypi","requirements":"\u003e=4.5.5.","direct":true,"kind":"runtime","optional":false},{"id":4442447404,"package_name":"torch","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":4442447405,"package_name":"pytorch_lightning","ecosystem":"pypi","requirements":"\u003e=1.5.9","direct":true,"kind":"runtime","optional":false},{"id":4442447406,"package_name":"torchmetrics","ecosystem":"pypi","requirements":"\u003e=0.7.0","direct":true,"kind":"runtime","optional":false},{"id":4442447407,"package_name":"torch-geometric","ecosystem":"pypi","requirements":"\u003e=2.0.2","direct":true,"kind":"runtime","optional":false},{"id":4442447408,"package_name":"torch-geometric-temporal","ecosystem":"pypi","requirements":"\u003e=0.40","direct":true,"kind":"runtime","optional":false},{"id":4442447409,"package_name":"decorator","ecosystem":"pypi","requirements":"==4.4.2","direct":true,"kind":"runtime","optional":false},{"id":4442447410,"package_name":"rtree","ecosystem":"pypi","requirements":"\u003e=0.9.7","direct":true,"kind":"runtime","optional":false},{"id":4442447411,"package_name":"graphviz","ecosystem":"pypi","requirements":"\u003e=0.19.","direct":true,"kind":"runtime","optional":false},{"id":4442447412,"package_name":"tqdm","ecosystem":"pypi","requirements":"\u003e=4.62.","direct":true,"kind":"runtime","optional":false},{"id":4442447413,"package_name":"pyDeprecate","ecosystem":"pypi","requirements":"==0.3.1","direct":true,"kind":"runtime","optional":false},{"id":4442447414,"package_name":"future","ecosystem":"pypi","requirements":"\u003e=0.17.1","direct":true,"kind":"runtime","optional":false},{"id":4442447415,"package_name":"tensorboard","ecosystem":"pypi","requirements":"\u003e=2.2.0","direct":true,"kind":"runtime","optional":false},{"id":4442447416,"package_name":"PyYAML","ecosystem":"pypi","requirements":"\u003e=5.1","direct":true,"kind":"runtime","optional":false},{"id":4442447417,"package_name":"setuptools","ecosystem":"pypi","requirements":"==59.5.0","direct":true,"kind":"runtime","optional":false},{"id":4442447418,"package_name":"numpydoc","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":4442447419,"package_name":"sphinx","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":4442447420,"package_name":"sphinx-automodapi","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":4442447421,"package_name":"sphinxcontrib-apidoc","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":4442447422,"package_name":"sphinxcontrib-bibtex","ecosystem":"pypi","requirements":"==1.0.0","direct":true,"kind":"runtime","optional":false},{"id":4442447423,"package_name":"sphinxcontrib-napoleon","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/ci.yml","sha":null,"kind":"manifest","created_at":"2023-09-21T19:14:20.400Z","updated_at":"2023-09-21T19:14:20.400Z","repository_link":"https://github.com/jgrss/cultionet/blob/main/.github/workflows/ci.yml","dependencies":[{"id":13856554843,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":13856554844,"package_name":"actions/setup-python","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":13856554845,"package_name":"syphar/restore-virtualenv","ecosystem":"actions","requirements":"v1","direct":true,"kind":"composite","optional":false},{"id":13856554846,"package_name":"syphar/restore-pip-download-cache","ecosystem":"actions","requirements":"v1","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"docker","filepath":"Dockerfile","sha":null,"kind":"manifest","created_at":"2023-09-21T19:14:20.708Z","updated_at":"2023-09-21T19:14:20.708Z","repository_link":"https://github.com/jgrss/cultionet/blob/main/Dockerfile","dependencies":[{"id":13856554849,"package_name":"nvidia/cuda","ecosystem":"docker","requirements":"11.3.0-base-ubuntu20.04","direct":true,"kind":"build","optional":false}]},{"ecosystem":"pypi","filepath":"environment.yml","sha":null,"kind":"manifest","created_at":"2023-09-21T19:14:20.921Z","updated_at":"2023-09-21T19:14:20.921Z","repository_link":"https://github.com/jgrss/cultionet/blob/main/environment.yml","dependencies":[]},{"ecosystem":"pypi","filepath":"pyproject.toml","sha":null,"kind":"manifest","created_at":"2023-09-21T19:14:21.153Z","updated_at":"2023-09-21T19:14:21.153Z","repository_link":"https://github.com/jgrss/cultionet/blob/main/pyproject.toml","dependencies":[]},{"ecosystem":"pypi","filepath":"setup.py","sha":null,"kind":"manifest","created_at":"2023-09-21T19:14:21.310Z","updated_at":"2023-09-21T19:14:21.310Z","repository_link":"https://github.com/jgrss/cultionet/blob/main/setup.py","dependencies":[]}],"score":5.0238805208462765,"created_at":"2023-09-11T14:33:16.129Z","updated_at":"2026-04-14T18:00:21.683Z","avatar_url":"https://github.com/jgrss.png","language":"Python","category":"Natural Resources","sub_category":"Soil and Land","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![python](https://img.shields.io/badge/Python-3.9%20%7C%203.10-3776AB.svg?style=flat\u0026logo=python\u0026logoColor=white)](https://www.python.org)\n\u003c!-- [![](https://img.shields.io/github/v/release/jgrss/cultionet?display_name=release)](https://github.com/jgrss/cultionet/releases) --\u003e\n![](https://img.shields.io/badge/Version-v2.0.0b-8A2BE2)\n[![](https://github.com/jgrss/cultionet/actions/workflows/ci.yml/badge.svg)](https://github.com/jgrss/cultionet/actions?query=workflow%3ACI)\n\n## Cultionet\n\nCultionet is a library for semantic segmentation of cultivated land with a neural network. The base architecture is a UNet variant, inspired by [UNet 3+](https://arxiv.org/abs/2004.08790) and [Psi-Net](https://arxiv.org/abs/1902.04099), with convolution blocks following [ResUNet-a](https://arxiv.org/abs/1904.00592). The library is built on [PyTorch Lightning](https://www.pytorchlightning.ai/) and the segmentation objectives (class targets and losses) were designed following [previous work in the remote sensing community](https://www.sciencedirect.com/science/article/abs/pii/S0034425720301115).\n\nKey features of Cultionet:\n\n* uses satellite image time series instead of individual dates for training and inference\n* uses a [Transformer](https://arxiv.org/abs/1706.03762) time series embeddings\n* uses a UNet architecture with skip connections and deep supervision similar to [UNet 3+](https://arxiv.org/abs/2004.08790)\n* uses multi-stream outputs inspired by [Psi-Net](https://arxiv.org/abs/1902.04099)\n* uses residual [ResUNet-a](https://arxiv.org/abs/1904.00592) blocks with [Dilated Neighborhood Attention](https://arxiv.org/abs/2209.15001)\n* uses the [Tanimoto loss](https://www.mdpi.com/2072-4292/13/18/3707)\n\n## Install Cultionet\n\nIf PyTorch is installed\n\n```commandline\npip install git@github.com:jgrss/cultionet.git\n```\n\nSee the [installation section](#installation) for more detailed instructions.\n\n---\n\n## Data format\n\nThe model inputs are satellite time series (e.g., bands or spectral indices). Data are stored in a PyTorch [Data](https://github.com/jgrss/cultionet/blob/99fb16797f2d84b812c47dd9d03aea92b6b7aefa/src/cultionet/data/data.py#L51) object. For example, Cultionet datasets will have data that look something like the following.\n\n```python\nData(\n  x=[1, 3, 12, 100, 100], y=[1, 100, 100], bdist=[1, 100, 100],\n  start_year=torch.tensor([2020]), end_year=torch.tensor([2021]),\n  left=torch.tensor([\u003clongitude\u003e]), bottom=torch.tensor([\u003clatitude\u003e]),\n  right=torch.tensor([\u003clongitude\u003e]), top=torch.tensor([\u003clatitude\u003e]),\n  res=torch.tensor([10.0]), batch_id=['{site id}_2021_1_none'],\n)\n```\n\nwhere\n\n```\nx = input features = torch.Tensor of (batch x channels/bands x time x height x width)\ny = labels = torch.Tensor of (batch x height x width)\nbdist = distance transform = torch.Tensor of (batch x height x width)\nleft = image left coordinate bounds = torch.Tensor\nbottom = image bottom coordinate bounds = torch.Tensor\nright = image right coordinate bounds = torch.Tensor\ntop = image top coordinate bounds = torch.Tensor\nres = image spatial resolution = torch.Tensor\nbatch_id = image id = list\n```\n\n## Datasets\n\n### Create the vector training dataset\n\nTraining data pairs should consist of two files per grid/year. One file is a polygon vector file (stored as a GeoPandas-compatible\nformat like GeoPackage) of the training grid for a region. The other file is a polygon vector file (stored in the same format)\nof the training labels for a grid.\n\n**What is a grid?**\n\u003e A grid defines an area to be labeled. For example, a grid could be 1 km x 1 km. A grid should be small enough to be combined\n\u003e with other grids in batches in GPU memory. Thus, 1 km x 1 km is a good size with, say, Sentinel-2 imagery at 10 m spatial\n\u003e resolution.\n\n\u003e **Note:** grids across a study area should all be of equal dimensions\n\n**What is a training label?**\n\u003e Training labels are __polygons__ of delineated cropland (i.e., crop fields). The training labels will be clipped to the\n\u003e training grid (described above). Thus, it is important to digitize all crop fields within a grid unless data are to be used\n\u003e for partial labels.\n\n**Configuration file**\n\u003e The configuration file is used to create training datasets. Copy the [config template](scripts/config.yml) and modify it accordingly.\n\n**Training data requirements**\n\u003e The polygon vector file should have a field with values for crop fields set equal to 1. Other crop classes are allowed and\n\u003e can be recoded during the data creation step. However, the current version of cultionet expects the final data to be binary\n\u003e (i.e., 0=non-cropland; 1=cropland). For grids with all null data (i.e., non-crop), simply create a grid file with no intersecting\n\u003e crop polygons.\n\n**Training name requirements**\n\u003e There are no requirements. Simply specify the paths in the configuration file.\n\nExample directory structure and format for training data. For each region, there is a grid file and a polygon file. The\nnumber of grid/polygon pairs within the region is unlimited.\n\n```yaml\nregion_id_file:\n  - /user_data/training/grid_REGION_A_YEAR.gpkg\n  - /user_data/training/grid_REGION_B_YEAR.gpkg\n  - ...\n\npolygon_file:\n  - /user_data/training/crop_polygons_REGION_A_YEAR.gpkg\n  - /user_data/training/crop_polygons_REGION_B_YEAR.gpkg\n  - ...\n```\n\nThe grid file should contain polygons of the AOIs. The AOIs represent the area that imagery will be clipped and masked to (only 1 km x 1 km has been tested). Required\ncolumns include 'geo_id' and 'year', which are a unique identifier and the sampling year, respectively.\n\n```python\ngrid_df = gpd.read_file(\"/user_data/training/grid_REGION_A_YEAR.gpkg\")\ngrid_df.head(2)\n\n \t                                     geo_id year \t    geometry\n0 \tREGION_A_e3a4f2346f50984d87190249a5def1d0 2021 POLYGON ((...\n1 \tREGION_A_18485a3271482f2f8a10bb16ae59be74 2021 POLYGON ((...\n```\n\nThe polygon file should contain polygons of field boundaries, with a column for the crop class. Any number of other columns can be included. Note that polygons do not need to be clipped to the grids.\n\n```python\nimport geopandas as gpd\npoly_df = gpd.read_file(\"/user_data/training/crop_polygons_REGION_A_YEAR.gpkg\")\npoly_df.head(2)\n \tcrop_class      geometry\n0          1 POLYGON ((...\n1          1 POLYGON ((...\n```\n\n### Create the image time series\n\nThis must be done outside of Cultionet. Essentially, a directory with band or VI time series must be generated before\nusing Cultionet.\n\n- The raster files should be stored as GeoTiffs with names that follow a date format (e.g., `yyyyddd.tif` or `yyymmdd.tif`).\n  - The date format can be specified at the CLI.\n- There is no maximum requirement on the temporal frequency (i.e., daily, weekly, bi-weekly, monthly, etc.).\n  - Just note that a higher frequency will result in larger memory footprints for the GPU, plus slower training and inference.\n- While there is no requirement for the time series frequency, time series _must_ have different start and end years.\n  - For example, a northern hemisphere time series might consist of (1 Jan 2020 to 1 Jan 2021) whereas a southern hemisphere time series might range from (1 July 2020 to 1 July 2021). In either case, note that something like (1 Jan 2020 to 1 Dec 2020) will not work.\n- Time series should align with the training data files. More specifically, the training data year (year in the grid vector file) should correspond to the time series start year.\n  - For example, a training grid 'year' column equal to 2022 should be trained on a 2022-2023 image time series.\n- The image time series footprints (bounding box) can be of any size, but should encompass the training data bounds. During data creation (next step below), only the relevant bounds of the image are extracted and matched with the training data using the training grid bounds.\n\nExample time series directory with bi-weekly cadence for three VIs (i.e., evi2, gcvi, kndvi)\n\n```yaml\nproject_dir:\n   time_series_vars:\n      grid_id_a:\n         evi2:\n          2022001.tif\n          2022014.tif\n          ...\n          2023001.tif\n         gcvi:\n          \u003crepeat of above\u003e\n         kndvi:\n          \u003crepeat of above\u003e\n      grid_id_b:\n        \u003crepeat of above\u003e\n```\n\n### Create the time series training dataset\n\nAfter training data and image time series have been created, the training data PyTorch files (.pt) can be generated using the commands below.\n\n\u003e **Note:** Modify a copy of the [config template](scripts/config.yml) as needed and save in the project directory. The command below assumes image time series are saved under `/project_dir/time_series_vars`. The training polygon and grid paths are taken from the config.yml file.\n\nThis command would generate .pt files with image time series of 100 x 100 height/width and a spatial resolution of 10 meters.\n\n```commandline\n# Activate your virtual environment. See installation section below for environment details.\npyenv venv venv.cultionet\n# Create the training dataset.\n(venv.cultionet) cultionet create --project-path /project_dir --grid-size 100 100 --destination train -r 10.0 --max-crop-class 1 --crop-column crop_class --image-date-format %Y%m%d --num-workers 8 --config-file config.yml\n```\n\nThe output .pt data files will be stored in `/project_dir/data/train/processed`. Each .pt data file will consist of\nall the information needed to train the segmentation model.\n\n## Training a model\n\nTo train a model on a dataset, use (as an example):\n\n```commandline\n(venv.cultionet) cultionet train --val-frac 0.2 --augment-prob 0.5 --epochs 100 --hidden-channels 32 --processes 8 --load-batch-workers 8 --batch-size 4 --accumulate-grad-batches 4 --dropout 0.2 --deep-sup --dilations 1 2 --pool-by-max --learning-rate 0.01 --weight-decay 1e-4 --attention-weights natten\n```\n\nFor more CLI options, see:\n\n```commandline\n(venv.cultionet) cultionet train -h\n```\n\nAfter a model has been fit, the best/last checkpoint file can be found at `/project_dir/ckpt/last.ckpt`.\n\n## Predicting on an image with a trained model\n\n### First, a prediction dataset is needed\n\n```commandline\n(venv.cultionet) cultionet create-predict --project-path /project_dir --year 2022 --ts-path /features\n--num-workers 4 --config-file project_config.yml\n```\n\n### Apply inference over the predictin dataset\n\n```commandline\n(venv.cultionet) cultionet predict --project-path /project_dir --out-path predictions.tif --grid-id 1 --window-size 100 --config-file project_config.yml --device gpu --processes 4\n```\n\n## Installation\n\n#### Install Cultionet (assumes a working CUDA installation)\n\n1. Create a new virtual environment (example using [pyenv](https://github.com/pyenv/pyenv))\n```commandline\npyenv virtualenv 3.10.14 venv.cultionet\npyenv activate venv.cultionet\n```\n\n2. Update install numpy and Python GDAL (assumes GDAL binaries are already installed)\n```commandline\n(venv.cultionet) pip install -U pip\n(venv.cultionet) pip install -U setuptools wheel\npip install -U numpy==1.24.4\n(venv.cultionet) pip install setuptools==57.5.0\n(venv.cultionet) GDAL_VERSION=$(gdal-config --version | awk -F'[.]' '{print $1\".\"$2\".\"$3}')\n(venv.cultionet) pip install GDAL==$GDAL_VERSION --no-binary=gdal\n```\n\n3. Install PyTorch 2.2.1 for CUDA 11.4 and 11.8\n```commandline\n(venv.cultionet) pip install -U --no-cache-dir setuptools\u003e=65.5.1\n(venv.cultionet) pip install torch==2.2.2 torchvision==0.17.2 torchaudio==2.2.2 --index-url https://download.pytorch.org/whl/cu118\n```\n\nThe command below should print `True` if PyTorch can access a GPU.\n\n```commandline\npython -c \"import torch;print(torch.cuda.is_available())\"\n```\n\n4. Install `natten` for CUDA 11.8 if using [neighborhood attention](https://github.com/SHI-Labs/NATTEN).\n```commandline\n(venv.cultionet) pip install natten==0.17.1+torch220cu118 -f https://shi-labs.com/natten/wheels\n```\n\n5. Install cultionet\n\n```commandline\n(venv.cultionet) pip install git@github.com:jgrss/cultionet.git\n```\n\n### Installing CUDA on Ubuntu\n\nSee [CUDA installation](docs/cuda_installation.md)\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":["geography","rasterio"],"project_url":"https://ost.ecosyste.ms/api/v1/projects/6312","html_url":"https://ost.ecosyste.ms/projects/6312"}