Skip to content

Conversation

@harsh1504660
Copy link

@harsh1504660 harsh1504660 commented Aug 6, 2025

📝 Description

  • This PR fixes a bug where AttributeError: 'F1AdaptiveThreshold' object has no attribute '_update_called' was raised when using models like GANomaly that don't define this attribute in their image_threshold_metric.

The change uses getattr(...) to safely check if _update_called exists before accessing it, ensuring compatibility with other models and avoiding unexpected crashes.

✨ Changes

Select what type of change your PR is:

  • 🚀 New feature (non-breaking change which adds functionality)
  • 🐞 Bug fix (non-breaking change which fixes an issue)
  • 🔄 Refactor (non-breaking change which refactors the code base)
  • ⚡ Performance improvements
  • 🎨 Style changes (code style/formatting)
  • 🧪 Tests (adding/modifying tests)
  • 📚 Documentation update
  • 📦 Build system changes
  • 🚧 CI/CD configuration
  • 🔧 Chore (general maintenance)
  • 🔒 Security update
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)

✅ Checklist

Before you submit your pull request, please make sure you have completed the following steps:

  • 📚 I have made the necessary updates to the documentation (if applicable).
  • 🧪 I have written tests that support my changes and prove that my fix is effective or my feature works (if applicable).
  • 🏷️ My PR title follows conventional commit format.

For more information about code review checklists, see the Code Review Checklist.

@psous32
Copy link

psous32 commented Aug 7, 2025

Hello @harsh1504660 , all good ?
I saw your commit and tried to change it. It worked, but in the next update_called, the code crashed. I changed it the same way you did, and it started working, and I'm already running the model. I'll leave the change below.
Thanks for your help and availability.

           if getattr(self._image_threshold_metric, "_update_called", False):
                  self._image_threshold.copy_(self._image_threshold_metric.compute())
                  self._image_threshold_metric.reset()
              if getattr(self._image_threshold_metric, "_update_called", False):
                  self._pixel_threshold.copy_(self._pixel_threshold_metric.compute())
                  self._pixel_threshold_metric.reset()
        if self.enable_normalization:
            # compute normalization values
            if getattr(self._image_min_max_metric, "_update_called", False):
                image_min, image_max = self._image_min_max_metric.compute()
                self.image_min.copy_(image_min)
                self.image_max.copy_(image_max)
                self._image_min_max_metric.reset()
            if getattr(self._image_min_max_metric, "_update_called", False):
                pixel_min, pixel_max = self._pixel_min_max_metric.compute()
                self.pixel_min.copy_(pixel_min)
                self.pixel_max.copy_(pixel_max)
                self._pixel_min_max_metric.reset()

@harsh1504660
Copy link
Author

Hi @psous32,
Thanks for the heads-up. I've applied the necessary corrections to ensure update_called behaves as intended.

@psous32
Copy link

psous32 commented Aug 7, 2025

Thank you @harsh1504660 , I have to thank you for keeping this lib with a good support

@harsh1504660 harsh1504660 changed the title fix - update-called-attribute issue : #2862 fix(model): resolve update-called-attribute issue #2862 Aug 7, 2025
@rajeshgangireddy rajeshgangireddy self-requested a review August 14, 2025 11:27
Copy link
Contributor

@rajeshgangireddy rajeshgangireddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @harsh1504660
Thanks for the attempt to fix the error.

I have some comments:

  1. I can not reproduce the same error about the update_called not being there.
    As far as I can see, update_called is a standard property that should exist on all metrics from since torchmtrics 1.0 release.

Source: https://github.com/Lightning-AI/torchmetrics/blob/3a26afb551de6a2f479194c77e8b8bc8a6cd3f53/CHANGELOG.md?plain=1#L626
https://github.com/Lightning-AI/torchmetrics/blob/3a26afb551de6a2f479194c77e8b8bc8a6cd3f53/src/torchmetrics/metric.py#L187

torchmetrics version: 1.7.4
hasattr(metric, "update_called"): True

Which version of torch metrics are you using? Please note that the anomalib requires torchmetrics>1.3

  1. It might be nice to not use the private _update_called as it has been long deprecated.

https://github.com/Lightning-AI/torchmetrics/blob/3a26afb551de6a2f479194c77e8b8bc8a6cd3f53/CHANGELOG.md?plain=1#L416

@@ -135,15 +135,15 @@ def on_validation_epoch_end(self, trainer: Trainer, pl_module: LightningModule)
del trainer, pl_module
if self.enable_thresholding:
# compute threshold values
if self._image_threshold_metric.update_called:
if getattr(self._image_threshold_metric, "_update_called", False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am personally not in favour of using getattrs if possible. If the image threshold metric isn't set, it will be None. In that case we can just compare it against null value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐞 Error in attribute 'update_called'

4 participants