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

Unable to extract confusion matrix as a metric from trainer #19835

Open
lathashree01 opened this issue May 1, 2024 · 1 comment
Open

Unable to extract confusion matrix as a metric from trainer #19835

lathashree01 opened this issue May 1, 2024 · 1 comment
Labels
bug Something isn't working needs triage Waiting to be triaged by maintainers

Comments

@lathashree01
Copy link

lathashree01 commented May 1, 2024

Bug description

Hi team,

During testing, I would like to extract Binaryconfusion matrix as a metric from the trainer.

I can see the value being calculated successfully but it is failing in trainer where the number of elements in result is greater than 1.

def convert_tensors_to_scalars(data: Any) -> Any:
 """Recursively walk through a collection and convert single-item tensors to scalar values.
 Raises:
     ValueError:
         If tensors inside ``metrics`` contains multiple elements, hence preventing conversion to a scalar.

 """
 def to_item(value: Tensor) -> Union[int, float, bool]:
     if value.numel() != 1:
         raise ValueError(
             f"The metric `{value}` does not contain a single element, thus it cannot be converted to a scalar."
         )
     return value.item()
 return apply_to_collection(data, Tensor, to_item)

PS: I am using Anomalib library which is based on pytorch lightning.

How do I resolve this or is there another way to get this? Any help would be greatly appreciated.

Thanks

What version are you seeing the problem on?

v2.2

How to reproduce the bug

Extract BinaryConfusionMatrix as a metric during trainer.test

Error messages and logs

ValueError: The metric `tensor([[343, 497],
        [  0,   4]])` does not contain a single element, thus it cannot be converted to a scalar.

Environment

Current environment
#- Lightning Component (e.g. Trainer, LightningModule, LightningApp, LightningWork, LightningFlow):
#- PyTorch Lightning Version (e.g., 1.5.0):
#- Lightning App Version (e.g., 0.5.2):
#- PyTorch Version (e.g., 2.0):
#- Python version (e.g., 3.9):
#- OS (e.g., Linux):
#- CUDA/cuDNN version:
#- GPU models and configuration:
#- How you installed Lightning(`conda`, `pip`, source):
#- Running environment of LightningApp (e.g. local, cloud):

More info

No response

@lathashree01 lathashree01 added bug Something isn't working needs triage Waiting to be triaged by maintainers labels May 1, 2024
@ryan597
Copy link
Contributor

ryan597 commented May 3, 2024

As the error suggests, if logging a metric it must be a singe value. You could try logging the individual elements of the confusion matrix eg. the true positives, false positives, true negatives, and false negatives

self.log_dict({"bcm/tp": torch.rand(1),
               "bcm/fp": torch.rand(1),
               "bcm/tn": torch.rand(1),
               "bcm/fn": torch.rand(1),
               })

or you could log the confusion matrix as an image

logger = TensorBoardLogger()
logger.experiment.add_image("Confusion Matrix", torch.rand(1, 2, 2), global_step=self.global_step)

using the BinaryConfusionMatrix from torchmetrics

bcm = BinaryConfusionMatrix(normalize='all')
matrix = bcm(torch.randint(0, 2, (1, 50)), torch.randint(0, 2, (1, 50)))  # just making some random predictions and labels to compute BCM
logger.experiment.add_image("bcm", matrix[None], global_step=self.global_step)

or you could use other functions of your logger directly to save the tensor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage Waiting to be triaged by maintainers
Projects
None yet
Development

No branches or pull requests

2 participants