deepforest package#
Subpackages#
Submodules#
deepforest.IoU module#
IoU Module, with help from SpaceNetChallenge/utilities
deepforest.callbacks module#
A deepforest callback Callbacks must have the following methods on_epoch_begin, on_epoch_end, on_fit_end, on_fit_begin methods and inject model and epoch kwargs.
- class deepforest.callbacks.images_callback(savedir, n=2, every_n_epochs=5, select_random=False, color=None, thickness=1)[source]#
Bases:
Callback
Run evaluation on a file of annotations during training.
- Parameters:
savedir – optional, directory to save predicted images
probability_threshold – minimum probablity for inclusion, see deepforest.evaluate
n – number of images to upload
select_random (False) – whether to select random images or the first n images
every_n_epochs – run epoch interval
color – color of the bounding box as a tuple of BGR color, e.g. orange annotations is (0, 165, 255)
thickness – thickness of the rectangle border line in px
- Returns:
either prints validation scores or logs them to the pytorch-lightning logger
- Return type:
None
deepforest.dataset module#
Dataset model.
During training, the model expects both the input tensors, as well as a targets (list of dictionary), containing:
boxes (FloatTensor[N, 4]): the ground-truth boxes in [x1, y1, x2, y2] format, with values between 0 and H and 0 and W
labels (Int64Tensor[N]): the class label for each ground-truth box
- class deepforest.dataset.BoundingBoxDataset(df, root_dir, transform=None, augment=False)[source]#
Bases:
Dataset
An in memory dataset for bounding box predictions.
- Parameters:
df – a pandas dataframe with image_path and xmin,xmax,ymin,ymax columns
transform – a function to apply to the image
root_dir – the directory where the image is stored
- Returns:
a tensor of shape (3, height, width)
- Return type:
rgb
- class deepforest.dataset.RasterDataset(raster_path, patch_size, patch_overlap)[source]#
Bases:
object
Dataset for predicting on raster windows.
- Parameters:
raster_path (str) – Path to raster file
patch_size (int) – Size of windows to predict on
patch_overlap (float) – Overlap between windows as fraction (0-1)
- Returns:
A dataset of raster windows
- class deepforest.dataset.TileDataset(tile: ndarray | None, preload_images: bool = False, patch_size: int = 400, patch_overlap: float = 0.05)[source]#
Bases:
Dataset
- Parameters:
tile – an in memory numpy array.
patch_size (int) – The size for the crops used to cut the input raster into smaller pieces. This is given in pixels, not any geographic unit.
patch_overlap (float) – The horizontal and vertical overlap among patches
preload_images (bool) – If true, the entire dataset is loaded into memory. This is useful for small datasets, but not recommended for large datasets since both the tile and the crops are stored in memory.
- Returns:
a pytorch dataset
- Return type:
ds
- class deepforest.dataset.TreeDataset(csv_file, root_dir, transforms=None, label_dict={'Tree': 0}, train=True, preload_images=False)[source]#
Bases:
Dataset
- Parameters:
csv_file (string) – Path to a single csv file with annotations.
root_dir (string) – Directory with all the images.
transform (callable, optional) – Optional transform to be applied on a sample.
label_dict – a dictionary where keys are labels from the csv column and values are numeric labels “Tree” -> 0
- Returns:
If train, path, image, targets else image
deepforest.evaluate module#
Evaluation module.
- deepforest.evaluate.compute_class_recall(results)[source]#
Given a set of evaluations, what proportion of predicted boxes match.
True boxes which are not matched to predictions do not count against accuracy.
- deepforest.evaluate.evaluate_boxes(predictions, ground_df, root_dir, iou_threshold=0.4, savedir=None)[source]#
Image annotated crown evaluation routine submission can be submitted as a .shp, existing pandas dataframe or .csv path.
- Parameters:
predictions – a pandas dataframe, if supplied a root dir is needed to give the relative path of files in df.name. The labels in ground truth and predictions must match. If one is numeric, the other must be numeric.
ground_df – a pandas dataframe, if supplied a root dir is needed to give the relative path of files in df.name
root_dir – location of files in the dataframe ‘name’ column.
savedir – optional directory to save image with overlaid predictions and annotations
- Returns:
a dataframe of match bounding boxes box_recall: proportion of true positives of box position, regardless of class box_precision: proportion of predictions that are true positive, regardless of class class_recall: a pandas dataframe of class level recall and precision with class sizes
- Return type:
results
- deepforest.evaluate.evaluate_image_boxes(predictions, ground_df, root_dir, savedir=None)[source]#
Compute intersection-over-union matching among prediction and ground truth boxes for one image.
- Parameters:
df – a geopandas dataframe with geometry columns
predictions – a geopandas dataframe with geometry columns
ground_df – a geopandas dataframe with geometry columns
summarize – Whether to group statistics by plot and overall score
image_coordinates – Whether the current boxes are in coordinate system of the image, e.g. origin (0,0) upper left.
root_dir – Where to search for image names in df
savedir – optional directory to save image with overlaid predictions and annotations
- Returns:
pandas dataframe with crown ids of prediciton and ground truth and the IoU score.
- Return type:
result
- deepforest.evaluate.point_recall(predictions, ground_df, root_dir=None, savedir=None)[source]#
Evaluate the proportion on ground truth points overlap with predictions submission can be submitted as a .shp, existing pandas dataframe or .csv path For bounding box recall, see evaluate().
- Parameters:
predictions – a pandas dataframe, if supplied a root dir is needed to give the relative path of files in df.name. The labels in ground truth and predictions must match. If one is numeric, the other must be numeric.
ground_df – a pandas dataframe, if supplied a root dir is needed to give the relative path of files in df.name
root_dir – location of files in the dataframe ‘name’ column.
savedir – optional directory to save image with overlaid predictions and annotations
- Returns:
a dataframe of matched bounding boxes and ground truth labels box_recall: proportion of true positives between predicted boxes and ground truth points, regardless of class class_recall: a pandas dataframe of class level recall and precision with class sizes
- Return type:
results
deepforest.main module#
- class deepforest.main.deepforest(*args, **kwargs)[source]#
Bases:
LightningModule
,PyTorchModelHubMixin
Class for training and predicting tree crowns in RGB images.
- Parameters:
num_classes (int) – number of classes in the model
config_file (str) – path to deepforest config file
model (model.Model()) – a deepforest model object, see model.Model()
config_args (dict) – a dictionary of key->value to update config file at run time. e.g. {“batch_size”:10}. This is useful for iterating over arguments during model testing.
existing_train_dataloader – a Pytorch dataloader that yields a tuple path, images, targets
existing_val_dataloader – a Pytorch dataloader that yields a tuple path, images, targets
- Returns:
a deepforest pytorch lightning module
- Return type:
self
Create a new instance of the class and handle config.
3 cases: - If self._hub_mixin_config is already set, do nothing. - If config is passed as a dataclass, set it as self._hub_mixin_config. - Otherwise, build self._hub_mixin_config from default values and passed values.
- calculate_empty_frame_accuracy(ground_df, predictions_df)[source]#
Calculate accuracy for empty frames (frames with no objects).
- Parameters:
ground_df (pd.DataFrame) – Ground truth dataframe containing image paths and bounding boxes. Must have columns ‘image_path’, ‘xmin’, ‘ymin’, ‘xmax’, ‘ymax’.
predictions_df (pd.DataFrame) – Model predictions dataframe containing image paths and predicted boxes. Must have column ‘image_path’.
- Returns:
- Accuracy score for empty frame detection. A score of 1.0 means the model correctly
identified all empty frames (no false positives), while 0.0 means it predicted objects in all empty frames (all false positives). Returns None if there are no empty frames.
- Return type:
float or None
- configure_optimizers()[source]#
Choose what optimizers and learning-rate schedulers to use in your optimization. Normally you’d need one. But in the case of GANs or similar you might have multiple. Optimization with multiple optimizers only works in the manual optimization mode.
- Returns:
Any of these 6 options.
Single optimizer.
List or Tuple of optimizers.
Two lists - The first list has multiple optimizers, and the second has multiple LR schedulers (or multiple
lr_scheduler_config
).Dictionary, with an
"optimizer"
key, and (optionally) a"lr_scheduler"
key whose value is a single LR scheduler orlr_scheduler_config
.None - Fit will run without any optimizer.
The
lr_scheduler_config
is a dictionary which contains the scheduler and its associated configuration. The default configuration is shown below.lr_scheduler_config = { # REQUIRED: The scheduler instance "scheduler": lr_scheduler, # The unit of the scheduler's step size, could also be 'step'. # 'epoch' updates the scheduler on epoch end whereas 'step' # updates it after a optimizer update. "interval": "epoch", # How many epochs/steps should pass between calls to # `scheduler.step()`. 1 corresponds to updating the learning # rate after every epoch/step. "frequency": 1, # Metric to to monitor for schedulers like `ReduceLROnPlateau` "monitor": "val_loss", # If set to `True`, will enforce that the value specified 'monitor' # is available when the scheduler is updated, thus stopping # training if not found. If set to `False`, it will only produce a warning "strict": True, # If using the `LearningRateMonitor` callback to monitor the # learning rate progress, this keyword can be used to specify # a custom logged name "name": None, }
When there are schedulers in which the
.step()
method is conditioned on a value, such as thetorch.optim.lr_scheduler.ReduceLROnPlateau
scheduler, Lightning requires that thelr_scheduler_config
contains the keyword"monitor"
set to the metric name that the scheduler should be conditioned on.# The ReduceLROnPlateau scheduler requires a monitor def configure_optimizers(self): optimizer = Adam(...) return { "optimizer": optimizer, "lr_scheduler": { "scheduler": ReduceLROnPlateau(optimizer, ...), "monitor": "metric_to_track", "frequency": "indicates how often the metric is updated", # If "monitor" references validation metrics, then "frequency" should be set to a # multiple of "trainer.check_val_every_n_epoch". }, } # In the case of two optimizers, only one using the ReduceLROnPlateau scheduler def configure_optimizers(self): optimizer1 = Adam(...) optimizer2 = SGD(...) scheduler1 = ReduceLROnPlateau(optimizer1, ...) scheduler2 = LambdaLR(optimizer2, ...) return ( { "optimizer": optimizer1, "lr_scheduler": { "scheduler": scheduler1, "monitor": "metric_to_track", }, }, {"optimizer": optimizer2, "lr_scheduler": scheduler2}, )
Metrics can be made available to monitor by simply logging it using
self.log('metric_to_track', metric_val)
in yourLightningModule
.Note
Some things to know:
Lightning calls
.backward()
and.step()
automatically in case of automatic optimization.If a learning rate scheduler is specified in
configure_optimizers()
with key"interval"
(default “epoch”) in the scheduler configuration, Lightning will call the scheduler’s.step()
method automatically in case of automatic optimization.If you use 16-bit precision (
precision=16
), Lightning will automatically handle the optimizer.If you use
torch.optim.LBFGS
, Lightning handles the closure function automatically for you.If you use multiple optimizers, you will have to switch to ‘manual optimization’ mode and step them yourself.
If you need to control how often the optimizer steps, override the
optimizer_step()
hook.
- create_model()[source]#
Define a deepforest architecture. This can be done in two ways. Passed as the model argument to deepforest __init__(), or as a named architecture in config[“architecture”], which corresponds to a file in models/, as is a subclass of model.Model(). The config args in the .yaml are specified.
- Returns:
None
- create_trainer(logger=None, callbacks=[], **kwargs)[source]#
Create a pytorch lightning training by reading config files.
- Parameters:
logger – A pytorch lightning logger
callbacks (list) – a list of pytorch-lightning callback classes
**kwargs – Additional arguments to pass to the trainer
- Returns:
None
- evaluate(csv_file, root_dir, iou_threshold=None, savedir=None)[source]#
Compute intersection-over-union and precision/recall for a given iou_threshold.
- Parameters:
csv_file – location of a csv file with columns “name”,”xmin”,”ymin”,”xmax”,”ymax”,”label”
root_dir – location of files in the dataframe ‘name’ column
iou_threshold – float [0,1] intersection-over-union threshold for true positive
savedir – location to save images with bounding boxes
- Returns:
Results dictionary containing precision, recall and other metrics
- Return type:
dict
- load_dataset(csv_file, root_dir=None, augment=False, shuffle=True, batch_size=1, train=False)[source]#
Create a tree dataset for inference Csv file format is .csv file with the columns “image_path”, “xmin”,”ymin”,”xmax”,”ymax” for the image name and bounding box position. Image_path is the relative filename, not absolute path, which is in the root_dir directory. One bounding box per line.
- Parameters:
csv_file – path to csv file
root_dir – directory of images. If none, uses “image_dir” in config
augment – Whether to create a training dataset, this activates data augmentations
- Returns:
a pytorch dataset
- Return type:
ds
- load_model(model_name='weecology/deepforest-tree', revision='main')[source]#
Loads a model that has already been pretrained for a specific task, like tree crown detection.
Models (technically model weights) are distributed via Hugging Face and designated the Hugging Face repository ID (model_name), which is in the form: ‘organization/repository’. For a list of models distributed by the DeepForest team (and the associated model names) see the documentation: https://deepforest.readthedocs.io/en/latest/installation_and_setup/prebuilt.html
- Parameters:
model_name (str) – A repository ID for huggingface in the form of organization/repository
revision (str) – The model version (‘main’, ‘v1.0.0’, etc.).
- Returns:
None
- on_fit_start()[source]#
Called at the very beginning of fit.
If on DDP it is called on every process
- on_validation_epoch_start()[source]#
Called in the validation loop at the very beginning of the epoch.
- predict_batch(images, preprocess_fn=None)[source]#
Predict a batch of images with the deepforest model.
- Parameters:
images (torch.Tensor or np.ndarray) – A batch of images with shape (B, C, H, W) or (B, H, W, C).
preprocess_fn (callable, optional) – A function to preprocess images before prediction. If None, assumes images are preprocessed.
- Returns:
A list of dataframes with predictions for each image.
- Return type:
List[pd.DataFrame]
- predict_dataloader(ds)[source]#
Create a PyTorch dataloader for prediction.
- Parameters:
ds (torchvision.datasets.Dataset) – A torchvision dataset to be wrapped into a dataloader using config args.
- Returns:
A dataloader object that can be used for prediction.
- Return type:
torch.utils.data.DataLoader
- predict_file(csv_file, root_dir, savedir=None, color=None, thickness=1)[source]#
Create a dataset and predict entire annotation file Csv file format is .csv file with the columns “image_path”, “xmin”,”ymin”,”xmax”,”ymax” for the image name and bounding box position. Image_path is the relative filename, not absolute path, which is in the root_dir directory. One bounding box per line.
Deprecation warning: The return_plot argument is deprecated and will be removed in 2.0. Use visualize.plot_results on the result instead.
- Parameters:
csv_file – path to csv file
root_dir – directory of images. If none, uses “image_dir” in config
savedir ((deprecated)) – directory to save images with bounding boxes
color ((deprecated)) – color of the bounding box as a tuple of BGR color, e.g. orange annotations is (0, 165, 255)
thickness ((deprecated)) – thickness of the rectangle border line in px
- Returns:
pandas dataframe with bounding boxes, label and scores for each image in the csv file
- Return type:
df
- predict_image(image: ndarray | None = None, path: str | None = None, return_plot: bool = False, color: tuple | None = (0, 165, 255), thickness: int = 1)[source]#
Predict a single image with a deepforest model.
Deprecation warning: The ‘return_plot’, and related ‘color’ and ‘thickness’ arguments are deprecated and will be removed in 2.0. Use visualize.plot_results on the result instead.
- Parameters:
image – a float32 numpy array of a RGB with channels last format
path – optional path to read image from disk instead of passing image arg
return_plot – return a plot of the image with predictions overlaid (deprecated)
color – color of the bounding box as a tuple of BGR color (deprecated)
thickness – thickness of the rectangle border line in px (deprecated)
- Returns:
A pandas dataframe of predictions (Default) img: The input with predictions overlaid (Optional)
- Return type:
result
- predict_step(batch, batch_idx)[source]#
Step function called during
predict()
. By default, it callsforward()
. Override to add any processing logic.The
predict_step()
is used to scale inference on multi-devices.To prevent an OOM error, it is possible to use
BasePredictionWriter
callback to write the predictions to disk or database after each batch or on epoch end.The
BasePredictionWriter
should be used while using a spawn based accelerator. This happens forTrainer(strategy="ddp_spawn")
or training on 8 TPU cores withTrainer(accelerator="tpu", devices=8)
as predictions won’t be returned.- Parameters:
batch – The output of your data iterable, normally a
DataLoader
.batch_idx – The index of this batch.
dataloader_idx – The index of the dataloader that produced this batch. (only if multiple dataloaders used)
- Returns:
Predicted output (optional).
Example
class MyModel(LightningModule): def predict_step(self, batch, batch_idx, dataloader_idx=0): return self(batch) dm = ... model = MyModel() trainer = Trainer(accelerator="gpu", devices=2) predictions = trainer.predict(model, dm)
- predict_tile(raster_path=None, image=None, patch_size=400, patch_overlap=0.05, iou_threshold=0.15, in_memory=True, return_plot=False, mosaic=True, sigma=0.5, thresh=0.001, color=None, thickness=1, crop_model=None, crop_transform=None, crop_augment=False)[source]#
For images too large to input into the model, predict_tile cuts the image into overlapping windows, predicts trees on each window and reassambles into a single array.
- Parameters:
raster_path – Path to image on disk
image (array) – Numpy image array in BGR channel order following openCV convention
patch_size – patch size for each window
patch_overlap – patch overlap among windows
iou_threshold – Minimum iou overlap among predictions between windows to be suppressed
in_memory – If true, the entire dataset is loaded into memory
mosaic – Return a single prediction dataframe (True) or a tuple of image crops and predictions (False)
sigma – variance of Gaussian function used in Gaussian Soft NMS
thresh – the score thresh used to filter bboxes after soft-nms performed
crop_model – a deepforest.model.CropModel object to predict on crops
crop_transform – a torchvision.transforms object to apply to crops
crop_augment – a boolean to apply augmentations to crops
return_plot – return a plot of the image with predictions overlaid (deprecated)
color – color of the bounding box as a tuple of BGR color (deprecated)
thickness – thickness of the rectangle border line in px (deprecated)
- Returns:
Predictions dataframe or (predictions, crops) tuple
- Return type:
pd.DataFrame or tuple
- save_model(path)[source]#
Save the trainer checkpoint in user defined path, in order to access in future.
- Parameters:
Path – the path located the model checkpoint
- set_labels(label_dict)[source]#
Set new label mapping, updating both the label dictionary (str -> int) and its inverse (int -> str).
- Parameters:
label_dict (dict) – Dictionary mapping class names to numeric IDs.
- use_bird_release(check_release=True)[source]#
Use the latest DeepForest bird model release from Hugging Face, downloading if necessary. model. Optionally download if release doesn’t exist.
- Parameters:
check_release (logical) – Deprecated, not in use.
- Returns:
A trained pytorch model
- Return type:
model (object)
- use_release(check_release=True)[source]#
Use the latest DeepForest model release from Hugging Face, downloading if necessary. Optionally download if release doesn’t exist.
- Parameters:
check_release (logical) – Deprecated, not in use.
- Returns:
A trained PyTorch model
- Return type:
model (object)
deepforest.model module#
- class deepforest.model.CropModel(num_classes, batch_size=4, num_workers=0, lr=0.0001, model=None, label_dict=None)[source]#
Bases:
LightningModule
A PyTorch Lightning module for classifying image crops from object detection models.
This class provides a flexible architecture for training classification models on cropped regions identified by object detection models. It supports using either a default ResNet-50 model or a custom provided model.
- Parameters:
num_classes (int) – Number of classes for classification
batch_size (int, optional) – Batch size for training. Defaults to 4.
num_workers (int, optional) – Number of worker processes for data loading. Defaults to 0.
lr (float, optional) – Learning rate for optimization. Defaults to 0.0001.
model (nn.Module, optional) – Custom PyTorch model to use. If None, uses ResNet-50. Defaults to None.
label_dict (dict, optional) – Mapping of class labels to numeric indices. Defaults to None.
- model#
The classification model (ResNet-50 or custom)
- Type:
nn.Module
- accuracy#
Per-class accuracy metric
- Type:
torchmetrics.Accuracy
- total_accuracy#
Overall accuracy metric
- Type:
torchmetrics.Accuracy
- precision_metric#
Precision metric
- Type:
torchmetrics.Precision
- metrics#
Collection of all metrics
- Type:
torchmetrics.MetricCollection
- batch_size#
Batch size for training
- Type:
int
- num_workers#
Number of data loading workers
- Type:
int
- lr#
Learning rate
- Type:
float
- label_dict#
Label to index mapping {“Bird”: 0, “Mammal”: 1}
- Type:
dict
- numeric_to_label_dict#
Index to label mapping {0: “Bird”, 1: “Mammal”}
- Type:
dict
- configure_optimizers()[source]#
Choose what optimizers and learning-rate schedulers to use in your optimization. Normally you’d need one. But in the case of GANs or similar you might have multiple. Optimization with multiple optimizers only works in the manual optimization mode.
- Returns:
Any of these 6 options.
Single optimizer.
List or Tuple of optimizers.
Two lists - The first list has multiple optimizers, and the second has multiple LR schedulers (or multiple
lr_scheduler_config
).Dictionary, with an
"optimizer"
key, and (optionally) a"lr_scheduler"
key whose value is a single LR scheduler orlr_scheduler_config
.None - Fit will run without any optimizer.
The
lr_scheduler_config
is a dictionary which contains the scheduler and its associated configuration. The default configuration is shown below.lr_scheduler_config = { # REQUIRED: The scheduler instance "scheduler": lr_scheduler, # The unit of the scheduler's step size, could also be 'step'. # 'epoch' updates the scheduler on epoch end whereas 'step' # updates it after a optimizer update. "interval": "epoch", # How many epochs/steps should pass between calls to # `scheduler.step()`. 1 corresponds to updating the learning # rate after every epoch/step. "frequency": 1, # Metric to to monitor for schedulers like `ReduceLROnPlateau` "monitor": "val_loss", # If set to `True`, will enforce that the value specified 'monitor' # is available when the scheduler is updated, thus stopping # training if not found. If set to `False`, it will only produce a warning "strict": True, # If using the `LearningRateMonitor` callback to monitor the # learning rate progress, this keyword can be used to specify # a custom logged name "name": None, }
When there are schedulers in which the
.step()
method is conditioned on a value, such as thetorch.optim.lr_scheduler.ReduceLROnPlateau
scheduler, Lightning requires that thelr_scheduler_config
contains the keyword"monitor"
set to the metric name that the scheduler should be conditioned on.# The ReduceLROnPlateau scheduler requires a monitor def configure_optimizers(self): optimizer = Adam(...) return { "optimizer": optimizer, "lr_scheduler": { "scheduler": ReduceLROnPlateau(optimizer, ...), "monitor": "metric_to_track", "frequency": "indicates how often the metric is updated", # If "monitor" references validation metrics, then "frequency" should be set to a # multiple of "trainer.check_val_every_n_epoch". }, } # In the case of two optimizers, only one using the ReduceLROnPlateau scheduler def configure_optimizers(self): optimizer1 = Adam(...) optimizer2 = SGD(...) scheduler1 = ReduceLROnPlateau(optimizer1, ...) scheduler2 = LambdaLR(optimizer2, ...) return ( { "optimizer": optimizer1, "lr_scheduler": { "scheduler": scheduler1, "monitor": "metric_to_track", }, }, {"optimizer": optimizer2, "lr_scheduler": scheduler2}, )
Metrics can be made available to monitor by simply logging it using
self.log('metric_to_track', metric_val)
in yourLightningModule
.Note
Some things to know:
Lightning calls
.backward()
and.step()
automatically in case of automatic optimization.If a learning rate scheduler is specified in
configure_optimizers()
with key"interval"
(default “epoch”) in the scheduler configuration, Lightning will call the scheduler’s.step()
method automatically in case of automatic optimization.If you use 16-bit precision (
precision=16
), Lightning will automatically handle the optimizer.If you use
torch.optim.LBFGS
, Lightning handles the closure function automatically for you.If you use multiple optimizers, you will have to switch to ‘manual optimization’ mode and step them yourself.
If you need to control how often the optimizer steps, override the
optimizer_step()
hook.
- forward(x)[source]#
Same as
torch.nn.Module.forward()
.- Parameters:
*args – Whatever you decide to pass into the forward method.
**kwargs – Keyword arguments are also possible.
- Returns:
Your model’s output
- get_transform(augment)[source]#
Returns the data transformation pipeline for the model.
- Parameters:
augment (bool) – Flag indicating whether to apply data augmentation.
- Returns:
The composed data transformation pipeline.
- Return type:
torchvision.transforms.Compose
- predict_step(batch, batch_idx)[source]#
Step function called during
predict()
. By default, it callsforward()
. Override to add any processing logic.The
predict_step()
is used to scale inference on multi-devices.To prevent an OOM error, it is possible to use
BasePredictionWriter
callback to write the predictions to disk or database after each batch or on epoch end.The
BasePredictionWriter
should be used while using a spawn based accelerator. This happens forTrainer(strategy="ddp_spawn")
or training on 8 TPU cores withTrainer(accelerator="tpu", devices=8)
as predictions won’t be returned.- Parameters:
batch – The output of your data iterable, normally a
DataLoader
.batch_idx – The index of this batch.
dataloader_idx – The index of the dataloader that produced this batch. (only if multiple dataloaders used)
- Returns:
Predicted output (optional).
Example
class MyModel(LightningModule): def predict_step(self, batch, batch_idx, dataloader_idx=0): return self(batch) dm = ... model = MyModel() trainer = Trainer(accelerator="gpu", devices=2) predictions = trainer.predict(model, dm)
- training_step(batch, batch_idx)[source]#
Here you compute and return the training loss and some additional metrics for e.g. the progress bar or logger.
- Parameters:
batch – The output of your data iterable, normally a
DataLoader
.batch_idx – The index of this batch.
dataloader_idx – The index of the dataloader that produced this batch. (only if multiple dataloaders used)
- Returns:
Tensor
- The loss tensordict
- A dictionary which can include any keys, but must include the key'loss'
in the case of automatic optimization.None
- In automatic optimization, this will skip to the next batch (but is not supported for multi-GPU, TPU, or DeepSpeed). For manual optimization, this has no special meaning, as returning the loss is not required.
In this step you’d normally do the forward pass and calculate the loss for a batch. You can also do fancier things like multiple forward passes or something model specific.
Example:
def training_step(self, batch, batch_idx): x, y, z = batch out = self.encoder(x) loss = self.loss(out, x) return loss
To use multiple optimizers, you can switch to ‘manual optimization’ and control their stepping:
def __init__(self): super().__init__() self.automatic_optimization = False # Multiple optimizers (e.g.: GANs) def training_step(self, batch, batch_idx): opt1, opt2 = self.optimizers() # do training_step with encoder ... opt1.step() # do training_step with decoder ... opt2.step()
Note
When
accumulate_grad_batches
> 1, the loss returned here will be automatically normalized byaccumulate_grad_batches
internally.
- validation_step(batch, batch_idx)[source]#
Operates on a single batch of data from the validation set. In this step you’d might generate examples or calculate anything of interest like accuracy.
- Parameters:
batch – The output of your data iterable, normally a
DataLoader
.batch_idx – The index of this batch.
dataloader_idx – The index of the dataloader that produced this batch. (only if multiple dataloaders used)
- Returns:
Tensor
- The loss tensordict
- A dictionary. Can include any keys, but must include the key'loss'
.None
- Skip to the next batch.
# if you have one val dataloader: def validation_step(self, batch, batch_idx): ... # if you have multiple val dataloaders: def validation_step(self, batch, batch_idx, dataloader_idx=0): ...
Examples:
# CASE 1: A single validation dataset def validation_step(self, batch, batch_idx): x, y = batch # implement your own out = self(x) loss = self.loss(out, y) # log 6 example images # or generated text... or whatever sample_imgs = x[:6] grid = torchvision.utils.make_grid(sample_imgs) self.logger.experiment.add_image('example_images', grid, 0) # calculate acc labels_hat = torch.argmax(out, dim=1) val_acc = torch.sum(y == labels_hat).item() / (len(y) * 1.0) # log the outputs! self.log_dict({'val_loss': loss, 'val_acc': val_acc})
If you pass in multiple val dataloaders,
validation_step()
will have an additional argument. We recommend setting the default value of 0 so that you can quickly switch between single and multiple dataloaders.# CASE 2: multiple validation dataloaders def validation_step(self, batch, batch_idx, dataloader_idx=0): # dataloader_idx tells you which dataset this is. ...
Note
If you don’t need to validate you don’t need to implement this method.
Note
When the
validation_step()
is called, the model has been put in eval mode and PyTorch gradients have been disabled. At the end of validation, the model goes back to training mode and gradients are enabled.
- write_crops(root_dir, images, boxes, labels, savedir)[source]#
Write crops to disk.
- Parameters:
root_dir (str) – The root directory where the images are located.
images (list) – A list of image filenames.
boxes (list) – A list of bounding box coordinates in the format [xmin, ymin, xmax, ymax].
labels (list) – A list of labels corresponding to each bounding box.
savedir (str) – The directory where the cropped images will be saved.
- Returns:
None
- class deepforest.model.Model(config)[source]#
Bases:
object
A architecture agnostic class that controls the basic train, eval and predict functions. A model should optionally allow a backbone for pretraining. To add new architectures, simply create a new module in models/ and write a create_model. Then add the result to the if else statement below.
- Parameters:
num_classes (int) – number of classes in the model
nms_thresh (float) – non-max suppression threshold for intersection-over-union [0,1]
score_thresh (float) – minimum prediction score to keep during prediction [0,1]
- Returns:
a pytorch nn module
- Return type:
model
deepforest.predict module#
deepforest.preprocess module#
The preprocessing module is used to reshape data into format suitable for training or prediction.
For example cutting large tiles into smaller images.
- deepforest.preprocess.compute_windows(numpy_image, patch_size, patch_overlap)[source]#
Create a sliding window object from a raster tile.
- Parameters:
numpy_image (array) – Raster object as numpy array to cut into crops
- Returns:
a sliding windows object
- Return type:
windows (list)
- deepforest.preprocess.image_name_from_path(image_path)[source]#
Convert path to image name for use in indexing.
- deepforest.preprocess.preprocess_image(image)[source]#
Preprocess a single RGB numpy array as a prediction from channels last, to channels first.
- deepforest.preprocess.save_crop(base_dir, image_name, index, crop)[source]#
Save window crop as an image file to be read by PIL.
- Parameters:
base_dir (str) – The base directory to save the image file.
image_name (str) – The name of the original image.
index (int) – The index of the window crop.
crop (numpy.ndarray) – The window crop as a NumPy array.
- Returns:
The filename of the saved image.
- Return type:
str
- deepforest.preprocess.select_annotations(annotations, window)[source]#
Select annotations that overlap with selected image crop.
- Parameters:
annotations – a geopandas dataframe of annotations with a geometry column
windows – A sliding window object (see compute_windows)
- Returns:
a pandas dataframe of annotations
- Return type:
selected_annotations
- deepforest.preprocess.split_raster(annotations_file=None, path_to_raster=None, numpy_image=None, root_dir=None, base_dir=None, patch_size=400, patch_overlap=0.05, allow_empty=False, image_name=None, save_dir='.')[source]#
Divide a large tile into smaller arrays. Each crop will be saved to file.
- Parameters:
numpy_image – a numpy object to be used as a raster, usually opened from rasterio.open.read(), in order (height, width, channels)
root_dir – (str): Root directory of annotations file, if not supplied, will be inferred from annotations_file
path_to_raster – (str): Path to a tile that can be read by rasterio on disk
annotations_file (str or pd.DataFrame) – A pandas dataframe or path to annotations csv file to transform to cropped images. In the format -> image_path, xmin, ymin, xmax, ymax, label. If None, allow_empty is ignored and the function will only return the cropped images.
save_dir (str) – Directory to save images
base_dir (str) – Directory to save images
patch_size (int) – Maximum dimensions of square window
patch_overlap (float) – Percent of overlap among windows 0->1
allow_empty – If True, include images with no annotations to be included in the dataset. If annotations_file is None, this is ignored.
image_name (str) – If numpy_image arg is used, what name to give the raster?
Note
When allow_empty is True, the function will return 0’s for coordinates, following torchvision style, the label will be ignored, so for continuity, the first label in the annotations_file will be used.
- Returns:
If annotations_file is provided, a pandas dataframe with annotations file for training. A copy of this file is written to save_dir as a side effect. If not, a list of filenames of the cropped images.
deepforest.utilities module#
- class deepforest.utilities.DownloadProgressBar(*_, **__)[source]#
Bases:
tqdm
Download progress bar class.
- deepforest.utilities.annotations_to_shapefile(df, transform, crs)[source]#
Convert output from predict_image and predict_tile to a geopandas data.frame.
- Parameters:
df – prediction data.frame with columns [‘xmin’,’ymin’,’xmax’,’ymax’,’label’,’score’]
transform – A rasterio affine transform object
crs – A rasterio crs object
- Returns:
a geopandas dataframe where every entry is the bounding box for a detected tree.
- Return type:
results
- deepforest.utilities.boxes_to_shapefile(df, root_dir, projected=True, flip_y_axis=False)[source]#
Convert from image coordinates to geographic coordinates Note that this assumes df is just a single plot being passed to this function :param df: a pandas type dataframe with columns: name, xmin, ymin, xmax, ymax. Name is the relative path to the root_dir arg. :param root_dir: directory of images to lookup image_path column :param projected: If True, convert from image to geographic coordinates, if False, keep in image coordinate system :param flip_y_axis: If True, reflect predictions over y axis to align with raster data in QGIS, which uses a negative y origin compared to numpy. See https://gis.stackexchange.com/questions/306684/why-does-qgis-use-negative-y-spacing-in-the-default-raster-geotransform
- Returns:
a geospatial dataframe with the boxes optionally transformed to the target crs
- Return type:
df
- deepforest.utilities.check_image(image)[source]#
Check an image is three channel, channel last format :param image: numpy array
Returns: None, throws error on assert
- deepforest.utilities.convert_point_to_bbox(gdf, buffer_size)[source]#
Convert an input point type annotation to a bounding box by buffering the point with a fixed size.
- Parameters:
gdf (GeoDataFrame) – The input point type annotation.
buffer_size (float) – The size of the buffer to be applied to the point.
- Returns:
The output bounding box type annotation.
- Return type:
gdf (GeoDataFrame)
- deepforest.utilities.crop_annotations_to_bounds(gdf, bounds)[source]#
Crop a geodataframe of annotations to a bounding box :param gdf: a geodataframe of annotations :param bounds: a tuple of (left, bottom, right, top) bounds
- Returns:
a geodataframe of annotations cropped to the bounds
- Return type:
gdf
- deepforest.utilities.crop_raster(bounds, rgb_path=None, savedir=None, filename=None, driver='GTiff')[source]#
Crop a raster to a bounding box, save as projected or unprojected crop :param bounds: a tuple of (left, bottom, right, top) bounds :param rgb_path: path to the rgb image :param savedir: directory to save the crop :param filename: filename to save the crop “{}.tif”.format(filename)” :param driver: rasterio driver to use, default to GTiff, can be ‘GTiff’ for projected data or ‘PNG’ unprojected data
- Returns:
path to the saved crop, if savedir specified img: a numpy array of the crop, if savedir not specified
- Return type:
filename
- deepforest.utilities.determine_geometry_type(df)[source]#
Determine the geometry type of a prediction or annotation :param df: a pandas dataframe
- Returns:
a string of the geometry type
- Return type:
geometry_type
- deepforest.utilities.geo_to_image_coordinates(gdf, image_bounds, image_resolution)[source]#
Convert from projected coordinates to image coordinates :param gdf: a pandas type dataframe with columns: name, xmin, ymin, xmax, ymax. Name is the relative path to the root_dir arg. :param image_bounds: bounds of the image :param image_resolution: resolution of the image
- Returns:
a geopandas dataframe with the transformed to image origin. CRS is removed
- Return type:
gdf
- deepforest.utilities.image_to_geo_coordinates(gdf, root_dir, flip_y_axis=False)[source]#
Convert from image coordinates to geographic coordinates.
- Parameters:
gdf – A geodataframe.
root_dir – Directory of images to lookup image_path column.
flip_y_axis – If True, reflect predictions over y axis to align with raster data in QGIS, which uses a negative y origin compared to numpy.
- Returns:
A geospatial dataframe with the boxes optionally transformed to the target crs.
- Return type:
transformed_gdf
- deepforest.utilities.project_boxes(df, root_dir, transform=True)[source]#
Convert from image coordinates to geographic coordinates Note that this assumes df is just a single plot being passed to this function df: a pandas type dataframe with columns: name, xmin, ymin, xmax, ymax. Name is the relative path to the root_dir arg. root_dir: directory of images to lookup image_path column transform: If true, convert from image to geographic coordinates
- deepforest.utilities.read_coco(json_file)[source]#
Read a COCO format JSON file and return a pandas dataframe.
- Parameters:
json_file – Path to the COCO segmentation JSON file
- Returns:
A pandas dataframe with image_path and geometry columns
- Return type:
df
- deepforest.utilities.read_file(input, root_dir=None)[source]#
Read a file and return a geopandas dataframe.
This is the main entry point for reading annotations into deepforest. :param input: a path to a file or a pandas dataframe :param root_dir: location of the image files, if not in the same directory as the annotations file :type root_dir: str
- Returns:
a geopandas dataframe with the properly formatted geometry column df.root_dir: the root directory of the image files
- Return type:
df
- deepforest.utilities.read_pascal_voc(xml_path)[source]#
Load annotations from xml format (e.g. RectLabel editor) and convert them into retinanet annotations format.
- Parameters:
xml_path (str) – Path to the annotations xml, formatted by RectLabel
- Returns:
- in the
format -> path-to-image.png,x1,y1,x2,y2,class_name
- Return type:
Annotations (pandas dataframe)
- deepforest.utilities.round_with_floats(x)[source]#
Check if string x is float or int, return int, rounded if needed.
- deepforest.utilities.shapefile_to_annotations(shapefile, rgb=None, root_dir=None, buffer_size=None, convert_point=False, geometry_type=None, save_dir=None)[source]#
Convert a shapefile of annotations into annotations csv file for DeepForest training and evaluation.
- Parameters:
shapefile – Path to a shapefile on disk. If a label column is present, it will be used, else all labels are assumed to be “Tree”
rgb – Path to the RGB image on disk
root_dir – Optional directory to prepend to the image_path column
- Returns:
a pandas dataframe
- Return type:
results
deepforest.visualize module#
- deepforest.visualize.convert_to_sv_format(df, width=None, height=None)[source]#
Convert DeepForest prediction results to a supervision Detections object.
- Parameters:
df (pd.DataFrame) – The results from predict_image or predict_tile. Expected columns includes: [‘geometry’, ‘label’, ‘score’, ‘image_path’] for bounding boxes
width (int) – The width of the image in pixels. Only required if the geometry type is ‘polygon’.
height (int) – The height of the image in pixels. Only required if the geometry type is ‘polygon’.
- Returns:
Depending on the geometry type, the function returns either a Detections or a KeyPoints object from the supervision library.
- deepforest.visualize.format_boxes(prediction, scores=True)[source]#
Format a retinanet prediction into a pandas dataframe for a single image.
- Parameters:
prediction – a dictionary with keys ‘boxes’ and ‘labels’ coming from a retinanet
scores – Whether boxes come with scores, during prediction, or without scores, as in during training.
- Returns:
a pandas dataframe
- Return type:
df
- deepforest.visualize.format_geometry(predictions, scores=True)[source]#
Format a retinanet prediction into a pandas dataframe for a batch of images :param predictions: a list of dictionaries with keys ‘boxes’ and ‘labels’ coming from a retinanet :param scores: Whether boxes come with scores, during prediction, or without scores, as in during training.
- Returns:
a pandas dataframe
- Return type:
df
- deepforest.visualize.plot_annotations(annotations, savedir=None, height=None, width=None, color=[245, 135, 66], thickness=2, basename=None, root_dir=None, radius=3, image=None)[source]#
Plot the prediction results.
- Parameters:
annotations – a pandas dataframe with prediction results
savedir – optional path to save the figure. If None (default), the figure will be interactively plotted.
height – height of the image in pixels. Required if the geometry type is ‘polygon’.
width – width of the image in pixels. Required if the geometry type is ‘polygon’.
results_color (list or sv.ColorPalette) – color of the results annotations as a tuple of RGB color (if a single color), e.g. orange annotations is [245, 135, 66], or an supervision.ColorPalette if multiple labels and specifying colors for each label
thickness – thickness of the rectangle border line in px
basename – optional basename for the saved figure. If None (default), the basename will be extracted from the image path.
root_dir – optional path to the root directory of the images. If None (default), the root directory will be extracted from the annotations dataframe.root_dir attribute.
radius – radius of the points in px
- Returns:
None
- deepforest.visualize.plot_points(image, points, color=None, radius=5, thickness=1)[source]#
Plot points on an image :param image: a numpy array in BGR color order! Channel order is channels first :param points: a numpy array of shape (N, 2) representing the coordinates of the points :param color: color of the points as a tuple of BGR color, e.g. orange points is (0, 165, 255) :param radius: radius of the points in px :param thickness: thickness of the point border line in px
- Returns:
a numpy array with drawn points
- Return type:
image
- deepforest.visualize.plot_prediction_and_targets(image, predictions, targets, image_name, savedir)[source]#
Plot an image, its predictions, and its ground truth targets for debugging.
- Parameters:
image – torch tensor, RGB color order
targets – torch tensor
- Returns:
path on disk with saved figure
- Return type:
figure_path
- deepforest.visualize.plot_prediction_dataframe(df, root_dir, savedir, color=None, thickness=1, ground_truth=None)[source]#
For each row in dataframe, call plot predictions and save plot files to disk. For multi-class labels, boxes will be colored by labels. Ground truth boxes will all be same color, regardless of class.
- Parameters:
df – a pandas dataframe with image_path, xmin, xmax, ymin, ymax and label columns. The image_path column should be the relative path from root_dir, not the full path.
root_dir – relative dir to look for image names from df.image_path
ground_truth – an optional pandas dataframe in same format as df holding ground_truth boxes
savedir – save the plot to an optional directory path.
- Returns:
list of filenames written
- Return type:
written_figures
- deepforest.visualize.plot_predictions(image, df, color=None, thickness=1)[source]#
Plot a set of boxes on an image By default this function does not show, but only plots an axis Label column must be numeric! Image must be BGR color order!
- Parameters:
image – a numpy array in BGR color order! Channel order is channels first
df – a pandas dataframe with xmin, xmax, ymin, ymax and label column
color – color of the bounding box as a tuple of BGR color, e.g. orange annotations is (0, 165, 255)
thickness – thickness of the rectangle border line in px
- Returns:
a numpy array with drawn annotations
- Return type:
image
- deepforest.visualize.plot_results(results, ground_truth=None, savedir=None, height=None, width=None, results_color=[245, 135, 66], ground_truth_color=[0, 165, 255], thickness=2, basename=None, radius=3, image=None, axes=False)[source]#
Plot the prediction results.
- Parameters:
results – a pandas dataframe with prediction results
ground_truth – an optional pandas dataframe with ground truth annotations
savedir – optional path to save the figure. If None (default), the figure will be interactively plotted.
height – height of the image in pixels. Required if the geometry type is ‘polygon’.
width – width of the image in pixels. Required if the geometry type is ‘polygon’.
results_color (list or sv.ColorPalette) – color of the results annotations as a tuple of RGB color (if a single color), e.g. orange annotations is [245, 135, 66], or an supervision.ColorPalette if multiple labels and specifying colors for each label
ground_truth_color (list) – color of the ground truth annotations as a tuple of RGB color, e.g. blue annotations is [0, 165, 255]
thickness – thickness of the rectangle border line in px
basename – optional basename for the saved figure. If None (default), the basename will be extracted from the image path.
radius – radius of the points in px
image – an optional numpy array of an image to annotate. If None (default), the image will be loaded from the results dataframe.
axes – returns matplotlib axes object if True
- Returns:
Matplotlib axes object if axes=True, otherwise None
- deepforest.visualize.view_dataset(ds, savedir=None, color=None, thickness=1)[source]#
Plot annotations on images for debugging purposes.
- Parameters:
ds – a deepforest pytorch dataset, see deepforest.dataset or deepforest.load_dataset() to start from a csv file
savedir – optional path to save figures. If none (default) images will be interactively plotted
color – color of the bounding box as a tuple of BGR color, e.g. orange annotations is (0, 165, 255)
thickness – thickness of the rectangle border line in px
Module contents#
Top-level package for DeepForest.