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

[Bug]: AttributeError: 'NoneType' object has no attribute 'flatten' #2510

Open
1 task done
Septembit opened this issue Jan 15, 2025 · 3 comments
Open
1 task done

[Bug]: AttributeError: 'NoneType' object has no attribute 'flatten' #2510

Septembit opened this issue Jan 15, 2025 · 3 comments

Comments

@Septembit
Copy link

Describe the bug

when I tried to train a fastflow model by config file, I got this error.
the version is anomalib==2.0.0b2

Dataset

Folder

Model

FastFlow

Steps to reproduce the behavior

anomalib fit --config ./config.yaml

OS information

OS information:

  • OS: [e.g. Ubuntu 20.04]
  • Python version: [e.g. 3.10.0]
  • Anomalib version: [e.g. 0.3.6]
  • PyTorch version: [e.g. 1.9.0]
  • CUDA/cuDNN version: [e.g. 11.1]
  • GPU models and configuration: [e.g. 2x GeForce RTX 3090]
  • Any other relevant information: [e.g. I'm using a custom dataset]

Expected behavior

NG

Screenshots

Image

`

Pip/GitHub

pip

What version/branch did you use?

2.0.0b2

Configuration YAML

# anomalib==2.0.0b2
seed_everything: true

model:
  class_path: anomalib.models.Fastflow
  init_args:
    backbone: resnet18
    pre_trained: true
    flow_steps: 8
    conv3x3_only: false
    hidden_ratio: 1.0

trainer:
  max_epochs: 500
  callbacks:
    - class_path: lightning.pytorch.callbacks.EarlyStopping
      init_args:
        patience: 3
        monitor: pixel_AUROC
        mode: max
data:
  class_path: anomalib.data.Folder
  init_args:
    name: bottle_0528
    normal_dir: ok
    root: data/bottle-bottom-dataset
    abnormal_dir: ng
    normal_test_dir: null
    mask_dir: null
    normal_split_ratio: 0.2
    extensions: null
    train_batch_size: 1
    eval_batch_size: 1
    num_workers: 0
    train_augmentations: null
    val_augmentations: null
    test_augmentations: null
    augmentations: null
    test_split_mode: from_dir
    test_split_ratio: 0.2
    val_split_mode: same_as_test
    val_split_ratio: 0.2
    seed: null
logging:
  log_graph: false
default_root_dir: results
ckpt_path: null

Logs

NG

Code of Conduct

  • I agree to follow this project's Code of Conduct
@alexriedel1
Copy link
Contributor

If you don't provide a mask dir mask_dir: null of ground truth masks of anomalous samples, the trainer assumes you want to perform a classifaction task instead of an segmentation task. In an classification task, you cannot calculate pixel metrics (such as pixel_AUROC)

@Septembit
Copy link
Author

@alexriedel1
Thanks for your reply, I tried to change the pixel_AUROC to image_AUROC in trainer filed. But I still meet this error.

# anomalib==2.0.0b2
seed_everything: true

model:
  class_path: anomalib.models.Fastflow
  init_args:
    backbone: resnet18
    pre_trained: true
    flow_steps: 8
    conv3x3_only: false
    hidden_ratio: 1.0

trainer:
  max_epochs: 500
  callbacks:
    - class_path: lightning.pytorch.callbacks.EarlyStopping
      init_args:
        patience: 3
        monitor: image_AUROC
        mode: max
data:
  class_path: anomalib.data.Folder
  init_args:
    name: bottle_0528
    normal_dir: ok
    root: data/bottle-bottom-dataset
    abnormal_dir: ng
    normal_test_dir: null
    mask_dir: null
    normal_split_ratio: 0.2
    extensions: null
    train_batch_size: 64
    eval_batch_size: 64
    num_workers: 0
    train_augmentations: null
    val_augmentations: null
    test_augmentations: null
    augmentations: null
    test_split_mode: from_dir
    test_split_ratio: 0.2
    val_split_mode: same_as_test
    val_split_ratio: 0.2
    seed: null
logging:
  log_graph: false
default_root_dir: results
ckpt_path: null

@alexriedel1
Copy link
Contributor

alexriedel1 commented Jan 17, 2025

Ah I see!

The pixel threshold is calculated based on ground truth masks, even if it is a classification task and there is no mask!

if outputs.anomaly_map is not None:
self._pixel_threshold.update(outputs.anomaly_map, outputs.gt_mask)

To fix this, I created this PR @samet-akcay #2513

The other problem you will face after this fix is, that the default evaluator will evaluate pixel and image metrics.

image_auroc = AUROC(fields=["pred_score", "gt_label"], prefix="image_")
image_f1score = F1Score(fields=["pred_label", "gt_label"], prefix="image_")
pixel_auroc = AUROC(fields=["anomaly_map", "gt_mask"], prefix="pixel_")
pixel_f1score = F1Score(fields=["pred_mask", "gt_mask"], prefix="pixel_")
test_metrics = [image_auroc, image_f1score, pixel_auroc, pixel_f1score]
return Evaluator(test_metrics=test_metrics)

So if you have a classification task, you need to configure a custom evaluator. I'm not very familiar with the current config file design, but with the API, you would do it like this:

datamodule = Folder(
        name="bottle_0528",
        root = "data/bottle-bottom-dataset",
        normal_dir="ok",
        abnormal_dir="ng",
    )
    evaluator = Evaluator(
        test_metrics=[
            F1Score(fields=["pred_label", "gt_label"], prefix="image_"),
        ]
    )
    model = Patchcore(evaluator=evaluator)
    engine = Engine()
    engine.fit(datamodule=datamodule, model=model)

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

No branches or pull requests

2 participants