deeplabcut.core.metrics.api
API methods to get metrics for deep learning models.
Functions:
| Name | Description |
|---|---|
compute_metrics |
Computes pose estimation performance metrics. |
prepare_evaluation_data |
Prepares predictions and ground truth pose to compute metrics. |
compute_metrics
compute_metrics(
ground_truth: dict[str, ndarray],
predictions: dict[str, ndarray],
single_animal: bool = False,
unique_bodypart_gt: dict[str, ndarray] | None = None,
unique_bodypart_poses: dict[str, ndarray] | None = None,
pcutoff: float = -1,
oks_bbox_margin: int = 0,
oks_sigma: float | ndarray = 0.1,
per_keypoint_rmse: bool = False,
compute_detection_rmse: bool = True,
) -> dict
Computes pose estimation performance metrics.
Given ground truth pose labels and predictions on a dataset, computes RMSE and pose mAP/mAR using OKS.
The image paths in the ground_truth dict must be the same as the ones in the predictions dict.
Single animal RMSE is computed by simply calculating the Euclidean distance between each ground truth keypoint and the corresponding prediction.
Multi-animal RMSE is computed differently: predictions are first matched to ground truth individuals using greedy OKS matching. OKS (or object keypoint similarity) is a similarity metric for keypoints (you can read more about it and its definition here: https://cocodataset.org/#keypoints-eval). RMSE is then computed only between predictions and the ground truth pose they are matched to, only when the OKS is greater than a small threshold. Predictions that cannot be matched to any ground truth with non-zero OKS are not used to compute RMSE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
dict[str, ndarray]
|
The ground truth pose for which to compute metrics in the dataset.
This should be a dictionary mapping strings (image UIDs, such as image
paths) to ground truth pose for the image. The pose arrays should be
in the format (num_individuals, num_bodyparts, 3), where the 3 values are
x, y and visibility. The |
required |
|
dict[str, ndarray]
|
The predicted poses for which to compute metrics in the dataset. This should be a dictionary mapping strings (image UIDs, such as image paths) to pose predictions for the image. The pose arrays should be in the format (num_predictions, num_bodyparts, 3), where the 3 values are x, y and score. The number of predictions can be different to the number of ground truth individuals labeled for an image. |
required |
|
bool
|
Whether the metrics are being computed on a single-animal or multi-animal dataset. This has an impact on RMSE computation. |
False
|
|
dict[str, ndarray] | None
|
If unique bodyparts are defined for the dataset, they should
be contained in this dict in the same format as the |
None
|
|
dict[str, ndarray] | None
|
If unique bodyparts are defined for the dataset, the
predictions should be contained in this dict in the same format as the
|
None
|
|
float
|
The threshold to compute the "rmse_cutoff" score (RMSE of all predictions with score above the cutoff). |
-1
|
|
int
|
The margin to add around keypoints to compute the area for OKS computation. |
0
|
|
float | ndarray
|
The OKS sigma to use to compute pose. |
0.1
|
|
bool
|
Compute per-keypoint RMSE values. |
False
|
|
bool
|
Computes detection RMSE (without animal assembly) if the predictions are from a multi-animal model. |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
A dictionary containing keys "rmse", "rmse_cutoff", "mAP" and "mAR" mapping to those metrics on the given dataset. If unique bodyparts are given, two extra keys "rmse_unique_bodyparts" and "rmse_pcutoff_unique_bodyparts" are also returned, containing the metrics for the unique bodyparts head. If |
Examples:
>>> # Define the p-cutoff, prediction, and target DataFrames
>>> pcutoff = 0.5
>>> ground_truth = {"img0": np.array([[[1.0, 1.0, 2.0], ...], ...]), ...}
>>> predictions = {"img0": np.array([[[2.0, 1.0, 0.4], ...], ...]), ...}
>>> scores = compute_metrics(ground_truth, predictions, pcutoff=pcutoff)
>>> print(scores)
{
"rmse": 1.0,
"rmse_pcutoff": 0.0,
'mAP': 84.2,
'mAR': 74.5
} # Sample output scores
Source code in deeplabcut/core/metrics/api.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |
prepare_evaluation_data
prepare_evaluation_data(
ground_truth: dict[str, ndarray], predictions: dict[str, ndarray]
) -> list[tuple[np.ndarray, np.ndarray]]
Prepares predictions and ground truth pose to compute metrics.
Only keeps ground truth and predicted assemblies with at least 2 valid keypoints.
Sets the coordinates for all keypoints that aren't visible (for ground truth,
visibility <= 0 and for predictions score <= 0) to np.nan.
Sorts valid predictions by score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
dict[str, ndarray]
|
For each image, the GT of shape (n_idv, n_bpt, 3). |
required |
|
dict[str, ndarray]
|
For each image, the pose predictions of shape (n_pred, n_bpt, 3). |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[ndarray, ndarray]]
|
A list containing (ground truth pose, predicted pose) for each image in the dataset, where the predicted pose is sorted from highest to lowest score. |