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

Add ensembling methods for tiling to Anomalib #1226

Draft
wants to merge 192 commits into
base: main
Choose a base branch
from

Conversation

blaz-r
Copy link
Contributor

@blaz-r blaz-r commented Aug 1, 2023

Description

This PR adds mechanism to train ensemble of models on tiled images. It is part of Google Summer of Code.

A lot of details on implementation as well as discussion can be accessed in #1131.

Closes #1727

Changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which refactors the code base)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist

Some things still todo (tests, docs...) but most of the code is ready for review.

  • My code follows the pre-commit style and check guidelines of this project.
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes
  • I have added a summary of my changes to the CHANGELOG (not for minor changes, docs and tests).

Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
@blaz-r blaz-r marked this pull request as draft June 12, 2024 21:16
blaz-r added 18 commits June 13, 2024 14:11
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
Signed-off-by: Blaz Rolih <blaz.rolih@gmail.com>
@ashwinvaidya17 ashwinvaidya17 added this to the v1.2.0 milestone Jun 26, 2024
Copy link
Collaborator

@ashwinvaidya17 ashwinvaidya17 left a comment

Choose a reason for hiding this comment

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

Thanks! Massive efforts here. I have a few minor comments regarding refactoring the config file. It is more of a personal preference. Other than that, I think there are some files that might be left over from the previous version.

out = {}
for step in tqdm(self.steps):
if step.final_compute:
out[step.name] = step.compute()
Copy link
Collaborator

Choose a reason for hiding this comment

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

From what I understand, compute is only defined for EnsembleMetrics, and is the only one for which final_compute is set to True. I have two ideas here but they are more of a personal preference,

  1. Remove final_compute and implement compute for all sub-classes with pass or
  2. Use is_overridden from lightning_utilities.core.overrides to explicitly check if the step has compute defined
    something like
    if is_overridden("compute", step):
        step.compute()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is no longer used, I'll delete these files asap.

tiler (EnsembleTiler): Tiler object used to get tile dimension data.
"""

name = "pipeline"
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about we rename this to SmoothSeams?

)
runners.append(SerialRunner(MergeJobGenerator()))

if args["pipeline"]["ensemble"]["post_processing"]["seam_smoothing"]["apply"]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since each job is supposed to be independent, how about we move this to a separate section in the config.
Instead of defining the entire config under pipeline we can move each config under its separate key. So, if we set the SmoothingJob.name parameter to SmoothSeams or something, we can then move seam_smoothing section under post_processing to SmoothSeams.

TrainModel:
    ...

Predict:
    ...

SmoothSeams:
    apply: True
    sigma: 2
    width: 0.1

ComputeStatistics:
    ...

Then we can just check if args['SmoothSeams']['apply']:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The solution above should work for this case and is much nicer than what I have now.

The problem here is that some pipeline stages require args from some other part of config. For example, model training job needs to know normalization stage to determine if normalization should be applied at tile level, but normalization stage is is part of post processing. Since the pipeline class does this _args = args.get(runner.generator.job_class.name, None) it would then mean that train job doesn't have access, or I'd need to duplicate this.

So I'm not sure how to best handle such cases with current design.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One possibility is to somehow accumulate the ones that are shared under one name, but then the config file looses the structure a bit.

# tiler is used to determine where seams appear
tiler = get_ensemble_tiler(args)
yield SmoothingJob(
accelerator=args["accelerator"],
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about we pass accelerator in the init method? This way, the only arguments this method relies are under the seam_smoothing method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That could work yeah. Seam smoothing actually relies only on the params under seam_smoothing.

accelerator=args["accelerator"],
predictions=prev_stage_result,
width_factor=args["ensemble"]["post_processing"]["seam_smoothing"]["width"],
filter_sigma=args["ensemble"]["post_processing"]["seam_smoothing"]["width"],
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this supposed to be sigma?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, thanks.

@@ -0,0 +1,107 @@
"""Fixtures that are used in tiled ensemble testing"""

# Copyright (C) 2023 Intel Corporation
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# Copyright (C) 2023 Intel Corporation
# Copyright (C) 2024 Intel Corporation

from pytorch_lightning.callbacks import ModelCheckpoint
from tools.tiled_ensemble.ensemble_tiler import EnsembleTiler
from tools.tiled_ensemble.post_processing.postprocess import NormalizationStage
from tools.tiled_ensemble.predictions import (
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this up-to-date?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are old files, will be removed.

@@ -0,0 +1,112 @@
"""Tiler used with ensemble of models."""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need this here now that is moved to src/anomalib?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I'll delete this.

@@ -0,0 +1,124 @@
"""Anomalib Testing Script for ensemble of models.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this needs to be updated as well.

Copy link
Contributor Author

@blaz-r blaz-r Aug 2, 2024

Choose a reason for hiding this comment

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

I'll go over the test and rewrite them after I refactor the other things that you pointed out.

@@ -0,0 +1,33 @@
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am confused about this. Is this still relevant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No it's not, I'll remove this.

@blaz-r
Copy link
Contributor Author

blaz-r commented Jun 26, 2024

Okay. I'll check those out, thanks for going over the code. Indeed there are still some files left over as the refactor is still not 100% done therefore I left it as draft PR). I still need to cover the tests and all so I didn't delete everything.

blaz-r and others added 4 commits August 2, 2024 17:44
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
Signed-off-by: blaz-r <blaz.rolih@gmail.com>
@blaz-r
Copy link
Contributor Author

blaz-r commented Aug 2, 2024

I answered to some comments, and will refactor the config as you suggested in on of the comments. After the refactors I'll also update/rewrite all the tests. Thanks for all the feedback and patience, I'm quite busy right now and I'll really try to get this sorted when I get some time here and there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ensembling methods for tiling to Anomalib
6 participants