Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detection: panoptic quality #929

Merged
merged 75 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
2737c5c
add panoptic quality class and test
Mar 25, 2022
8b35d9d
implement draft panoptic quality module
Mar 25, 2022
c512db2
fix panoptic calculation
Mar 28, 2022
312de56
ignore void labels
Mar 28, 2022
42bb5e6
expose panoptic quality module
Mar 28, 2022
31d4b90
handle unknown classes as void
Mar 28, 2022
5919e38
add validation tests
Mar 28, 2022
fb0e49f
refacor to move logic in functional part
Mar 29, 2022
ce77781
ignore mostly void areas for fp/fn count
Mar 30, 2022
cf165b1
disallow unknown preds categories
Mar 30, 2022
312583f
disallow unknown preds categories
Mar 30, 2022
a16c7c4
update readme
Mar 30, 2022
ae1a995
add MetricTester class
Mar 30, 2022
85b85ba
add more tests images
Mar 31, 2022
b062e41
fix devices + compatibility with torch < 0.10
Mar 31, 2022
d56a012
define categories with set instead of dict
Apr 4, 2022
189d9d8
Merge branch 'master' into feature/50_panoptic_quality
Apr 4, 2022
2bcf236
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 4, 2022
76af389
ignore update type
Apr 4, 2022
63d7922
Merge branch 'feature/50_panoptic_quality' of https://github.com/nibe…
Apr 4, 2022
b77758d
fix changelog
Apr 4, 2022
aa15e69
fix unused import
Apr 4, 2022
3c3a6d9
fix PEP8 compliance of imports
Apr 4, 2022
4f35be2
ignore init type check
Apr 5, 2022
3a77f8e
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki Apr 11, 2022
4cae6ac
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki Apr 12, 2022
3682040
Apply suggestions from code review
SkafteNicki Apr 12, 2022
26088f1
add functional docs
SkafteNicki Apr 12, 2022
aa68357
Update docs/source/references/modules.rst
SkafteNicki Apr 12, 2022
5dd2f32
fix typing
SkafteNicki Apr 12, 2022
c6a0711
fix
SkafteNicki Apr 12, 2022
414c332
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki Apr 26, 2022
a67c081
docs
SkafteNicki Apr 26, 2022
591249f
fix some docs
SkafteNicki Apr 26, 2022
ddf4601
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki May 5, 2022
e44b673
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki May 10, 2022
0f336be
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki May 19, 2022
8729906
Merge branch 'master' into feature/50_panoptic_quality
Borda Dec 23, 2022
79f0bcd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 23, 2022
6030f54
Merge branch 'master' into feature/50_panoptic_quality
justusschock Jan 9, 2023
88be6ab
add missing docstrings
justusschock Jan 9, 2023
8a35c0c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 9, 2023
759985c
changelog
SkafteNicki Jan 31, 2023
23a0717
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 31, 2023
2d40239
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki Jan 31, 2023
e7a1796
fix docs
SkafteNicki Jan 31, 2023
ac72491
merge
SkafteNicki Jan 31, 2023
0376678
move file
SkafteNicki Jan 31, 2023
51d88d4
fix imports
SkafteNicki Jan 31, 2023
0a0dd45
fix tests
SkafteNicki Jan 31, 2023
dd92955
try fixing docs
SkafteNicki Jan 31, 2023
2400353
add batch size
SkafteNicki Jan 31, 2023
df3b228
fix typing
SkafteNicki Jan 31, 2023
e4a8e88
add class attributes
SkafteNicki Jan 31, 2023
70fdd5e
Merge branch 'master' into feature/50_panoptic_quality
SkafteNicki Jan 31, 2023
82f0be4
fix mypy
SkafteNicki Jan 31, 2023
1517081
Merge branch 'master' into feature/50_panoptic_quality
Borda Feb 7, 2023
4070e42
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 7, 2023
ba6ab38
Apply suggestions from code review
Borda Feb 7, 2023
50320fa
cleaning
Borda Feb 7, 2023
e4550db
precommit
Borda Feb 7, 2023
d48435e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 7, 2023
d3ae477
Merge branch 'feature/50_panoptic_quality' of https://github.com/nibe…
Borda Feb 7, 2023
25cff6a
Merge branch 'master' into feature/50_panoptic_quality
Borda Feb 13, 2023
513e1de
stuffs
Borda Feb 13, 2023
520d39f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 13, 2023
10b411a
Merge branch 'master' into feature/50_panoptic_quality
Borda Feb 13, 2023
c9469ee
stuffs
Borda Feb 13, 2023
f88aadc
Merge branch 'feature/50_panoptic_quality' of https://github.com/nibe…
Borda Feb 13, 2023
40da04d
Apply suggestions from code review
Borda Feb 14, 2023
0bcf6d2
warn
Borda Feb 14, 2023
dd87a8d
Merge branch 'feature/50_panoptic_quality' of https://github.com/nibe…
Borda Feb 14, 2023
68a302e
Apply suggestions from code review
Borda Feb 14, 2023
e182430
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 14, 2023
781fe83
precommit
Borda Feb 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `classes` to output from `MAP` metric ([#1419](https://github.com/Lightning-AI/metrics/pull/1419))


- Added new detection metric `PanopticQuality` ([#929](https://github.com/PyTorchLightning/metrics/pull/929))


- Add `ClassificationTask` Enum and use in metrics ([#1479](https://github.com/Lightning-AI/metrics/pull/1479))


Expand Down Expand Up @@ -314,6 +317,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `reset_real_features` argument image quality assessment metrics ([#722](https://github.com/Lightning-AI/metrics/pull/722))
- Added new keyword argument `compute_on_cpu` to all metrics ([#867](https://github.com/Lightning-AI/metrics/pull/867))


### Changed

- Made `num_classes` in `jaccard_index` a required argument ([#853](https://github.com/Lightning-AI/metrics/pull/853), [#914](https://github.com/Lightning-AI/metrics/pull/914))
Expand Down
21 changes: 21 additions & 0 deletions docs/source/detection/panoptic_quality.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.. customcarditem::
:header: Panoptic Quality
:image: https://pl-flash-data.s3.amazonaws.com/assets/thumbnails/image_classification.svg
:tags: Detection

################
Panoptic Quality
################

Module Interface
________________

.. autoclass:: torchmetrics.PanopticQuality
:noindex:
:exclude-members: update, compute

Functional Interface
____________________

.. autofunction:: torchmetrics.functional.panoptic_quality
:noindex:
1 change: 1 addition & 0 deletions docs/source/links.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,5 @@
.. _kid ref2: https://arxiv.org/abs/1706.08500
.. _Spectral Angle Mapper: https://ntrs.nasa.gov/citations/19940012238
.. _Multilabel coverage error: https://link.springer.com/chapter/10.1007/978-0-387-09823-4_34
.. _Panoptic Quality: https://arxiv.org/abs/1801.00868
.. _torchmetrics mAP example: https://github.com/Lightning-AI/metrics/blob/master/examples/detection_map.py
2 changes: 2 additions & 0 deletions src/torchmetrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
StatScores,
)
from torchmetrics.collections import MetricCollection # noqa: E402
from torchmetrics.detection import PanopticQuality # noqa: E402
from torchmetrics.image import ( # noqa: E402
ErrorRelativeGlobalDimensionlessSynthesis,
MultiScaleStructuralSimilarityIndexMeasure,
Expand Down Expand Up @@ -153,6 +154,7 @@
"MinMetric",
"MultioutputWrapper",
"MultiScaleStructuralSimilarityIndexMeasure",
"PanopticQuality",
"PearsonCorrCoef",
"PearsonsContingencyCoefficient",
"PermutationInvariantTraining",
Expand Down
2 changes: 2 additions & 0 deletions src/torchmetrics/detection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@

if _TORCHVISION_GREATER_EQUAL_0_8:
from torchmetrics.detection.mean_ap import MeanAveragePrecision # noqa: F401

from torchmetrics.detection.panoptic_quality import PanopticQuality # noqa: F401
137 changes: 137 additions & 0 deletions src/torchmetrics/detection/panoptic_quality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Copyright The PyTorch Lightning team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Any, Set

import torch
from torch import Tensor

from torchmetrics.functional.detection.panoptic_quality import (
_get_category_id_to_continuous_id,
_get_void_color,
_panoptic_quality_compute,
_panoptic_quality_update,
_prepocess_image,
_validate_categories,
_validate_inputs,
)
from torchmetrics.metric import Metric


class PanopticQuality(Metric):
r"""Compute the `Panoptic Quality`_ for panoptic segmentations.

.. math::
PQ = \frac{IOU}{TP + 0.5 FP + 0.5 FN}

where IOU, TP, FP and FN are respectively the sum of the intersection over union for true positives, the number of
true postitives, false positives and false negatives. This metric is inspired by the PQ implementation of
panopticapi, a standard implementation for the PQ metric for object detection.

Borda marked this conversation as resolved.
Show resolved Hide resolved
Args:
things:
Set of ``category_id`` for countable things.
stuffs:
Set of ``category_id`` for uncountable stuffs.
allow_unknown_preds_category:
Bool indication if unknown categories in preds is allowed

Raises:
ValueError:
If ``things``, ``stuffs`` share the same ``category_id``.

Example:
>>> from torch import tensor
>>> preds = tensor([[[6, 0], [0, 0], [6, 0], [6, 0]],
... [[0, 0], [0, 0], [6, 0], [0, 1]],
... [[0, 0], [0, 0], [6, 0], [0, 1]],
... [[0, 0], [7, 0], [6, 0], [1, 0]],
... [[0, 0], [7, 0], [7, 0], [7, 0]]])
>>> target = tensor([[[6, 0], [0, 1], [6, 0], [0, 1]],
... [[0, 1], [0, 1], [6, 0], [0, 1]],
... [[0, 1], [0, 1], [6, 0], [1, 0]],
... [[0, 1], [7, 0], [1, 0], [1, 0]],
... [[0, 1], [7, 0], [7, 0], [7, 0]]])
>>> panoptic_quality = PanopticQuality(things = {0, 1}, stuffs = {6, 7})
>>> panoptic_quality(preds, target)
tensor(0.5463, dtype=torch.float64)
"""
is_differentiable: bool = False
higher_is_better: bool = True
full_state_update: bool = False

iou_sum: Tensor
true_positives: Tensor
false_positives: Tensor
false_negatives: Tensor

def __init__(
self,
things: Set[int],
stuffs: Set[int],
allow_unknown_preds_category: bool = False,
**kwargs: Any,
):
super().__init__(**kwargs)

_validate_categories(things, stuffs)
self.things = things
self.stuffs = stuffs
self.void_color = _get_void_color(things, stuffs)
self.cat_id_to_continuous_id = _get_category_id_to_continuous_id(things, stuffs)
self.allow_unknown_preds_category = allow_unknown_preds_category

# per category intermediate metrics
n_categories = len(things) + len(stuffs)
self.add_state("iou_sum", default=torch.zeros(n_categories, dtype=torch.double), dist_reduce_fx="sum")
self.add_state("true_positives", default=torch.zeros(n_categories, dtype=torch.int), dist_reduce_fx="sum")
self.add_state("false_positives", default=torch.zeros(n_categories, dtype=torch.int), dist_reduce_fx="sum")
self.add_state("false_negatives", default=torch.zeros(n_categories, dtype=torch.int), dist_reduce_fx="sum")

def update(self, preds: Tensor, target: Tensor) -> None:
r"""Update state with predictions and targets.

Args:
preds: panoptic detection of shape ``[height, width, 2]`` containing
the pair ``(category_id, instance_id)`` for each pixel of the image.
If the ``category_id`` refer to a stuff, the instance_id is ignored.

target: ground truth of shape ``[height, width, 2]`` containing
the pair ``(category_id, instance_id)`` for each pixel of the image.
If the ``category_id`` refer to a stuff, the instance_id is ignored.

Raises:
TypeError:
If ``preds`` or ``target`` is not an ``torch.Tensor``
ValueError:
If ``preds`` or ``target`` has different shape.
ValueError:
If ``preds`` is not a 3D tensor where the final dimension have size 2
"""
_validate_inputs(preds, target)
flatten_preds = _prepocess_image(
self.things, self.stuffs, preds, self.void_color, self.allow_unknown_preds_category
)
flatten_target = _prepocess_image(self.things, self.stuffs, target, self.void_color, True)
iou_sum, true_positives, false_positives, false_negatives = _panoptic_quality_update(
flatten_preds, flatten_target, self.cat_id_to_continuous_id, self.void_color
)
self.iou_sum += iou_sum
self.true_positives += true_positives
self.false_positives += false_positives
self.false_negatives += false_negatives

def compute(self) -> Tensor:
"""Computes panoptic quality based on inputs passed in to ``update`` previously."""
return _panoptic_quality_compute(self.iou_sum, self.true_positives, self.false_positives, self.false_negatives)
2 changes: 2 additions & 0 deletions src/torchmetrics/functional/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from torchmetrics.functional.classification.roc import roc
from torchmetrics.functional.classification.specificity import specificity
from torchmetrics.functional.classification.stat_scores import stat_scores
from torchmetrics.functional.detection.panoptic_quality import panoptic_quality
from torchmetrics.functional.image.d_lambda import spectral_distortion_index
from torchmetrics.functional.image.ergas import error_relative_global_dimensionless_synthesis
from torchmetrics.functional.image.gradients import image_gradients
Expand Down Expand Up @@ -138,6 +139,7 @@
"pairwise_euclidean_distance",
"pairwise_linear_similarity",
"pairwise_manhattan_distance",
"panoptic_quality",
"pearson_corrcoef",
"pearsons_contingency_coefficient",
"pearsons_contingency_coefficient_matrix",
Expand Down
14 changes: 14 additions & 0 deletions src/torchmetrics/functional/detection/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright The PyTorch Lightning team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from torchmetrics.functional.detection.panoptic_quality import panoptic_quality # noqa: F401
Loading