{"id":23652919,"url":"https://github.com/restlessronin/fastgs","last_synced_at":"2025-08-14T08:06:17.138Z","repository":{"id":62773961,"uuid":"557972840","full_name":"restlessronin/fastgs","owner":"restlessronin","description":"Geospatial (Sentinel2 Multi-Spectral) support for fastai","archived":false,"fork":false,"pushed_at":"2023-02-02T01:10:59.000Z","size":65520,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-04T08:43:21.993Z","etag":null,"topics":["fastai","geospatial","multi-spectral","nbdev","sentinel2"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","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/restlessronin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-10-26T16:46:53.000Z","updated_at":"2024-07-03T09:46:00.000Z","dependencies_parsed_at":"2023-02-10T02:45:38.863Z","dependency_job_id":null,"html_url":"https://github.com/restlessronin/fastgs","commit_stats":{"total_commits":113,"total_committers":1,"mean_commits":113.0,"dds":0.0,"last_synced_commit":"33df7c2a4343e8780ceaa7e74e9a5a85963bf72d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/restlessronin/fastgs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/restlessronin%2Ffastgs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/restlessronin%2Ffastgs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/restlessronin%2Ffastgs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/restlessronin%2Ffastgs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/restlessronin","download_url":"https://codeload.github.com/restlessronin/fastgs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/restlessronin%2Ffastgs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270385467,"owners_count":24574556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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"}},"keywords":["fastai","geospatial","multi-spectral","nbdev","sentinel2"],"created_at":"2024-12-28T17:22:43.450Z","updated_at":"2025-08-14T08:06:17.055Z","avatar_url":"https://github.com/restlessronin.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"Welcome to fastgs\n================\n\n\u003c!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! --\u003e\n\n## Introduction\n\n**This library is currently in *alpha*, neither the functionality nor\nthe API is stable**. Feedback / PR’s welcome!\n\nThis library provides geospatial multi-spectral image support for\nfastai. FastAI already has extensive support for RGB images in the\npipeline. I try to achieve feature parity for multi-spectral images with\nthis library, specifically in the context of Sentinel 2 geospatial\nimaging.\n\n## Demo Notebooks\n\nComplete examples are provided in the following notebooks\n\n1.  working with a netCDF sample\n    [KappaSet](https://www.kaggle.com/code/restlessronin/netcdf-demo-fastai-using-fastgs).\n    demo code for brightness factor calculation by\n    [@wrignj08](https://github.com/wrignj08). Shows how to load images\n    with all channels stored in a single netCDF file.\n2.  working with the kaggle [38-cloud/95-cloud landsat\n    dataset](https://www.kaggle.com/code/restlessronin/cloud95-fastai-with-fastgs-multispectral-support).\n    Shows how to load images stored in a “single channel per file”\n    format (seems to be the common case).\n3.  working on a segmentation problem with a [Sentinel 2\n    dataset](https://www.kaggle.com/code/restlessronin/lila-sentinel-2-segmentation-with-fastai)\n\nThese are boths works in progress and optimized to display the features\nof the library, rather than the best possible results. Even so, the\n“cloud 95” notebook is providing results comparable to other hiqh\nquality notebooks on the same dataset.\n\n## Install\n\n``` sh\npip install -Uqq fastgs\n```\n\n``` sh\nconda install -c restlessronin fastgs\n```\n\n## Multi-spectral visualization\n\nOne key problem that is solved is visualization of multi-spectral data,\nwhich has more than the three R, G, B channels.\n\nWe introduce a new category of pytorch tensor,\n[`TensorImageMS`](https://restlessronin.github.io/fastgs/vision.core.html#tensorimagems),\nthat shows multiple images. In addition to the normal RGB image, it\nhandles extra channels by displaying them as additional images, either\nin sets of false-colour RGB images, or as ‘monochrome’ images (one per\nchannel).\n\nThere is also [experimental\nsupport](07a_vision.core.ipynb#animating-multiple-images) (not\nintegrated into the API yet) for mapping multi-spectral images to an\nanimation of multiple images. Feedback on it’s usefulness is welcome!\n\nThe first use-case is Sentinel 2 images, which are naturally “dark”.\nThere is a provision to provide “brightening” multipliers during\ndisplay, customizable per channel.\n\n## Image data class\n\nA high-level API,\n[`MSData`](https://restlessronin.github.io/fastgs/multispectral.html#msdata)\nis exposed that knows how to load multispectral images given some\nparameters.\n\n``` python\nfrom fastgs.multispectral import *\n```\n\nThe following code creates a class that can load 11 Sentinel 2 channels\ninto a\n[`TensorImageMS`](https://restlessronin.github.io/fastgs/vision.core.html#tensorimagems).\nThe first parameter is a descriptor that provides mapping from Sentinel\n2 channels to brightening factors and other parameters specific to the\ninputs. This will generally be tailored to your image dataset.\n\n``` python\nfrom fastgs.test.io import * # defines file naming and io for our test samples\n\nsentinel2 = createSentinel2Descriptor()\n\nsnt12_imgs = MSData.from_files(\n    sentinel2,\n    # B04 and B02 are transposed so that the first 3 channels are natural R,G,B channels\n    [\"B04\",\"B03\",\"B02\",\"B05\",\"B06\",\"B07\",\"B08\",\"B8A\",\"B11\",\"B12\",\"AOT\"],\n    [[\"B04\",\"B03\",\"B02\"],[\"B07\",\"B06\",\"B05\"],[\"B12\",\"B11\",\"B8A\"],[\"B08\"]],\n    get_channel_filenames,\n    read_multichan_files\n)\n```\n\nThe second parameter is a list of ids of channel to be loaded into the\nimage tensor, in the order in which they are loaded.\n\nThe third parameter is a list of 4 channel lists. Each channel list\ndescribes one image that will be displayed. The lists that have 3\nchannel ids will map those channels to the R,G,B inputs of a\n“false-colour” image. Lists with a single channel id will be mapped to\nmonochrome images.\n\nIn this example, we will display 4 images per MS image. The first maps\nthe “real” RGB channels (B04, B03, B02) of Sentinel 2 data to an RGB\nimage, which makes this a true-colour image. The second image maps\nchannels B07, B06, B05 to a false-colour image. Likewise the third image\nmaps B12, B11, B8A to a false-colour image. Finally the one remaining\nchannel B08 is mapped to a monochrome image. Thus all the channels in\nthe image are displayed.\n\nThe fourth parameter is a function that maps channel id’s to filenames\nthat provide the image data for a single channel. The final parameter is\nan IO function that loads a complete TensorImageMS given the list of\nfiles corresponding to individual channels.\n\n## Image display\n\nThe simplest use of the high-level wrapper class is to load an indvidual\nMS image.\n\n``` python\nimg12 = snt12_imgs.load_image(66)\nimg12.show()\n```\n\n    [\u003cAxesSubplot:title={'center':'B04,B03,B02'}\u003e,\n     \u003cAxesSubplot:title={'center':'B07,B06,B05'}\u003e,\n     \u003cAxesSubplot:title={'center':'B12,B11,B8A'}\u003e,\n     \u003cAxesSubplot:title={'center':'B08'}\u003e]\n\n![](index_files/figure-commonmark/cell-4-output-2.png)\n\nNote that the single MS image is displayed as 4 images, each\ncorresponding to one of the channel lists we provided. The first image\nis the true-colour image, the next 2 are false colour, and the final one\nis monochrome.\n\n## High level wrapper [`FastGS`](https://restlessronin.github.io/fastgs/multispectral.html#fastgs) for semantic segmentation\n\nWe also provide a high-level wrapper\n[`FastGS`](https://restlessronin.github.io/fastgs/multispectral.html#fastgs)\nwhich generates fastai dataloaders and learners for semantic\nsegmentation using unets. Providing support for other models and for\nclassification should be straightforward.\n\n### [`MaskData`](https://restlessronin.github.io/fastgs/multispectral.html#maskdata)\n\nContinuing our example, we provide mask information using a wrapper\nclass for segmentation mask loading (this is analogous to the\n[`MSData`](https://restlessronin.github.io/fastgs/multispectral.html#msdata)\nclass, but for ‘normal’ `TensorImage`s).\n\n``` python\nmsks = MaskData.from_files(\"LC\",get_channel_filenames,read_mask_file,[\"non-building\",\"building\"])\n```\n\n### [`MSAugment`](https://restlessronin.github.io/fastgs/multispectral.html#msaugment)\n\nWe also provide a wrapper class that can specify which (if any)\naugmentations to use during training and validation, using the\nalbumentations library (which works for multi-spectral data).\n\n``` python\nimport albumentations as A\n```\n\nHere we just use demo augmentations\n\n``` python\naugs = MSAugment.from_augs(train_aug=A.Rotate(p=1),valid_aug=A.HorizontalFlip(p=0.33))\n```\n\nNow we create the actual high level wrapper\n\n``` python\nfastgs = FastGS.for_training(snt12_imgs,msks,augs)\n```\n\nCreate a datablock and a data loader\n\n``` python\ndb = fastgs.create_data_block()\ndl = db.dataloaders(source=[66]*10,bs=8) # repeat the sample image 10 times\n```\n\nNow we can see the visualization support in action. Let’s look at some\ntraining and validation batches (with augmentation). Each row shows the\nimage in 4 columns and the mask in the 5th.\n\n``` python\nfrom fastai.vision.all import *\nfrom fastgs.vision.data import *\nfrom fastgs.vision.learner import *\nfrom fastgs.vision.augment import *\n```\n\n``` python\ndl.train.show_batch(max_n=3,mskovl=False) # don't overlay mask\n```\n\n![](index_files/figure-commonmark/cell-11-output-1.png)\n\n``` python\ndl.valid.show_batch(mskovl=False)\n```\n\n![](index_files/figure-commonmark/cell-12-output-1.png)\n\nWe create and train a unet learner and look at results. Image is in\nfirst 4 columns, mask in the 5th and prediction in the 6th.\n\n``` python\nlearner = fastgs.create_learner(dl,reweight=\"avg\") # weights of n \u003e 3 channels are set to average of first 3 channels\nlearner.fit_one_cycle(1)\nlearner.show_results(mskovl=False)\n```\n\n    /opt/homebrew/Caskroom/miniforge/base/envs/fastgs/lib/python3.10/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n      warnings.warn(\n    /opt/homebrew/Caskroom/miniforge/base/envs/fastgs/lib/python3.10/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=None`.\n      warnings.warn(msg)\n\n\u003ctable border=\"1\" class=\"dataframe\"\u003e\n  \u003cthead\u003e\n    \u003ctr style=\"text-align: left;\"\u003e\n      \u003cth\u003eepoch\u003c/th\u003e\n      \u003cth\u003etrain_loss\u003c/th\u003e\n      \u003cth\u003evalid_loss\u003c/th\u003e\n      \u003cth\u003edice\u003c/th\u003e\n      \u003cth\u003etime\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e0\u003c/td\u003e\n      \u003ctd\u003e0.872479\u003c/td\u003e\n      \u003ctd\u003e0.691804\u003c/td\u003e\n      \u003ctd\u003e0.044623\u003c/td\u003e\n      \u003ctd\u003e00:27\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n![](index_files/figure-commonmark/cell-13-output-6.png)\n\nFinally, we can look at the top losses\n\n``` python\ninterp = SegmentationInterpretation.from_learner(learner)\ninterp.plot_top_losses(k=1,mskovl=False)\n```\n\n![](index_files/figure-commonmark/cell-14-output-5.png)\n\n## Acknowledgements\n\nThis library is inspired by the following notebooks (and related works\nby the authors)\n\n- [@cordmaur](https://github.com/cordmaur) - Mauricio Cordeiro’s\n  [multi-spectral segmentation fastai\n  pipeline](https://www.kaggle.com/code/cordmaur/remotesensing-fastai2-multiband-augmentations/notebook)\n- [@wrignj08](https://github.com/wrignj08) - Nick Wright’s\n  [multi-spectral classification\n  notebook](https://dpird-dma.github.io/blog/Multispectral-image-classification-Transfer-Learning//)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frestlessronin%2Ffastgs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frestlessronin%2Ffastgs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frestlessronin%2Ffastgs/lists"}