Giter Site home page Giter Site logo

liznerski / fcdd Goto Github PK

View Code? Open in Web Editor NEW
219.0 10.0 60.0 3.45 MB

Repository for the Explainable Deep One-Class Classification paper

License: MIT License

Python 100.00%
anomaly-detection deep-learning one-class-learning xai explanations explainable-deepneuralnetwork machine-learning deep-anomaly-detection pytorch python

fcdd's Introduction

Explainable Deep One-Class Classification

Here we provide the implementation of Fully Convolutional Data Description (FCDD), an explainable approach to deep one-class classification. The implementation is based on PyTorch 1.9.1 and Python 3.8. The code is tested on Linux only. There is a windows branch where we have fixed some errors to make the code Windows compatible. However, there are no guarantees that it will work as expected.

Deep one-class classification variants for anomaly detection learn a mapping that concentrates nominal samples in feature space causing anomalies to be mapped away. Because this transformation is highly non-linear, finding interpretations poses a significant challenge. In this paper we present an explainable deep one-class classification method, Fully Convolutional Data Description (FCDD), where the mapped samples are themselves also an explanation heatmap. FCDD yields competitive detection performance and provides reasonable explanations on common anomaly detection benchmarks with CIFAR-10 and ImageNet. On MVTec-AD, a recent manufacturing dataset offering ground-truth anomaly maps, FCDD sets a new state of the art in the unsupervised setting. Our method can incorporate ground-truth anomaly maps during training and using even a few of these (โˆผ5) improves performance significantly. Finally, using FCDDโ€™s explanations we demonstrate the vulnerability of deep one-class classification models to spurious image features such as image watermarks. The following image shows some of the FCDD explanation heatmaps for test samples of MVTec-AD:

Citation

A PDF of our ICLR 2021 paper is available at: https://openreview.net/forum?id=A5VV3UyIQz.

If you use our work, please also cite the paper:

@inproceedings{
    liznerski2021explainable,
    title={Explainable Deep One-Class Classification},
    author={Philipp Liznerski and Lukas Ruff and Robert A. Vandermeulen and Billy Joe Franks and Marius Kloft and Klaus-Robert M{\"u}ller},
    booktitle={International Conference on Learning Representations},
    year={2021},
    url={https://openreview.net/forum?id=A5VV3UyIQz}
}

Table of contents

Installation

It is recommended to use a virtual environment to install FCDD. Assuming you're in the python directory, install FCDD via pip:

virtualenv -p python3 venv 
source venv/bin/activate
pip install .

Train FCDD

Log data Log data -- i.e. heatmaps, metrics, snapshots, etc. -- is stored on the disc in a certain log directory. The default log directory is located at ../../data/results/fcdd_TIMESTAMP. Thus, log data is being saved in the data directory in the root folder of this repository if the code is run from python/fcdd. The same holds for the data directory, where the datasets are downloaded to. You can change both, the log directory and the data directory, by altering the respective arguments (logdir and datadir).

Virtual Environment If you have used a virtual environment to install FCDD, make sure to activate it.

Train Scripts We recommend training FCDD by starting one of the runners in python/fcdd/runners from the python/fcdd directory. They train several (randomly initialized) separate FCDD models for each class, where in each the respective class is considered nominal.

Fashion-MNIST

With EMNIST OE:

python runners/run_fmnist.py --noise-mode emnist

With CIFAR-100 OE:

python runners/run_fmnist.py 

CIFAR-10

For full OE:

python runners/run_cifar10.py 

For limited OE, change the respective parameter, e.g. for using 8 OE samples:

python runners/run_cifar10.py --oe-limit 8 

ImageNet

For full OE:

 python runners/run_imagenet.py 

Please note that you have to manually download ImageNet1k and ImageNet22k and place them in the correct folders. Let dsdir be your specified dataset directory (per default ../../data/datasets/).

ImageNet1k needs to be in dsdir/imagenet/, containing the devkit, train, and val split in form of a tar file each -- with names ILSVRC2012_devkit_t12.tar.gz, ILSVRC2012_img_train.tar, and ILSVRC2012_img_val.tar. These are the default names expected by the PyTorch loaders. You can download ImageNet1k on the official website: http://image-net.org/download. Note that you have to register beforehand.

ImageNet22k needs to be in dsdir/imagenet22k/fall11_whole_extracted/, containing all the extracted class directories with pictures, e.g. the folder n12267677 having pictures of acorns. Decompressing the downloaded archive should automatically yield this structure. ImageNet22k, i.e. the full release fall 11, can also be downloaded on the official website: http://image-net.org/download.

MVTec-AD

Using confetti noise:

python runners/run_mvtec.py 

Using a semi-supervised setup with one true anomaly per defection:

python runners/run_mvtec.py --supervise-mode noise --noise-mode mvtec_gt --oe-limit 1 

Pascal VOC

python runners/run_pascalvoc.py 

Custom Data

Let again dsdir be your specified dataset directory (per default ../../data/datasets/). Place your training data in dsdir/custom/train/classX/ and your test data in dsdir/custom/test/classX/, with classX being one of the class folders (they can have arbitrary names, but need to be consistent for training and testing). For a one-vs-rest setup (as used for Cifar-10, etc.), place the corresponding images directly in the class folders and run:

python runners/run_custom.py -ovr 

Otherwise, each class requires a separate set of nominal and anomalous test samples. Place the corresponding images in dsdir/custom/test/classX/normal/, dsdir/custom/test/classX/anomalous/, dsdir/custom/train/classX/normal/ and run:

python runners/run_custom.py

If you have some training anomalies in dsdir/custom/train/classX/anomalous/, you can use them in a semi-supervised setting with

python runners/run_custom.py --supervise-mode other

In general, you can adapt most training parameters using the program's arguments (see python runners/run_custom.py --help). Per default, it chooses some parameters that are assumed general-purpose, such as the imagenet-pre-trained CNN for 224x224 images and imagenet22k outlier exposure. To, for example, use confetti noise instead of outlier exposure, set --supervise-mode to malformed_normal and --noise-mode to confetti.

Train Baselines

To run the baseline experiments -- i.e. HSC with heatmaps based on gradients and AE with reconstruction error heatmaps -- little has to be done. Only a few parameters have to be adjusted, most importantly the objective and the network. For instance, in the case of Cifar-10 and HSC:

python runners/run_cifar10.py --objective hsc -n CNN32  --blur-heatmaps 

Similarily for the AE baseline:

python runners/run_cifar10.py --objective ae -n AE32 --supervise-mode unsupervised --blur-heatmaps 
Alternatively, one can use the add_exp_to_base script:

The script is located at python/fcdd/runners/add_exp_to_base.py. It takes a log directory of a previous experiment as input and automatically changes the arguments to run baseline experiments with the same basic configuration. This script has also the advantage of automatically aggregating heatmaps of the given old experiment and baseline experiments to create combined pictures as seen in the paper. For instance, let ../../data/results/fcdd_20200801120000_my_awesome_experiment be a log directory of an old experiment. Then, to produce both baselines, run:

python runners/add_exp_to_base.py ../../data/results/fcdd_20200801120000_my_awesome_experiment 

This will create log directories for each baseline by appending a suffix to the given one, i.e. in this case ../../data/results/fcdd_20200801120000_my_awesome_experiment_HSC and ../../data/results/fcdd_20200801120000_my_awesome_experiment_AE.

Note that the previous experiment needs to be an FCDD experiment and not a baseline itself. Also, note that the baseline experiments use the same data directory parameter as found in the old experiment configuration file. That is, if add_exp_to_base.py is not started from the same directory (e.g. python/fcdd), it will not find the datasets and attempt to download it to another one.

Explanation of the Log Data

A runner saves the achieved scores, metrics, plots, snapshots, and heatmaps in a given log directory. Each log directory contains a separate subdirectory for each class that is trained to be nominal. These subdirectories are named "normal_x", where x is the class number. The class subdirectories again contain a subdirectory for each random seed. These are named "it_x" for x being the iteration number (random seed). Inside the seed subdirectories all actual log data can be found. Additionally, summarized plots will be created for the class subdirectories and the root log directory. For instance, a plot containing ROC curves for each class (averaged over all seeds) can be found in the root log directory.

Visualization for 2 classes and 2 random seeds:

./log_directory 
./log_directory/normal_0 
./log_directory/normal_0/it_0 
./log_directory/normal_0/it_1
./log_directory/normal_1 
./log_directory/normal_1/it_0 
./log_directory/normal_1/it_1 
...

Note that the leaf nodes, i.e. the iteration subdirectories, contain completely separate training results and have no impact on each other.

The actual log data consists of:

  • config.txt: A file containing all the arguments of the training.
  • ds_preview.png: A preview of the dataset, i.e. some random nominal and anomalous samples from the training set. Includes augmentation and data preprocessing. Also shows corresponding ground-truth maps, if such are available.
  • err.pdf: A plot of the loss over time.
  • err_anomalous.pdf: A plot of the loss for anomalous samples only.
  • err_normal.pdf: A plot of the loss for nominal samples only.
  • heatmaps_paper_x_lbly.png: An image of test heatmaps, test inputs, and ground-truth maps. One image for each x-y combination. x is the normalization used, either local (each heatmap is normalized w.r.t. itself only) or semi_global (each heatmap is normalized w.r.t. to all heatmaps in the image). y is the label, i.e. either 1 or 0 (per default 1 is for anomalies).
  • heatmaps_global.png: An image of the first test heatmaps and inputs found in the dataset. The first row shows nominal samples, the second-row anomalous samples. The third row shows the ten most nominal rated nominal samples on the left and the ten most anomalous rated nominal samples on the right. The fourth row shows the ten most nominal rated anomalies on the left and the ten most anomalous rated anomalies on the right. Note that changing the nominal label to 1 flips this.
  • train_heatmaps_global.png: Like above, but for training samples.
  • history.json: A file containing metrics in text form.
  • log.txt: A file containing some logged text lines, like the average AUC value achieved and the duration of the training.
  • print.log: A file that contains all text that has been printed on the console using the Logger.
  • roc.json: ROC values saved as text (not very readable for humans).
  • roc_curve.pdf: ROC for detection performance.
  • gtmap_roc_curve.pdf: ROC for explanation performance. Only for MVTec-AD (or datasets with ground-truth maps).
  • snapshot.pt: Snapshot of the training state and model parameters.
  • src.tar.gz: Snapshot of the complete source code at the moment of the training start time.
  • tims: A directory containing raw tensors heatmaps (not readable for humans).

Customize FCDD

In general, the FCDD implementation splits in five packages: datasets, models, runners, training, and util. dataset contains an implementation of the base class for AD datasets, actual torchvision-style dataset implementations, and artificial anomaly generation implementations. models contains an implementation of the network base class -- including receptive field upsampling and gradient-based heatmap computation -- and implementations of all network architectures. runners contains scripts for starting training runs, processing program arguments, and preparing all training parameters -- like creating an optimizer and network instances. training contains an implementation for actual training and evaluation of the network. util contains all the rest, i.e. e.g. a logger that handles all I/O interactions.

In the following we give a brief tutorial on how to modify the FCDD implementation for specific requirements.

Add a new Network Architecture
  1. Create a new python script in the models package. Implement a PyTorch module that inherits the fcdd.models.bases.BaseNet or the fcdd.models.bases.ReceptiveNet class. The latter takes track of the receptive field. Read the documentation for further details.

  2. Import the new network class in fcdd.models.__init__ to automatically add the network name to the available ones. Make sure that the class name is unique.

Add a new Dataset

First, you should check whether it's possible to use the custom dataset implementation. If not:

  1. Create a new python script in the datasets package. Implement a dataset that inherits the fcdd.datasets.bases.TorchvisionDataset class. Your implementation needs to process all parameters of the fcdd.datasets.bases.load_dataset function in its initialization. You can use the preproc parameter to switch between different data preprocessing pipelines (augmentation, etc). In the end, your implementation needs to have at least all attributes defined in fcdd.datasets.bases.BaseADDataset class. Most importantly, the _train_set attribute and the _test_set attribute containing the corresponding torchvision-style datasets. Have a look at the already available implementations.

  2. Add a name for your dataset to the fcdd.datasets.__init__.DS_CHOICES variable. Add your dataset to the "switch-case" in the fcdd.datasets.__init__.load_dataset function. Add the number of available class for your dataset to the fcdd.datasets.__init__.no_classes function and add the class names to fcdd.datasets.__init__.str_labels.

Add a new Training Parameter
  1. Add an argument to the fcdd.runners.argparse_configs.DefaultConfig class.

  2. Add this argument as a parameter to the fcdd.training.setup.trainer_setup function. Also, make it return the parameter itself, or some other thing that has been created based on your new argument (e.g. an instance of some network, optimizer, etc.).

  3. Add whatever new is being returned by the fcdd.training.setup.trainer_setup function as a parameter to the fcdd.training.super_trainer.SuperTrainer class.

  4. Implement your requested novel behavior based on the new parameter in the SuperTrainer or one of the actual model trainers (FCDDTrainer, HSCTrainer, AETrainer), depending on the objective.

Add a new Runner
  1. Create a new python script in the runners package. Implement a configuration that inherits fcdd.runners.argparse_configs.DefaultConfig. You need to implement the call method for it, where you can add new arguments to the given parser or change the default values.

  2. Create an instance of one of the runners, e.g. fcdd.runners.bases.ClassesRunner or fcdd.runners.bases.SeedsRunner, and use your configuration implementation for that. For both, the SeedsRunner and ClassesRunner, you need to additionally add an argument in your configuration named it that determines the number of different random seeds. Invoke the instance's run method.

Add a new Objective / Trainer
  1. Add a string identification for your new objective to the fcdd.training.setup.OBJECTIVES variable.

  2. Create a new trainer script in the training package. Implement a trainer inheriting fcdd.training.bases.BaseADTrainer. At least implement the loss and snapshot method.

  3. Add the creation of an instance for your new trainer to the "switch-case" in the initialization of fcdd.training.super_trainer.SuperTrainer.

Add a new Type of Synthetic Anomaly
  1. Implement your new synthetic anomaly in fcdd.datasets.noise.

  2. Add a string identification for you new function to the fcdd.datasets.noise_modes.MODES variable.

  3. Add an invocation of your new function to the "switch-case" in fcdd.datasets.noise_modes.generate_noise.

Add a new Outlier Exposure Dataset
  1. Create a new python script in the datasets/outlier_exposure package. Implement a torchvision-style dataset that expects at least the following parameters: size, root, and limit_var. Also, you need to at least implement a get_item method and data_loader method. Cf. one of the existing implementations of Outlier Exposure datasets, e.g. fcdd.datasets.outlier_exposure.emnist.

Need help?

If you find any bugs, have questions, need help modifying FCDD, or want to get in touch in general, feel free to write us an email!

fcdd's People

Contributors

dependabot[bot] avatar liznerski avatar trellixvulnteam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fcdd's Issues

Draw a roc metric plot from another dataset

I tried drawing it using "--load snapshot.pt", but it is lower than the performance confirmed during training.

Assuming you have a validation set of the same type other than the dataset used for training and testing. In this case, how can I draw the roc curve using snapshot.pt?

Can you tell me the right way?

How to pip install FCDD ?

Hey there!

I would like to run the windows version of mvtec.py.

But i could not install FCDD after installing the requirements , and got all this errors
when mvtec.py tries to access bases.py

from fcdd.runners.argparse_configs import DefaultConfig
from fcdd.training.setup import trainer_setup
from fcdd.training.super_trainer import SuperTrainer
from fcdd.util.logging import plot_many_roc, time_format
from fcdd.util.metrics import mean_roc

Which is the right pip command to install it?

In the installation instructions says: pip install... (nothing)

Thanks you so much!

Are all the pictures shown from the test set?

Thanks for the great work!

However, I am confused about data splitting, which is shown with anomalous heatmap. Are they all from the validation or test set? Or from the train set?

Thanks in advance.

can't run runners

Hello, thank you for sharing this project.
I can't run the runner and I have this output after following all the instructions:

Plotting ROC for completed classes up to 0...
Traceback (most recent call last):
File "runners/run_custom.py", line 37, in
runner.run()
File "..\fcdd-master\venv\lib\site-packages\fcdd\runners\bases.py", line 203, in run
self.run_classes(**vars(self.args))
File "..\fcdd-master\venv\lib\site-packages\fcdd\runners\bases.py", line 222, in run_classes
it, **kwargs
File "..\fcdd-master\venv\lib\site-packages\fcdd\runners\bases.py", line 182, in run_seeds
this_viz_ids, **kwargs
File "..\fcdd-master\venv\lib\site-packages\fcdd\runners\bases.py", line 101, in run_one
**kwargs
File "..\fcdd-master\venv\lib\site-packages\fcdd\training\setup.py", line 106, in trainer_setup
noise_mode, online_supervision, nominal_label, oe_limit, logger=logger
File "..\fcdd-master\venv\lib\site-packages\fcdd\datasets_init_.py", line 62, in load_dataset
oe_limit=oe_limit, logger=logger, nominal_label=nominal_label
File "..\fcdd-master\venv\lib\site-packages\fcdd\datasets\image_folder.py", line 90, in init
mean, std = self.extract_mean_std(trainpath, normal_class)
File "..\fcdd-master\venv\lib\site-packages\fcdd\datasets\image_folder.py", line 188, in extract_mean_std
for x, _ in loader:
File "..\fcdd-master\venv\lib\site-packages\torch\utils\data\dataloader.py", line 279, in iter
return _MultiProcessingDataLoaderIter(self)
File "..\fcdd-master\venv\lib\site-packages\torch\utils\data\dataloader.py", line 719, in init
w.start()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\popen_spawn_win32.py", line 65, in _init
_
reduction.dump(process_obj, to_child)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'ADImageFolderDataset.extract_mean_std..'

(venv) ..\fcdd-master\python\fcdd>Traceback (most recent call last):
File "", line 1, in
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

Could you help me, please?
Thank you

Rename online_superviser and offline_superviser

Hi! Thank you for providing the FCDD implementation!
In your last commit (e8d71d0), you renamed superviser to supervisor but the filename and class name of online_superviser.py and filename offline_superviser.py should be renamed too, otherwise the runners won't work.

Providing ground truth maps to prevent purely black or purely white maps

I have ground truth masks and source images for normal and anomalous data samples in my dataset and I have arranged them in the following format:

datasets/custom/test/class1/normal/  # 59 source images
datasets/custom/test/class1/anomalous/  # 53 source images
 
datasets/custom/test_maps/class1/normal/  # 59 ground truth maps \in {0, 255}^(1, W, H)
datasets/custom/test_maps/class1/anomalous/  # 53 ground truth maps \in {0, 255}^(1, W, H)

datasets/custom/train/class1/normal/  # 2370 source images
datasets/custom/train/class1/anomalous/  # 6 source images

datasets/custom/train_maps/class1/normal/  # 2370 ground truth maps \in {0, 255}^(1, W, H)
datasets/custom/train_maps/class1/anomalous/  # 6 ground truth maps \in {0, 255}^(1, W, H)

With the above arrangement, I use the following command:
python runners/run_custom.py --supervise-mode other --ground-truth-maps --blur-heatmaps

The code runs without any errors. However, when I go into the results folder, then I see that the ground truth maps are completely black or completely white images. They do not include the maps that I stored in the folder above. I am not sure why this is happening. Is there any mistake that I am making in the command, or is there any other reason why it is taking purely white or purely black images as ground truth and not using the ones that I provided?
Thank you in advance for your help and suggestions.

Changing loading paths of pretrained model

Hey again @liznerski !

I wish to change the path where the pretrained model (vgg11_bn-6002323d.pth) is loaded from.
From my understanding, the default path is data\\models\\vgg11_bn-6002323d.pth
Where should I edit to do so?

Once again, thank you very much for taking your time!

How to make predictions

Another comment on this. If you want the raw pixel values of the heatmaps that are generated, you can find these in the "tims" directory and load them via torch.load("heatmaps_paper_global_lbl0.pth"). If you want a script that loads the snapshot of a model and generates pixel-wise anomaly score tensors, I added such an implementation here. I hope this helps.

I have run run_prediction_with_snapshot.py, and get the all_anomaly_scores tensor๏ผŒbut how to judge whether it is abnormal through pixel-wise anomaly score tensors? and how to get the heat map through the run_prediction_with_snapshot.py method?

@liznerski

Originally posted by @opentld in #15 (comment)

another question๏ผš
I only put one picture,and the path is shown in the figure:
image
then I ran python runners/run_custom.py --supervise-mode unsupervised --it 1 -e 0 --load ../../data/test/model/snapshot.pt --net FCDD_CNN224_VGG_F
Get the following result๏ผš
image
image
heatmaps_global.png as shown:
heatmaps_global
heatmaps_paper_global_lbl0.png:
heatmaps_paper_global_lbl0
heatmaps_paper_global_lbl1.png:
heatmaps_paper_global_lbl1
heatmaps_paper_local_lbl0.png:
heatmaps_paper_local_lbl0
heatmaps_paper_local_lbl1.png:
heatmaps_paper_local_lbl1
train_heatmaps_global.png:
train_heatmaps_global

so, why does run_custom.py try to process all the classes? For example, I did not place the cable picture, but it still generates normal_1? I just want to perform anomaly detection on the bottle image I set, and get its classification result and heat map. How can I do it?

Originally posted by @opentld in #15 (comment)

@liznerski

how to generate ground truth map

I want to train using a custom dataset.

  1. python run_custom.py -gtms --supervise-mode other

datasets/custom/test/class1/normal/
datasets/custom/test/class1/anomalous/

datasets/custom/train/class1/normal/
datasets/custom/train/class1/anomalous/

Skipped computing the gtmap ROC score. for some samples no ground-truth maps were found

  1. run_prediction_with_snapshot.py
    image

Can I create metric(accuracy)?

First of all, thank you to the developer.

When measuring model performance, I want to use accuracy as well as 'AUC'.
I'm asking you a question because I feel so hard when I try to modify the code.

I try to modify this function( line 328 )and use it.

I understand that the algorithm uses existing labels and score(red_ascores) to obtain AUC.
loss is same anomaly score(pseudo-Huber loss).
anomaly score is loss. ( ascores == anomaly score)
Find tpr, fpr, and thresholds through the "roc_auc_curve" function &
the reduce_ascore(""" Reduces the anomaly score to be a score per image (detection). """) through the "roc_auc_score" function.

However, it is difficult to obtain 'accuracy' in this way.
I understand that "anomaly score" is only used to 'explain' through heat maps.

Ask how to configure the algorithm of 'accuracy'.
I think I need a anomaly detection(binary classification) result for the test dataset.
How do I implement this part?

EOFError: Ran out of input

run_fmnist.py, run_cifar.py, run_tech.py... all runners have a Run out of input error.

====================================================================
...
File "C:\Users\KBM.conda\envs\torch14\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'ADFMNIST.init..'

(torch14) D:\90. Anormaly\fcdd>Traceback (most recent call last):
File "", line 1, in
File "C:\Users\AIW_KBM.conda\envs\torch14\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Users\AIW_KBM.conda\envs\torch14\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

A question about run run_mvtec.py

When I ran python runner/run_mvtec.py, I found that there was no training but directly printed in the terminal: plotting many ROC for completed classes up to [0,...,14], I didnโ€™t find the pictures whcih plotting in the file related directory.
Can you give me some suggestions? thank you very much.

How can i get the best model?

Hi, thank you for your great work.

In the model training process, i wanna select the model with the highest performance.
However, currently, the results learned in the last epoch are stored in the snapshot.

How can I get a best model?

FCDD model without bias raises AssertionError: VGG net is only supported with bias atm!

I am trying to implement the default FCDD model (FCDD_CNN224_VGG_F) without any biases, since there are batch norm layers after conv layers throughout the model, but I get an AssertionError. It looks like I can edit the code and set bias=False in models/bases.py, but I am not sure if this will cause any inconsistencies with the results or their interpretation. Could you please clarify if simply changing the value of bias in the model descriptions in the code will work, or if it is more involved than that? Thank you in advance for any help.

How to do prediction?

Hi
Thanks for your great work.
Could you please explain how to detect and localize anomaly or generate a heatmap for the test image with the .pt file generated?

the heatmap was wrong when used ResNet

When I used ResNet18~50 to instead the vgg networks๏ผŒthe program get NET RECEPTION{'n':7, 'j':32, 'r':11, 's':0.0, 'img_shape':(3,244,244)} , but get strong sense of grainines heatmaps. The parameters are obviously unreasonable๏ผŒhave you ever run into such a problem๏ผŸ

Disabling test phase after training is completed

Hello again, @liznerski !

I want to add an option that allows the user to disable the usage of testing data,
and only do training when training a custom dataset.

Is that even possible?
If it is, what are the places that I should be editing to be able to do so?

Thanks, once again!

Can we use ResNet for FCDD?

Hi. Thank you for sharing your excellent work with us.

I am replacing VGG with Resnet-18 for MVTec training. When the model runs, this error would occur:

File "fcdd/python/fcdd/models/bases.py", line 88, in receptive_upsample res = torch.nn.functional.conv_transpose2d( RuntimeError: negative output_padding is not supported

The output_padding calculated by the receptive_upsample is a negative value.

I have inherited the FCDDNet, and used _create_conv2d and _create_maxpool2d as replacement for torch.nn.Conv2d and torch.nn.MaxPool2d.

I wonder if ResNet can be considered as a valid type of FCDD? Much appreciation for your help!

Could we use Grad-CAM to get a heatmap?

hi, I'm a beginner, this question may be not professional๏ผŒbut it puzzles meใ€‚it seems that Grad-CAM can also get class heatmap, why not use it to visualize abnormal information?

How to start an inference test after completed training

How do i start an inference after i have completed the training?

I started training with mvtec ad dataset class 7 with:
$ python runners/run_single_mvtec.py --normal-class 7

Training works perfect but how can i make an inference from my own image of a screw after training is done?

What size should the inference image file be? Does it need to be resized before inference?

Can I run it on a cpu?

Hi,
I hope this is not a silly question, I am quite unexperienced on the field.
I'm trying to use the network on a laptop without any cuda GPUs, and it seems not to be working. Shouldn't it run on the cpu as well?

Change the OE dataset for training on custom data

While training the fcdd using run_custom.py I'm getting this error:

FileNotFoundError: [Errno 2] No such file or directory: '/home/OneClass/fcdd/data/datasets/imagenet22k/fall11_whole_extracted'

I guess for training on custom data, ImageNet22k is used as an OE dataset. I want to change this to ImageNet1k dataset. I have downloaded and placed the appropriate files in the datasets folder. @liznerski Could you please help me how to change the OE dataset to Imagenet1k?

Fixing seed to enable reproducibility of snapshot

Hi @liznerski,

It seems that when training twice with the same exact training parameters,
the resulting snapshots would differ from one another, resulting in different prediction results.

This may be due to random variables used during training.

Is there a way to set the random seed for training so that the snapshots would be the same?

Thank you for your time!

ModuleNotFoundError: No module named 'fcdd'

Hi, How to solve this problem please?

Traceback (most recent call last):
File "runners/run_mvtec.py", line 1, in
from fcdd.runners.bases import ClassesRunner
ModuleNotFoundError: No module named 'fcdd'

Error when running runners/run_mvtec.py

First of all thank you for your work, it's great๏ผBut I have some problems in the process of use, the following are the details๏ผš

platform๏ผšWindows 10 + Anaconda
I manually downloaded the mvtec_anomaly_detection.tar.xz, and then ran run_mvtec.py, the result was an error:

image

here is my datasets folder:

image

@liznerski

Editing required custom dataset structure

Hi!
Is it possible to use a different custom dataset structure by editing the program?

As far as I understand, the current required custom dataset structure is as below.

โ””โ”€โ”€ custom
    โ”œโ”€โ”€ test
    โ”‚   โ””โ”€โ”€ [class name]
    โ”‚         โ”œโ”€โ”€ anomalous
    โ”‚         โ”‚   โ””โ”€โ”€ img1.bmp, img2.bmp, ....
    โ”‚         โ””โ”€โ”€ normal
    โ”‚              โ””โ”€โ”€ img_NOK1.bmp, img_NOK2.bmp, ....
    โ””โ”€โ”€ train
        โ””โ”€โ”€ [class name]
              โ”œโ”€โ”€ anomalous
              โ”‚   โ””โ”€โ”€ train_img1.bmp, train_img2.bmp, ....
              โ””โ”€โ”€ normal
                   โ””โ”€โ”€ train_img_NOK1.bmp, train_img_NOK2.bmp, ....

I would like to modify the program so that it would accept a dataset structure like below.
Train and test dataset would not be in the same folder and both have the structure below.
Class is completely removed.

โ””โ”€โ”€ [arbitrary dataset name]
    โ”œโ”€โ”€ OK
    โ”‚   โ””โ”€โ”€ img1.bmp, img2.bmp, ....
    โ”‚       
    โ””โ”€โ”€ NOK
        โ””โ”€โ”€ img_NOK1.bmp, img_NOK2.bmp, ....

If this can be done, what are the places that I should be modifying?

Thank you very much for taking your time!

Can I use multi-gpu?

Hello.

First of all, thank you for your good thesis and code release.

I am writing because I have a question in the process of applying it to 'custom data'.

I have two 'GPU RTX-2080ti'.

When operating the model, is it possible to perform GPU parallel processing?

I'm asking because I looked at the code as a whole and judged that there was no parallel processing of the model.

If there is no 'GPU' parallel processing code, should I add the code myself?

I run to code my custom data , code error

  1. I use other custom image data but CUDA memory error.
    so, I use sample image data

  2. my custom data
    label : normal, Center, Donut, Edge-Loc, Edge-Ring, Loc, Near-full, Near-full, Scratch (total 9 label)
    Total image count : 172,950

  3. my goal

    1. Nine label multi-classification and explainable image using heatmap.
    2. I want to use multi-gpu
    3. I want to nominal-label : normal (I think maybe 'normal' number is 6th , ex) --nominal-label 6 )
      but nominal-label [0, 1].
  4. code error
    sudo python runners/run_custom.py --logdir /mnt/c/JSJ/FCDD_Wafer_0930_1st --datadir /mnt/c/JSJ/Wafer_denoising_data_split --objective fcdd -b 1 -e 1 --it 1 -d custom -n FCDD_CNN28 --preproc none --supervise-mode unsupervised --noise-mode cifar100 --nominal-label 0 -ovr
    normal_class : 0
    Plotting ROC for completed classes up to 0...
    Traceback (most recent call last):
    File "runners/run_custom.py", line 48, in
    runner.run()
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 203, in run
    self.run_classes(**vars(self.args))
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 221, in run_classes
    res = self.run_seeds(
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 181, in run_seeds
    res = self.run_one(
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 100, in run_one
    setup = trainer_setup(
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/training/setup.py", line 104, in trainer_setup
    ds = load_dataset(
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/datasets/init.py", line 67, in load_dataset
    dataset = ADImageFolderDataset(
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/datasets/image_folder.py", line 92, in init
    self.mean, self.std = self.extract_mean_std(self.trainpath, normal_class)
    File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/datasets/image_folder.py", line 193, in extract_mean_std
    for x, _ in loader:
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 652, in next
    data = self._next_data()
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 1347, in _next_data
    return self._process_data(data)
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 1373, in _process_data
    data.reraise()
    File "/home/psm/.local/lib/python3.8/site-packages/torch/_utils.py", line 461, in reraise
    raise exception
    RuntimeError: Caught RuntimeError in pin memory thread for device 0.
    Original Traceback (most recent call last):
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 34, in _pin_memory_loop
    data = pin_memory(data, device)
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 65, in pin_memory
    return type(data)([pin_memory(sample, device) for sample in data]) # type: ignore[call-arg]
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 65, in
    return type(data)([pin_memory(sample, device) for sample in data]) # type: ignore[call-arg]
    File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 50, in pin_memory
    return data.pin_memory(device)
    RuntimeError: CUDA error: out of memory
    CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
    For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

Exception in thread Thread-1:
Traceback (most recent call last):
Fatal Python error: could not acquire lock for <_io.BufferedWriter name=''> at interpreter shutdown, possibly due to daemon threads
Python runtime state: finalizing (tstate=0xe89e30)

Thread 0x00007f313cff9700 (most recent call first):
File "/usr/lib/python3.8/threading.py", line 1202 in invoke_excepthook
File "/usr/lib/python3.8/threading.py", line 934 in _bootstrap_inner
File "/usr/lib/python3.8/threading.py", line 890 in _bootstrap

Current thread 0x00007f31de32d740 (most recent call first):

[1] 9072 abort sudo python runners/run_custom.py --logdir /mnt/c/JSJ/FCDD_Wafer_0930_1st

or

sudo python runners/run_custom.py --logdir /mnt/c/JSJ/FCDD_Wafer_0930_1st --datadir /mnt/c/JSJ/Wafer_denoising_data_split --objective fcdd -b 1 -e 1 --it 1 -d custom -n FCDD_CNN224 --preproc none --supervise-mode noise --noise-mode cifar100 --nominal-label 0 -ovr
[sudo] password for psm:
normal_class : 0
Plotting ROC for completed classes up to 0...
Traceback (most recent call last):
File "runners/run_custom.py", line 48, in
runner.run()
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 203, in run
self.run_classes(**vars(self.args))
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 221, in run_classes
res = self.run_seeds(
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 181, in run_seeds
res = self.run_one(
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/runners/bases.py", line 100, in run_one
setup = trainer_setup(
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/training/setup.py", line 104, in trainer_setup
ds = load_dataset(
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/datasets/init.py", line 67, in load_dataset
dataset = ADImageFolderDataset(
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/datasets/image_folder.py", line 92, in init
self.mean, self.std = self.extract_mean_std(self.trainpath, normal_class)
File "/usr/local/lib/python3.8/dist-packages/fcdd-1.1.0-py3.8.egg/fcdd/datasets/image_folder.py", line 193, in extract_mean_std
for x, _ in loader:
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 652, in next
data = self._next_data()
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 1347, in _next_data
return self._process_data(data)
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 1373, in _process_data
data.reraise()
File "/home/psm/.local/lib/python3.8/site-packages/torch/_utils.py", line 461, in reraise
raise exception
RuntimeError: Caught RuntimeError in pin memory thread for device 0.
Original Traceback (most recent call last):
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 34, in _pin_memory_loop
data = pin_memory(data, device)
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 65, in pin_memory
return type(data)([pin_memory(sample, device) for sample in data]) # type: ignore[call-arg]
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 65, in
return type(data)([pin_memory(sample, device) for sample in data]) # type: ignore[call-arg]
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 50, in pin_memory
return data.pin_memory(device)
RuntimeError: CUDA error: out of memory
CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/home/psm/.local/lib/python3.8/site-packages/torch/utils/data/_utils/pin_memory.py", line 28, in _pin_memory_loop
r = in_queue.get(timeout=MP_STATUS_CHECK_INTERVAL)
File "/usr/lib/python3.8/multiprocessing/queues.py", line 116, in get
return _ForkingPickler.loads(res)
File "/home/psm/.local/lib/python3.8/site-packages/torch/multiprocessing/reductions.py", line 297, in rebuild_storage_fd
fd = df.detach()
File "/usr/lib/python3.8/multiprocessing/resource_sharer.py", line 57, in detach
with _resource_sharer.get_connection(self._id) as conn:
File "/usr/lib/python3.8/multiprocessing/resource_sharer.py", line 87, in get_connection
c = Client(address, authkey=process.current_process().authkey)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
ConnectionRefusedError: [Errno 111] Connection refused

Multiple classes with one-vs-rest training raises AttributeError

I have a dataset that is organised as follows:

Train images:
custom/train/class0/
custom/train/class1/
custom/train/class2/

Train maps:
custom/train_maps/class0/
custom/train_maps/class1/
custom/train_maps/class2/

Test images:
custom/test/class0/
custom/test/class1/
custom/test/class2/

Test maps:
custom/test_maps/class0/
custom/test_maps/class1/
custom/test_maps/class2/

I use the following command for training the model:
python runners/run_custom.py --supervise-mode other --blur-heatmaps -gtms -ovr
It starts training the model for 200 epochs, and creates a folder normal_0 with it_0 in it. It generates an error as follows:

EPOCH 199 NBAT 0000/0005 ERR 1.343491 ERR_NORMAL 2.115482 ERR_ANOMALOUS 0.550352 INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
Test training data...
TEST 0000/0005 ID fcdd.training.fcdd.FCDDTrainer
Test test data...
TEST 0000/0002 ID fcdd.training.fcdd.FCDDTrainer NCLS (0,)
Computing test score...
##### ROC TEST SCORE 0.019260400616332822 #####
Computing GT test score...
Plotting ROC for completed classes up to 0...
Traceback (most recent call last):
  File "runners/run_custom.py", line 48, in <module>
    runner.run()
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\runners\bases.py", line 203, in run
    self.run_classes(**vars(self.args))
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\runners\bases.py", line 221, in run_classes
    res = self.run_seeds(
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\runners\bases.py", line 181, in run_seeds
    res = self.run_one(
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\runners\bases.py", line 107, in run_one
    x = trainer.test(viz_ids)
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\training\super_trainer.py", line 94, in test
    res = self.trainer.test(specific_viz_ids)
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\training\bases.py", line 264, in test
    sc = self.score(labels, anomaly_scores, imgs, outputs, gtmaps, grads)
  File "C:\Users\laydas\AppData\Roaming\Python\Python38\site-packages\fcdd\training\bases.py", line 377, in score
    gtmaps = self.test_loader.dataset.dataset.get_original_gtmaps_normal_class()
AttributeError: 'ImageFolderDatasetGTM' object has no attribute 'dataset'

I am not sure why this errors occurs - is there a problem with the command, or the dataset organisation? Thank you in advance for your help and suggestions.

Issue with running on custom dataset with --supervise_mode == unsupervised

Hi, thank you so much for the well organized and documented codebase.

I am trying to run your code on a custom dataset and setting the supervise_mode to unsupervised. However, the code seems to get stuck on Generating dataset preview.... Any idea why? When I run the same code with supervise_mode parameter set to malformed_normal, it works fine.

Thank you!

Edit: I found the reason. In datasets\bases.py file, the preview function keeps loading in training data until we have a certain amount of abnormal and normal images. For unsupervised setting, there will not be abnormal images, hence the loop keeps going. I changed that portion of the code and it works now. ;)

Error on custom dataset training

I followed the instruction giude and tried to train a custom dataset.
Dataset is as follows:
fcdd\data\datasets\custom\train\dashboard\normal
fcdd\data\datasets\custom\test\dashboard\normal
fcdd\data\datasets\custom\test\dashboard\anomalous

The error i get is
`python runners/run_custom.py

Plotting ROC for completed classes up to 0...
Traceback (most recent call last):
File ".\fcdd\python\fcdd\runners\run_custom.py", line 49, in
runner.run()
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\runners\bases.py", line 203, in run
self.run_classes(**vars(self.args))
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\runners\bases.py", line 221, in run_classes
res = self.run_seeds(
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\runners\bases.py", line 181, in run_seeds
res = self.run_one(
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\runners\bases.py", line 100, in run_one
setup = trainer_setup(
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\training\setup.py", line 104, in trainer_setup
ds = load_dataset(
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\datasets_init_.py", line 67, in load_dataset
dataset = ADImageFolderDataset(
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\datasets\image_folder.py", line 95, in init
self.mean, self.std = self.extract_mean_std(self.trainpath, normal_class)
File "...\Anaconda3\lib\site-packages\fcdd-1.1.0-py3.9.egg\fcdd\datasets\image_folder.py", line 194, in extract_mean_std
for x, _ in loader:
File "...\Anaconda3\lib\site-packages\torch\utils\data\dataloader.py", line 359, in iter
return self._get_iterator()
File "...\Anaconda3\lib\site-packages\torch\utils\data\dataloader.py", line 305, in _get_iterator
return _MultiProcessingDataLoaderIter(self)
File "...\Anaconda3\lib\site-packages\torch\utils\data\dataloader.py", line 918, in init
w.start()
File "...\Anaconda3\lib\multiprocessing\process.py", line 121, in start
self._popen = self._Popen(self)
File "...\Anaconda3\lib\multiprocessing\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "...\Anaconda3\lib\multiprocessing\context.py", line 327, in _Popen
return Popen(process_obj)
File "...\Anaconda3\lib\multiprocessing\popen_spawn_win32.py", line 93, in init
reduction.dump(process_obj, to_child)
File "...\Anaconda3\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'ADImageFolderDataset.extract_mean_std..'

$ Traceback (most recent call last):
File "", line 1, in
File "...\Anaconda3\lib\multiprocessing\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "...\Anaconda3\lib\multiprocessing\spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
`

Training on new custom dataset

Hello! Thank you for the code.

I am trying to train the model on my own custom dataset (folder of images). But it's a bit hard to do so. I tried to follow this:

`
Create a new python script in the datasets package. Implement a dataset that inherits the fcdd.datasets.bases.TorchvisionDataset class. Your implementation needs to process all parameters of the fcdd.datasets.bases.load_dataset function in its initialization. You can use the preproc parameter to switch between different data preprocessing pipelines (augmentation, etc). In the end, your implementation needs to have at least all attributes defined in fcdd.datasets.bases.BaseADDataset class. Most importantly, the _train_set attribute and the _test_set attribute containing the corresponding torchvision-style datasets. Have a look at the already available implementations.

Add a name for your dataset to the fcdd.datasets.init.DS_CHOICES variable. Add your dataset to the "switch-case" in the fcdd.datasets.init.load_dataset function. Add the number of available class for your dataset to the fcdd.datasets.init.no_classes function and add the class names to fcdd.datasets.init.str_labels.

`

But I am finding it hard to do. I cant see where shall I put the images folder exactly and how to prepare those scripts.
Can anyone help?

How to set run_custom parameters?

I run run_custom.py, I set dataset by this way:
dataSet
In test file , it is include normal and annormal file, as mtevc datset structure.

then๏ผŒI set parameters by this way:

parser.set_defaults(
batch_size=16 , acc_batches = 8, supervise_mode='unsupervised',preproc='aug1',
gauss_std=12, epochs=500, weight_decay=1e-4,
quantile=0.99, net='FCDD_CNN224_VGG_F', dataset='custom', noise_mode='confetti'
)
other parameters set default.

when I trained finished , the heatmap seems is not correct .
the heatmap_paper_local_lbl1.png
image

the heatmap_paper_local_lbl0.png
image

the heatmaps_paper_global_lbl1.png
image

the heatmaps_paper_global_lbl0.png
image

the train_heatmaps_global.png
image

the heatmap_global.png
image

I am not clear that which parameters lead to this result. Looking forward your replying. If you have time to write a detail Markdown about how to run run_custom.py, Thank you very much.

"AssertionError: binary labels required" when unsupervised training of MVTec AD Dataset

๐Ÿ›Bug

  • Training the model using MVTec AD dataset without any Outlier Exposure seems to cause an error "AssertionError: binary labels required"

Traceback

The input command is as below:
python ./fcdd/runners/run_mvtec.py --supervise-mode unsupervised

......
EPOCH 1991 NBAT 0007/0014 ERR 0.000805  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1992 NBAT 0007/0014 ERR 0.000803  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1993 NBAT 0007/0014 ERR 0.000802  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1994 NBAT 0007/0014 ERR 0.000803  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1995 NBAT 0007/0014 ERR 0.000802  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1996 NBAT 0007/0014 ERR 0.000800  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1997 NBAT 0007/0014 ERR 0.000801  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1998 NBAT 0007/0014 ERR 0.000801  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
EPOCH 1999 NBAT 0007/0014 ERR 0.000800  INFO LR ['5e-05'] ID fcdd.training.fcdd.FCDDTrainer
Test training data...
TEST 0000/0014 ID fcdd.training.fcdd.FCDDTrainer
TEST 0007/0014 ID fcdd.training.fcdd.FCDDTrainer
Plotting Many ROC for completed classes up to 0...
Traceback (most recent call last):
  File "./fcdd/runners/run_mvtec.py", line 19, in <module>
    runner.run()
  File "/usr/local/lib/python3.6/dist-packages/fcdd/runners/bases.py", line 203, in run
    self.run_classes(**vars(self.args))
  File "/usr/local/lib/python3.6/dist-packages/fcdd/runners/bases.py", line 222, in run_classes
    it, **kwargs
  File "/usr/local/lib/python3.6/dist-packages/fcdd/runners/bases.py", line 182, in run_seeds
    this_viz_ids, **kwargs
  File "/usr/local/lib/python3.6/dist-packages/fcdd/runners/bases.py", line 107, in run_one
    x = trainer.test(viz_ids)
  File "/usr/local/lib/python3.6/dist-packages/fcdd/training/super_trainer.py", line 94, in test
    res = self.trainer.test(specific_viz_ids)
  File "/usr/local/lib/python3.6/dist-packages/fcdd/training/bases.py", line 244, in test
    name='train_heatmaps',
  File "/usr/local/lib/python3.6/dist-packages/fcdd/training/bases.py", line 414, in heatmap_generation
    idx, name, imgs.shape, subdir, show_per_cls, imgs, ascores, grads, gtmaps, labels
  File "/usr/local/lib/python3.6/dist-packages/fcdd/training/bases.py", line 486, in _create_heatmaps_picture
    colorize=True, ref=balance_labels(ascores, labels, err) if norm == 'global' else ascores[idx],
  File "/usr/local/lib/python3.6/dist-packages/fcdd/training/__init__.py", line 13, in balance_labels
    assert len(lblset) == 2, 'binary labels required'
AssertionError: binary labels required

Expected Behaviour

Was expecting for it run test phase without any problem

Environment

Environment: Google Colab

PyTorch version: 1.4.0
Is debug build: No
CUDA used to build PyTorch: 10.1

OS: Ubuntu 18.04.5 LTS
GCC version: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
CMake version: version 3.12.0

Python version: 3.6
Is CUDA available: Yes
CUDA runtime version: 10.1.243
GPU models and configuration: GPU 0: Tesla T4
Nvidia driver version: 460.32.03
cuDNN version: /usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5

Versions of relevant libraries:
[pip3] numpy==1.18.1
[pip3] torch==1.4.0
[pip3] torchsummary==1.5.1
[pip3] torchtext==0.3.1
[pip3] torchvision==0.5.0
[conda] Could not collect

Additional Context

I'm using linux this time, but it seems that the ram wasn't enough during the multiprocessing phase, where datas are sampled 10 times. I then turned off 'enlarge' and switched the epochs to 2000.

Thanks once again for taking your time!

Error while execution MVTEC runner

Greetings!
First of all, I would like to thank you for sharing this project. It was a pleasure to study the main paper.
I would like to ask for some help in solving the problems related to running the code.
The first problem occurred after running the command
pip install .

It failed to install the required version of pprofile. By modifying the requirements.txt for pprofile from version pprofile==2.0.5 to pprofile==2.1, the problem was solved.
The Fashion MNIST and CIFAR runners seem to be working correctly. However, MVTec-AD, unfortunately, does not start. Any idea what I could be doing wrong? is it possible that this error was a consequence of changing the version of the pprofile?

Thanks for patience.

I use Ubuntu 20.04, virtualenv

LOG:

/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/torchvision/transforms/transforms.py:280: UserWarning: Argument interpolation should be of type InterpolationMode instead of int. Please, use InterpolationMode enum.
  warnings.warn(
Downloading ftp://guest:GU%[email protected]/mvtec_anomaly_detection/mvtec_anomaly_detection.tar.xz to /home/dima/cham/fcdd/data/datasets/mvtec/mvtec_anomaly_detection.tar.xz
0it [00:00, ?it/s]Plotting ROC for completed classes up to 0...
Traceback (most recent call last):
  File "/usr/lib/python3.8/urllib/request.py", line 1571, in ftp_open
    fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
  File "/usr/lib/python3.8/urllib/request.py", line 1592, in connect_ftp
    return ftpwrapper(user, passwd, host, port, dirs, timeout,
  File "/usr/lib/python3.8/urllib/request.py", line 2413, in __init__
    self.init()
  File "/usr/lib/python3.8/urllib/request.py", line 2423, in init
    self.ftp.login(self.user, self.passwd)
  File "/usr/lib/python3.8/ftplib.py", line 410, in login
    resp = self.sendcmd('PASS ' + passwd)
  File "/usr/lib/python3.8/ftplib.py", line 277, in sendcmd
    return self.getresp()
  File "/usr/lib/python3.8/ftplib.py", line 250, in getresp
    raise error_perm(resp)
ftplib.error_perm: 530 Login incorrect.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "runners/run_mvtec.py", line 19, in <module>
    runner.run()
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/runners/bases.py", line 203, in run
    self.run_classes(**vars(self.args))
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/runners/bases.py", line 221, in run_classes
    res = self.run_seeds(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/runners/bases.py", line 181, in run_seeds
    res = self.run_one(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/runners/bases.py", line 100, in run_one
    setup = trainer_setup(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/training/setup.py", line 104, in trainer_setup
    ds = load_dataset(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/__init__.py", line 42, in load_dataset
    dataset = ADMvTec(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/mvtec.py", line 214, in __init__
    train_set = MvTec(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/mvtec_base.py", line 78, in __init__
    self.download(shape=self.shape[1:])
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/mvtec_base.py", line 148, in download
    self.download_and_extract_archive(
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/mvtec_base.py", line 266, in download_and_extract_archive
    MvTec.download_url(url, download_root, filename)
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/mvtec_base.py", line 315, in download_url
    raise e
  File "/home/dima/cham/fcdd/python/venv/lib/python3.8/site-packages/fcdd/datasets/mvtec_base.py", line 304, in download_url
    urllib.request.urlretrieve(url, fpath, reporthook=gen_bar_updater())
  File "/usr/lib/python3.8/urllib/request.py", line 247, in urlretrieve
    with contextlib.closing(urlopen(url, data)) as fp:
  File "/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.8/urllib/request.py", line 525, in open
    response = self._open(req, data)
  File "/usr/lib/python3.8/urllib/request.py", line 542, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.8/urllib/request.py", line 1589, in ftp_open
    raise exc.with_traceback(sys.exc_info()[2])
  File "/usr/lib/python3.8/urllib/request.py", line 1571, in ftp_open
    fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
  File "/usr/lib/python3.8/urllib/request.py", line 1592, in connect_ftp
    return ftpwrapper(user, passwd, host, port, dirs, timeout,
  File "/usr/lib/python3.8/urllib/request.py", line 2413, in __init__
    self.init()
  File "/usr/lib/python3.8/urllib/request.py", line 2423, in init
    self.ftp.login(self.user, self.passwd)
  File "/usr/lib/python3.8/ftplib.py", line 410, in login
    resp = self.sendcmd('PASS ' + passwd)
  File "/usr/lib/python3.8/ftplib.py", line 277, in sendcmd
    return self.getresp()
  File "/usr/lib/python3.8/ftplib.py", line 250, in getresp
    raise error_perm(resp)
urllib.error.URLError: <urlopen error ftp error: error_perm('530 Login incorrect.')>
0it [00:00, ?it/s]```

Image level AUC-ROC for MV-Tech dataset

Dear Liznerski,
I am unable to find information about image-level AUC-ROC in your work.
Do you have any reliable information on this?

Thank you in advance

"RuntimeError: Trying to resize storage that is not resizable at .." when executing "python runners/run_mvtec.py"

๐Ÿ›Bug

  • Executing "python runners/run_mvtec.py" in windows seems to cause "RuntimeError: Trying to resize storage that is not resizable at ..".
  • Used windows branch program.

Traceback

(Fcdd_Env) C:\Users\PC-2001-044\Desktop\fcdd-windows\fcdd-windows\python>python fcdd/runners/run_mvtec.py
Downloading ftp://guest:GU%[email protected]/mvtec_anomaly_detection/mvtec_anomaly_detection.tar.xz to C:\Users\PC-2001-044\Desktop\fcdd-windows\data\datasets\mvtec\mvtec_anomaly_detection.tar.xz
100.0%Extracting C:\Users\PC-2001-044\Desktop\fcdd-windows\data\datasets\mvtec\mvtec_anomaly_detection.tar.xz to C:\Users\PC-200~1\AppData\Local\Temp\tmpvdfnxt5a
Processing data for label bottle...
Processing data for label cable...
Processing data for label capsule...
Processing data for label carpet...
Processing data for label grid...
Processing data for label hazelnut...
Processing data for label leather...
Processing data for label metal_nut...
Processing data for label pill...
Processing data for label screw...
Processing data for label tile...
Processing data for label toothbrush...
Processing data for label transistor...
Processing data for label wood...
Processing data for label zipper...
Loading dataset from C:\Users\PC-2001-044\Desktop\fcdd-windows\data\datasets\mvtec\admvtec_240x240.pt...
Dataset complete.
Files already downloaded.
Loading dataset from C:\Users\PC-2001-044\Desktop\fcdd-windows\data\datasets\mvtec\admvtec_240x240.pt...
Dataset complete.
Downloading: "https://download.pytorch.org/models/vgg11_bn-6002323d.pth" to C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\models\..\..\..\data\models\vgg11_bn-6002323d.pth
100.0%
##### NET RECEPTION {'n': 28, 'j': 8, 'r': 62, 's': 3.5, 'img_shape': (3, 224, 224)} #####
Successfully saved code at C:\Users\PC-2001-044\Desktop\fcdd-windows\data\results\fcdd_20210206091247_mvtec_\normal_0\it_0\.\src.tar.gz
Generating dataset preview...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\multiprocessing\spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\multiprocessing\reductions.py", line 90, in rebuild_tensor
    t = torch._utils._rebuild_tensor(storage, storage_offset, size, stride)
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\_utils.py", line 131, in _rebuild_tensor
    return t.set_(storage, storage_offset, size, stride)
RuntimeError: Trying to resize storage that is not resizable at ..\aten\src\TH\THStorageFunctions.cpp:88
Plotting Many ROC for completed classes up to 0...
Traceback (most recent call last):
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\utils\data\dataloader.py", line 761, in _try_get_data
    data = self._data_queue.get(timeout=timeout)
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\queue.py", line 178, in get
    raise Empty
_queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "fcdd/runners/run_mvtec.py", line 19, in <module>
    runner.run()
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\runners\bases.py", line 203, in run
    self.run_classes(**vars(self.args))
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\runners\bases.py", line 221, in run_classes
    res = self.run_seeds(
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\runners\bases.py", line 181, in run_seeds
    res = self.run_one(
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\runners\bases.py", line 100, in run_one
    setup = trainer_setup(
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\training\setup.py", line 122, in trainer_setup
    'ds_preview', ds.preview(20), nrow=20,
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\fcdd\datasets\bases.py", line 94, in preview
    for xb, yb, gtsb in loader:
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\utils\data\dataloader.py", line 345, in __next__
    data = self._next_data()
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\utils\data\dataloader.py", line 841, in _next_data
    idx, data = self._get_data()
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\utils\data\dataloader.py", line 798, in _get_data
    success, data = self._try_get_data()
  File "C:\Users\PC-2001-044\anaconda3\envs\Fcdd_Env\lib\site-packages\torch\utils\data\dataloader.py", line 774, in _try_get_data
    raise RuntimeError('DataLoader worker (pid(s) {}) exited unexpectedly'.format(pids_str))
RuntimeError: DataLoader worker (pid(s) 13204) exited unexpectedly

Expected Behaviour

Was expecting for it to sample the MVTec Dataset without any problems

Environment

PyTorch Version: 1.4.0
Is Cuda Available?: Yes

OS: Windows 10 Pro

Python version: 3.8

CUDA runtime version: 10.2.141
GPU models and configuration: GPU 0: NVIDIA Quadro P1000
Nvidia driver version: 442.50

Additional Context

Thank you very much for taking time in assessing this issue :)

Edit

Sorry, i forgot to mention, i had problems with installing pytorch for the environment, then i went to install it by [direct linking](https://stackoverflow.com/a/60141990) to the builds
(Fcdd_Env) C:\Users\PC-2001-044\Desktop\fcdd-windows\fcdd-windows\python>pip install .
Processing c:\users\pc-2001-044\desktop\fcdd-windows\fcdd-windows\python
Requirement already satisfied: matplotlib==3.1.3 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (3.1.3)
Requirement already satisfied: torchvision==0.5.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (0.5.0)
ERROR: Could not find a version that satisfies the requirement torch==1.4.0 (from fcdd)
ERROR: No matching distribution found for torch==1.4.0

(Fcdd_Env) C:\Users\PC-2001-044\Desktop\fcdd-windows\fcdd-windows\python>pip install https://download.pytorch.org/whl/cu101/torch-1.4.0-cp38-cp38-win_amd64.whl
Collecting torch==1.4.0
  Using cached https://download.pytorch.org/whl/cu101/torch-1.4.0-cp38-cp38-win_amd64.whl (796.9 MB)
Installing collected packages: torch
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
torchvision 0.5.0 requires numpy, which is not installed.
Successfully installed torch-1.4.0

(Fcdd_Env) C:\Users\PC-2001-044\Desktop\fcdd-windows\fcdd-windows\python>pip install .
Processing c:\users\pc-2001-044\desktop\fcdd-windows\fcdd-windows\python
Requirement already satisfied: matplotlib==3.1.3 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (3.1.3)
Requirement already satisfied: torchvision==0.5.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (0.5.0)
Requirement already satisfied: torch==1.4.0 in c:\users\pc-2001-044\anaconda3\envs\fcdd_env\lib\site-packages (from fcdd==0.6.1) (1.4.0)
Requirement already satisfied: opencv-python==4.2.0.32 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (4.2.0.32)
Requirement already satisfied: six==1.14.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (1.14.0)
Requirement already satisfied: scipy==1.4.1 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (1.4.1)
Requirement already satisfied: scikit-image==0.16.2 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (0.16.2)
Requirement already satisfied: scikit-learn==0.22.1 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (0.22.1)
Requirement already satisfied: Pillow==7.0.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (7.0.0)
Requirement already satisfied: pprofile==2.0.2 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (2.0.2)
Requirement already satisfied: psutil==5.7.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (5.7.0)
Requirement already satisfied: pyparsing==2.4.6 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (2.4.6)
Requirement already satisfied: networkx==2.4 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (2.4)
Requirement already satisfied: imageio==2.6.1 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (2.6.1)
Requirement already satisfied: joblib==0.14.1 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (0.14.1)
Requirement already satisfied: kiwisolver==1.1.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (1.1.0)
Requirement already satisfied: kornia==0.2.0 in c:\users\pc-2001-044\appdata\roaming\python\python38\site-packages (from fcdd==0.6.1) (0.2.0)
Requirement already satisfied: setuptools in c:\users\pc-2001-044\anaconda3\envs\fcdd_env\lib\site-packages (from kiwisolver==1.1.0->fcdd==0.6.1) (52.0.0.post20210125)
Collecting numpy==1.18.1
  Using cached numpy-1.18.1-cp38-cp38-win_amd64.whl (12.8 MB)
Collecting python-dateutil==2.8.1
  Using cached python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting PyWavelets==1.1.1
  Downloading PyWavelets-1.1.1-cp38-cp38-win_amd64.whl (4.3 MB)
     |โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 4.3 MB 3.3 MB/s
Collecting cycler>=0.10
  Using cached cycler-0.10.0-py2.py3-none-any.whl (6.5 kB)
Collecting decorator>=4.3.0
  Using cached decorator-4.4.2-py2.py3-none-any.whl (9.2 kB)
Building wheels for collected packages: fcdd
  Building wheel for fcdd (setup.py) ... done
  Created wheel for fcdd: filename=fcdd-0.6.1-py3-none-any.whl size=116241 sha256=c46c3f9294caaf6e171a8456c35860ebc8a09c572fdb9e2be9d880e7f3c787c1
  Stored in directory: C:\Users\PC-2001-044\AppData\Local\Temp\pip-ephem-wheel-cache-tmdctf0b\wheels\ac\7e\35\c763dfdc3e2ef819fad43e7ad60cedb088e9f8f8ec8e0d4b13
Successfully built fcdd
Installing collected packages: python-dateutil, numpy, decorator, cycler, PyWavelets, fcdd
Successfully installed PyWavelets-1.1.1 cycler-0.10.0 decorator-4.4.2 fcdd-0.6.1 numpy-1.18.1 python-dateutil-2.8.1

Enlarging dataset option for custom datasets

I was wondering if there is an enlarging option for custom datasets for
users to try, such as the one used for MVTec dataset.

I'm currently training by setting the epoch to 2000
and also using the same training parameters used for MVTec dataset
to get the same performance, but it sure takes some time.

Thank you for taking your time!

Installing and running with CUDA in Windows 10 raises Pickle error

I am working on a computer with Windows 10 with one GPU. I have the following situation:

  • I install using the command pip install . --user from the python directory.
  • Then I use the command python runners/run_mvtec.py from the fcdd directory that appears after installation. This causes an error with CUDA:
Traceback (most recent call last):
  File "C:\Work\IMAGE\New folder\ADProject1\fcdd-master\python\fcdd\runners\run_mvtec.py", line 19, in <module>
    runner.run()
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\fcdd\runners\bases.py", line 203, in run
    self.run_classes(**vars(self.args))
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\fcdd\runners\bases.py", line 221, in run_classes
    res = self.run_seeds(
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\fcdd\runners\bases.py", line 181, in run_seeds
    res = self.run_one(
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\fcdd\runners\bases.py", line 100, in run_one
    setup = trainer_setup(
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\fcdd\training\setup.py", line 113, in trainer_setup
    net = net.to(device)
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\torch\nn\modules\module.py", line 852, in to
    return self._apply(convert)
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\torch\nn\modules\module.py", line 530, in _apply
    module._apply(fn)
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\torch\nn\modules\module.py", line 530, in _apply
    module._apply(fn)
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\torch\nn\modules\module.py", line 552, in _apply
    param_applied = fn(param)
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\torch\nn\modules\module.py", line 850, in convert
    return t.to(device, dtype if t.is_floating_point() or t.is_complex() else None, non_blocking)
  File "C:\Users\laydas\AppData\Roaming\Python\Python39\site-packages\torch\cuda\__init__.py", line 166, in _lazy_init
    raise AssertionError("Torch not compiled with CUDA enabled")
AssertionError: Torch not compiled with CUDA enabled
  • To correct this situation, I install the latest PyTorch.
  • I then execute python runners/run_mvtec.py from the fcdd folder. Now this causes an error associated with a pickle command of a Lambda function.

Here is the complete output after executing python runners/run_mvtec.py:

Files already downloaded.
Loading dataset from C:\Work\IMAGE\New folder\ADProject\fcdd_master\python\data\datasets\mvtec\admvtec_240x240.pt...
Dataset complete.
Files already downloaded.
Loading dataset from C:\Work\IMAGE\New folder\ADProject\fcdd_master\python\data\datasets\mvtec\admvtec_240x240.pt...
Dataset complete.
Downloading: "https://download.pytorch.org/models/vgg11_bn-6002323d.pth" to C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\models\..\..\..\data\models\vgg11_bn-6002323d.pth
100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 507M/507M [00:17<00:00, 30.0MB/s]
##### NET RECEPTION {'n': 28, 'j': 8, 'r': 62, 's': 3.5, 'img_shape': (3, 224, 224)} #####
Successfully saved code at C:\Work\IMAGE\New folder\ADProject\fcdd_master\python\data\results\fcdd_20221025165156_mvtec_\normal_0\it_0\.\src.tar.gz
Generating dataset preview...
Plotting ROC for completed classes up to 0...
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm 2021.3.2\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Work/IMAGE/New folder/ADProject/fcdd_master/python/fcdd/runners/run_mvtec.py", line 19, in <module>
    runner.run()
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\runners\bases.py", line 203, in run
    self.run_classes(**vars(self.args))
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\runners\bases.py", line 221, in run_classes
    res = self.run_seeds(
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\runners\bases.py", line 181, in run_seeds
    res = self.run_one(
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\runners\bases.py", line 100, in run_one
    setup = trainer_setup(
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\training\setup.py", line 122, in trainer_setup
    images = ds.preview(20, classes=[0, 1] if supervise_mode != "unsupervised" else [0], train=True)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\fcdd\datasets\bases.py", line 99, in preview
    for xb, yb, gtsb in loader:
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\torch\utils\data\dataloader.py", line 444, in __iter__
    return self._get_iterator()
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\torch\utils\data\dataloader.py", line 390, in _get_iterator
    return _MultiProcessingDataLoaderIter(self)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\site-packages\torch\utils\data\dataloader.py", line 1077, in __init__
    w.start()
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'ADMvTec.__init__.<locals>.<lambda>'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\ProgramData\Anaconda3\envs\ADProject\lib\multiprocessing\spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

I am not able to figure out a solution to this problem. Can you please let me know how to correct/prevent this problem?
Thank you very much for your help in advance.

Error running custom.py using semi-supervised mode with multiple classes

Hi liznerski, thanks for the great work!

I'm trying to train a custom dataset (with 5 classes) with the semi-supervised mode where i provide the ground truth maps for both train and test sets. I have been facing an error that says there are inconsistent number of samples.
I structured my dataset according to this format:
image

The error i got:
image

I printed their shapes to understand the error:
image

I believe the error is due to the 'gtmaps' taking the total number of test samples from all 5 classes (172 normal + 174 anomalous) while the 'ascores' is only getting the test samples of the first class (30 normal + 72 anomalous). When i tried training only 1 class, the training completed successfully without any errors.

I assume the 'fcdd.datasets.image_folder_gtms.ImageFolderDatasetGTM.get_original_gtmaps_normal_class' is the root cause of this error. Any suggestions on how to fix this?
Thanks in advance.

"OsError: Can't get source code <function>" when Packaging FCDD using PyInstaller

After packaging FCDD using PyInstaller, a bug within torch seems
to prevent the packaged program to run smoothly.
I was able to solve this, and I hope this can be solved within FCDD.

Details

After packaging FCDD and running the exe file, I got an exception and traceback as below.

image

It turns out there's a bug within torchvision.
More on this bug can be found here.
FCDD uses the Kornia library, which in turn uses torch.jit.script (at kornia\ jit\init.py), which causes the problem to occur.

Replacing jit.script with jit._script_if_tracing as below seems to solve it.

import torch
import kornia as K

#ORIGINAL
# # expose functions to torch.jit
# # TODO: find an automatic way to do this
# rgb_to_grayscale = torch.jit.script(K.color.rgb_to_grayscale)
# bgr_to_grayscale = torch.jit.script(K.color.bgr_to_grayscale)
#
# spatial_soft_argmax2d = torch.jit.script(K.geometry.spatial_soft_argmax2d)
# spatial_softmax2d = torch.jit.script(K.geometry.dsnt.spatial_softmax2d)
# spatial_expectation2d = torch.jit.script(K.geometry.dsnt.spatial_expectation2d)
# render_gaussian2d = torch.jit.script(K.geometry.dsnt.render_gaussian2d)
# warp_perspective = torch.jit.script(K.geometry.warp_perspective)

# monkey patch
bgr_to_grayscale = torch.jit._script_if_tracing(K.color.bgr_to_grayscale)
rgb_to_grayscale = torch.jit._script_if_tracing(K.color.rgb_to_grayscale)

spatial_soft_argmax2d = torch.jit._script_if_tracing(K.geometry.spatial_soft_argmax2d)
spatial_softmax2d = torch.jit._script_if_tracing(K.geometry.dsnt.spatial_softmax2d)
spatial_expectation2d = torch.jit._script_if_tracing(K.geometry.dsnt.spatial_expectation2d)
render_gaussian2d = torch.jit._script_if_tracing(K.geometry.dsnt.render_gaussian2d)
warp_perspective = torch.jit._script_if_tracing(K.geometry.warp_perspective)

I hope this can be a reference for others!

Training on grayscale images

The code only accept RGB input data for the training and when I tried to feed grayscale images to the model it failed. Any idea how to modify the code to accept grayscale images

pip install fcdd

I want to install fcdd on Windows 10, when I use pip install fcdd, there is an error:

(venv) D:\python38\venv\Scripts>pip install fcdd
ERROR: Could not find a version that satisfies the requirement fcdd (from versions: none)
ERROR: No matching distribution found for fcdd

How can I solve this problem? Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.