oodeel 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of oodeel might be problematic. Click here for more details.

Files changed (62) hide show
  1. {oodeel-0.2.0 → oodeel-0.3.0}/PKG-INFO +144 -18
  2. {oodeel-0.2.0 → oodeel-0.3.0}/README.md +27 -15
  3. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/__init__.py +1 -1
  4. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/datasets/__init__.py +2 -1
  5. oodeel-0.3.0/oodeel/datasets/data_handler.py +304 -0
  6. oodeel-0.2.0/oodeel/datasets/data_handler.py → oodeel-0.3.0/oodeel/datasets/deprecated/DEPRECATED_data_handler.py +6 -6
  7. oodeel-0.2.0/oodeel/datasets/ooddataset.py → oodeel-0.3.0/oodeel/datasets/deprecated/DEPRECATED_ooddataset.py +14 -13
  8. oodeel-0.2.0/oodeel/datasets/tf_data_handler.py → oodeel-0.3.0/oodeel/datasets/deprecated/DEPRECATED_tf_data_handler.py +7 -7
  9. oodeel-0.2.0/oodeel/datasets/torch_data_handler.py → oodeel-0.3.0/oodeel/datasets/deprecated/DEPRECATED_torch_data_handler.py +12 -9
  10. oodeel-0.3.0/oodeel/datasets/deprecated/__init__.py +31 -0
  11. oodeel-0.3.0/oodeel/datasets/tf_data_handler.py +609 -0
  12. oodeel-0.3.0/oodeel/datasets/torch_data_handler.py +694 -0
  13. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/eval/metrics.py +7 -2
  14. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/extractor/feature_extractor.py +11 -0
  15. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/extractor/keras_feature_extractor.py +51 -1
  16. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/extractor/torch_feature_extractor.py +103 -21
  17. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/__init__.py +16 -1
  18. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/base.py +72 -15
  19. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/dknn.py +20 -7
  20. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/energy.py +8 -0
  21. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/entropy.py +8 -0
  22. oodeel-0.3.0/oodeel/methods/gen.py +118 -0
  23. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/gram.py +15 -4
  24. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/mahalanobis.py +9 -7
  25. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/mls.py +8 -0
  26. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/odin.py +8 -0
  27. oodeel-0.3.0/oodeel/methods/rmds.py +122 -0
  28. oodeel-0.3.0/oodeel/methods/she.py +197 -0
  29. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/methods/vim.py +1 -1
  30. oodeel-0.3.0/oodeel/preprocess/__init__.py +31 -0
  31. oodeel-0.3.0/oodeel/preprocess/tf_preprocess.py +95 -0
  32. oodeel-0.3.0/oodeel/preprocess/torch_preprocess.py +97 -0
  33. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/operator.py +17 -0
  34. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/tf_operator.py +15 -0
  35. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/tf_training_tools.py +2 -2
  36. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/torch_operator.py +19 -0
  37. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel.egg-info/PKG-INFO +144 -18
  38. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel.egg-info/SOURCES.txt +11 -1
  39. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel.egg-info/requires.txt +22 -12
  40. {oodeel-0.2.0 → oodeel-0.3.0}/setup.cfg +21 -5
  41. {oodeel-0.2.0 → oodeel-0.3.0}/setup.py +8 -4
  42. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tests_tensorflow/tf_methods_utils.py +2 -1
  43. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tests_torch/torch_methods_utils.py +34 -27
  44. {oodeel-0.2.0 → oodeel-0.3.0}/LICENSE +0 -0
  45. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/eval/__init__.py +0 -0
  46. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/eval/plots/__init__.py +0 -0
  47. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/eval/plots/features.py +0 -0
  48. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/eval/plots/metrics.py +0 -0
  49. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/eval/plots/plotly.py +0 -0
  50. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/extractor/__init__.py +0 -0
  51. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/types/__init__.py +0 -0
  52. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/__init__.py +0 -0
  53. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/general_utils.py +0 -0
  54. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel/utils/torch_training_tools.py +0 -0
  55. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel.egg-info/dependency_links.txt +0 -0
  56. {oodeel-0.2.0 → oodeel-0.3.0}/oodeel.egg-info/top_level.txt +0 -0
  57. {oodeel-0.2.0 → oodeel-0.3.0}/tests/__init__.py +0 -0
  58. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tests_tensorflow/__init__.py +0 -0
  59. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tests_tensorflow/tools_tf.py +0 -0
  60. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tests_torch/__init__.py +0 -0
  61. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tests_torch/tools_torch.py +0 -0
  62. {oodeel-0.2.0 → oodeel-0.3.0}/tests/tools_operator.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: oodeel
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Simple, compact, and hackable post-hoc deep OOD detection for alreadytrained tensorflow or pytorch image classifiers.
5
5
  Author: DEEL Core Team
6
6
  Author-email: paul.novello@irt-saintexupery.com
@@ -11,13 +11,127 @@ Classifier: Programming Language :: Python :: 3.8
11
11
  Classifier: Programming Language :: Python :: 3.9
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: faiss_cpu
16
+ Requires-Dist: numpy
17
+ Requires-Dist: scikit_learn
18
+ Requires-Dist: scipy
19
+ Requires-Dist: setuptools
20
+ Requires-Dist: matplotlib
21
+ Requires-Dist: pandas
22
+ Requires-Dist: seaborn
23
+ Requires-Dist: plotly
24
+ Requires-Dist: tqdm
14
25
  Provides-Extra: dev
26
+ Requires-Dist: mypy; extra == "dev"
27
+ Requires-Dist: ipywidgets; extra == "dev"
28
+ Requires-Dist: mkdocs-jupyter; extra == "dev"
29
+ Requires-Dist: mkdocstrings-python; extra == "dev"
30
+ Requires-Dist: flake8; extra == "dev"
31
+ Requires-Dist: setuptools; extra == "dev"
32
+ Requires-Dist: pre-commit; extra == "dev"
33
+ Requires-Dist: tox; extra == "dev"
34
+ Requires-Dist: black; extra == "dev"
35
+ Requires-Dist: ruff; extra == "dev"
36
+ Requires-Dist: ipython; extra == "dev"
37
+ Requires-Dist: ipykernel; extra == "dev"
38
+ Requires-Dist: pytest; extra == "dev"
39
+ Requires-Dist: pylint; extra == "dev"
40
+ Requires-Dist: mypy; extra == "dev"
41
+ Requires-Dist: mkdocs; extra == "dev"
42
+ Requires-Dist: mkdocs-material; extra == "dev"
43
+ Requires-Dist: mkdocstrings; extra == "dev"
44
+ Requires-Dist: mknotebooks; extra == "dev"
45
+ Requires-Dist: mike; extra == "dev"
46
+ Requires-Dist: bump2version; extra == "dev"
47
+ Requires-Dist: docsig; extra == "dev"
48
+ Requires-Dist: no_implicit_optional; extra == "dev"
49
+ Requires-Dist: numpy==1.26.4; extra == "dev"
50
+ Requires-Dist: tensorflow==2.11.0; extra == "dev"
51
+ Requires-Dist: tensorflow_datasets; extra == "dev"
52
+ Requires-Dist: tensorflow_probability==0.19.0; extra == "dev"
53
+ Requires-Dist: timm; extra == "dev"
54
+ Requires-Dist: torch==1.13.1; extra == "dev"
55
+ Requires-Dist: torchvision==0.14.1; extra == "dev"
15
56
  Provides-Extra: tensorflow-dev
57
+ Requires-Dist: mypy; extra == "tensorflow-dev"
58
+ Requires-Dist: ipywidgets; extra == "tensorflow-dev"
59
+ Requires-Dist: mkdocs-jupyter; extra == "tensorflow-dev"
60
+ Requires-Dist: mkdocstrings-python; extra == "tensorflow-dev"
61
+ Requires-Dist: flake8; extra == "tensorflow-dev"
62
+ Requires-Dist: setuptools; extra == "tensorflow-dev"
63
+ Requires-Dist: pre-commit; extra == "tensorflow-dev"
64
+ Requires-Dist: tox; extra == "tensorflow-dev"
65
+ Requires-Dist: black; extra == "tensorflow-dev"
66
+ Requires-Dist: ruff; extra == "tensorflow-dev"
67
+ Requires-Dist: ipython; extra == "tensorflow-dev"
68
+ Requires-Dist: ipykernel; extra == "tensorflow-dev"
69
+ Requires-Dist: pytest; extra == "tensorflow-dev"
70
+ Requires-Dist: pylint; extra == "tensorflow-dev"
71
+ Requires-Dist: mypy; extra == "tensorflow-dev"
72
+ Requires-Dist: mkdocs; extra == "tensorflow-dev"
73
+ Requires-Dist: mkdocs-material; extra == "tensorflow-dev"
74
+ Requires-Dist: mkdocstrings; extra == "tensorflow-dev"
75
+ Requires-Dist: mknotebooks; extra == "tensorflow-dev"
76
+ Requires-Dist: mike; extra == "tensorflow-dev"
77
+ Requires-Dist: bump2version; extra == "tensorflow-dev"
78
+ Requires-Dist: docsig; extra == "tensorflow-dev"
79
+ Requires-Dist: no_implicit_optional; extra == "tensorflow-dev"
80
+ Requires-Dist: numpy==1.26.4; extra == "tensorflow-dev"
81
+ Requires-Dist: tensorflow==2.11.0; extra == "tensorflow-dev"
82
+ Requires-Dist: tensorflow_datasets; extra == "tensorflow-dev"
83
+ Requires-Dist: tensorflow_probability==0.19.0; extra == "tensorflow-dev"
16
84
  Provides-Extra: torch-dev
85
+ Requires-Dist: mypy; extra == "torch-dev"
86
+ Requires-Dist: ipywidgets; extra == "torch-dev"
87
+ Requires-Dist: mkdocs-jupyter; extra == "torch-dev"
88
+ Requires-Dist: mkdocstrings-python; extra == "torch-dev"
89
+ Requires-Dist: flake8; extra == "torch-dev"
90
+ Requires-Dist: setuptools; extra == "torch-dev"
91
+ Requires-Dist: pre-commit; extra == "torch-dev"
92
+ Requires-Dist: tox; extra == "torch-dev"
93
+ Requires-Dist: black; extra == "torch-dev"
94
+ Requires-Dist: ruff; extra == "torch-dev"
95
+ Requires-Dist: ipython; extra == "torch-dev"
96
+ Requires-Dist: ipykernel; extra == "torch-dev"
97
+ Requires-Dist: pytest; extra == "torch-dev"
98
+ Requires-Dist: pylint; extra == "torch-dev"
99
+ Requires-Dist: mypy; extra == "torch-dev"
100
+ Requires-Dist: mkdocs; extra == "torch-dev"
101
+ Requires-Dist: mkdocs-material; extra == "torch-dev"
102
+ Requires-Dist: mkdocstrings; extra == "torch-dev"
103
+ Requires-Dist: mknotebooks; extra == "torch-dev"
104
+ Requires-Dist: mike; extra == "torch-dev"
105
+ Requires-Dist: bump2version; extra == "torch-dev"
106
+ Requires-Dist: docsig; extra == "torch-dev"
107
+ Requires-Dist: no_implicit_optional; extra == "torch-dev"
108
+ Requires-Dist: numpy==1.26.4; extra == "torch-dev"
109
+ Requires-Dist: timm; extra == "torch-dev"
110
+ Requires-Dist: torch==1.13.1; extra == "torch-dev"
111
+ Requires-Dist: torchvision==0.14.1; extra == "torch-dev"
17
112
  Provides-Extra: tensorflow
113
+ Requires-Dist: tensorflow==2.11.0; extra == "tensorflow"
114
+ Requires-Dist: tensorflow_datasets; extra == "tensorflow"
115
+ Requires-Dist: tensorflow_probability==0.19.0; extra == "tensorflow"
18
116
  Provides-Extra: torch
117
+ Requires-Dist: timm; extra == "torch"
118
+ Requires-Dist: torch==1.13.1; extra == "torch"
119
+ Requires-Dist: torchvision==0.14.1; extra == "torch"
19
120
  Provides-Extra: docs
20
- License-File: LICENSE
121
+ Requires-Dist: mkdocs; extra == "docs"
122
+ Requires-Dist: mkdocs-material; extra == "docs"
123
+ Requires-Dist: mkdocstrings; extra == "docs"
124
+ Requires-Dist: mknotebooks; extra == "docs"
125
+ Requires-Dist: ipython; extra == "docs"
126
+ Dynamic: author
127
+ Dynamic: author-email
128
+ Dynamic: classifier
129
+ Dynamic: description
130
+ Dynamic: description-content-type
131
+ Dynamic: license-file
132
+ Dynamic: provides-extra
133
+ Dynamic: requires-dist
134
+ Dynamic: summary
21
135
 
22
136
 
23
137
  <!-- Banner section -->
@@ -33,29 +147,23 @@ License-File: LICENSE
33
147
  <!-- Badge section -->
34
148
  <div align="center">
35
149
  <a href="#">
36
- <img src="https://img.shields.io/badge/python-3.8%2B-blue">
37
- </a>
150
+ <img src="https://img.shields.io/badge/python-3.8%2B-blue"></a>
38
151
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-linters.yml">
39
- <img alt="Flake8" src="https://github.com/deel-ai/oodeel/actions/workflows/python-linters.yml/badge.svg">
40
- </a>
152
+ <img alt="Flake8" src="https://github.com/deel-ai/oodeel/actions/workflows/python-linters.yml/badge.svg"></a>
41
153
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-tf.yml">
42
- <img alt="Tests tf" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-tf.yml/badge.svg">
43
- </a>
154
+ <img alt="Tests tf" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-tf.yml/badge.svg"></a>
44
155
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-torch.yml">
45
- <img alt="Tests torch" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-torch.yml/badge.svg">
46
- </a>
156
+ <img alt="Tests torch" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-torch.yml/badge.svg"></a>
47
157
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-coverage-shield.yml">
48
- <img alt="Coverage" src="https://github.com/deel-ai/oodeel/raw/gh-shields/coverage.svg">
49
- </a>
158
+ <img alt="Coverage" src="https://github.com/deel-ai/oodeel/raw/gh-shields/coverage.svg"></a>
50
159
  <a href="https://github.com/deel-ai/oodeel/blob/master/LICENSE">
51
- <img alt="License MIT" src="https://img.shields.io/badge/License-MIT-efefef">
52
- </a>
160
+ <img alt="License MIT" src="https://img.shields.io/badge/License-MIT-efefef"></a>
53
161
  </div>
54
162
  <br>
55
163
 
56
164
  <!-- Short description of your library -->
57
165
 
58
- <b>Oodeel</b> is a library that performs post-hoc deep OOD detection on already trained neural network image classifiers. The philosophy of the library is to favor quality over quantity and to foster easy adoption. As a result, we provide a simple, compact and easily customizable API and carefully integrate and test each proposed baseline into a coherent framework that is designed to enable their use in tensorflow **and** pytorch. You can find the documentation [here](https://deel-ai.github.io/oodeel/).
166
+ <b>Oodeel</b> is a library that performs post-hoc deep OOD (Out-of-Distribution) detection on already trained neural network image classifiers. The philosophy of the library is to favor quality over quantity and to foster easy adoption. As a result, we provide a simple, compact and easily customizable API and carefully integrate and test each proposed baseline into a coherent framework that is designed to enable their use in tensorflow **and** pytorch. You can find the documentation [here](https://deel-ai.github.io/oodeel/).
59
167
 
60
168
  ```python
61
169
  from oodeel.methods import MLS
@@ -75,7 +183,8 @@ scores, info = mls.score(ds) # ds is a tf.data.Dataset or a torch.DataLoader
75
183
  - [Contributing](#contributing)
76
184
  - [See Also](#see-also)
77
185
  - [Acknowledgments](#acknowledgments)
78
- - [Creator](#creator)
186
+ - [Creators](#creators)
187
+ - [Citation](#citation)
79
188
  - [License](#license)
80
189
 
81
190
  # Installation
@@ -202,7 +311,11 @@ Currently, **oodeel** includes the following baselines:
202
311
  | ReAct | [ReAct: Out-of-distribution Detection With Rectified Activations](http://arxiv.org/abs/2111.12797) | NeurIPS 2021 | avail [tensorflow](docs/notebooks/tensorflow/demo_react_tf.ipynb) or [torch](docs/notebooks/torch/demo_react_torch.ipynb) |
203
312
  | NMD | [Neural Mean Discrepancy for Efficient Out-of-Distribution Detection](https://openaccess.thecvf.com/content/CVPR2022/html/Dong_Neural_Mean_Discrepancy_for_Efficient_Out-of-Distribution_Detection_CVPR_2022_paper.html) | CVPR 2022 | planned |
204
313
  | Gram | [Detecting Out-of-Distribution Examples with Gram Matrices](https://proceedings.mlr.press/v119/sastry20a.html) | ICML 2020 | avail [tensorflow](docs/notebooks/tensorflow/demo_gram_tf.ipynb) or [torch](docs/notebooks/torch/demo_gram_torch.ipynb) |
205
-
314
+ | GEN | [GEN: Pushing the Limits of Softmax-Based Out-of-Distribution Detection](https://openaccess.thecvf.com/content/CVPR2023/html/Liu_GEN_Pushing_the_Limits_of_Softmax-Based_Out-of-Distribution_Detection_CVPR_2023_paper.html) | CVPR 2023 | avail [tensorflow](docs/notebooks/tensorflow/demo_gen_tf.ipynb) or [torch](docs/notebooks/torch/demo_gen_torch.ipynb) |
315
+ | RMDS | [A Simple Fix to Mahalanobis Distance for Improving Near-OOD Detection](https://arxiv.org/abs/2106.09022) | preprint | avail [tensorflow](docs/notebooks/tensorflow/demo_rmds_tf.ipynb) or [torch](docs/notebooks/torch/demo_rmds_torch.ipynb) |
316
+ | SHE | [Out-of-Distribution Detection based on In-Distribution Data Patterns Memorization with Modern Hopfield Energy](https://openreview.net/forum?id=KkazG4lgKL) | ICLR 2023 | avail [tensorflow](docs/notebooks/tensorflow/demo_she_tf.ipynb) or [torch](docs/notebooks/torch/demo_she_torch.ipynb) |
317
+ | ASH | [Extremely Simple Activation Shaping for Out-of-Distribution Detection](http://arxiv.org/abs/2310.00227) | ICLR 2023 | avail [tensorflow](docs/notebooks/tensorflow/demo_ash_tf.ipynb) or [torch](docs/notebooks/torch/demo_ash_torch.ipynb) |
318
+ | SCALE | [Scaling for Training Time and Post-hoc Out-of-distribution Detection Enhancement](https://arxiv.org/abs/2111.12797) | ICLR 2024 | avail [tensorflow](docs/notebooks/tensorflow/demo_scale_tf.ipynb) or [torch](docs/notebooks/torch/demo_scale_torch.ipynb) |
206
319
 
207
320
 
208
321
 
@@ -252,6 +365,19 @@ This project received funding from the French ”Investing for the Future – PI
252
365
 
253
366
  The library was created by Paul Novello to streamline DEEL research on post-hoc deep OOD methods and foster their adoption by DEEL industrial partners. He was soon joined by Yann Pequignot, Yannick Prudent, Corentin Friedrich and Matthieu Le Goff.
254
367
 
368
+ # Citation
369
+
370
+ If you use OODEEL for your research project, please consider citing:
371
+ ```
372
+ @misc{oodeel,
373
+ author = {Novello, Paul and Prudent, Yannick and Friedrich, Corentin and Pequignot, Yann and Le Goff, Matthieu},
374
+ title = {OODEEL, a simple, compact, and hackable post-hoc deep OOD detection for already trained tensorflow or pytorch image classifiers.},
375
+ year = {2023},
376
+ publisher = {GitHub},
377
+ journal = {GitHub repository},
378
+ howpublished = {\url{https://github.com/deel-ai/oodeel}},
379
+ }
380
+ ```
255
381
  # License
256
382
 
257
383
  The package is released under [MIT license](LICENSE).
@@ -12,29 +12,23 @@
12
12
  <!-- Badge section -->
13
13
  <div align="center">
14
14
  <a href="#">
15
- <img src="https://img.shields.io/badge/python-3.8%2B-blue">
16
- </a>
15
+ <img src="https://img.shields.io/badge/python-3.8%2B-blue"></a>
17
16
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-linters.yml">
18
- <img alt="Flake8" src="https://github.com/deel-ai/oodeel/actions/workflows/python-linters.yml/badge.svg">
19
- </a>
17
+ <img alt="Flake8" src="https://github.com/deel-ai/oodeel/actions/workflows/python-linters.yml/badge.svg"></a>
20
18
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-tf.yml">
21
- <img alt="Tests tf" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-tf.yml/badge.svg">
22
- </a>
19
+ <img alt="Tests tf" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-tf.yml/badge.svg"></a>
23
20
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-torch.yml">
24
- <img alt="Tests torch" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-torch.yml/badge.svg">
25
- </a>
21
+ <img alt="Tests torch" src="https://github.com/deel-ai/oodeel/actions/workflows/python-tests-torch.yml/badge.svg"></a>
26
22
  <a href="https://github.com/deel-ai/oodeel/actions/workflows/python-coverage-shield.yml">
27
- <img alt="Coverage" src="https://github.com/deel-ai/oodeel/raw/gh-shields/coverage.svg">
28
- </a>
23
+ <img alt="Coverage" src="https://github.com/deel-ai/oodeel/raw/gh-shields/coverage.svg"></a>
29
24
  <a href="https://github.com/deel-ai/oodeel/blob/master/LICENSE">
30
- <img alt="License MIT" src="https://img.shields.io/badge/License-MIT-efefef">
31
- </a>
25
+ <img alt="License MIT" src="https://img.shields.io/badge/License-MIT-efefef"></a>
32
26
  </div>
33
27
  <br>
34
28
 
35
29
  <!-- Short description of your library -->
36
30
 
37
- <b>Oodeel</b> is a library that performs post-hoc deep OOD detection on already trained neural network image classifiers. The philosophy of the library is to favor quality over quantity and to foster easy adoption. As a result, we provide a simple, compact and easily customizable API and carefully integrate and test each proposed baseline into a coherent framework that is designed to enable their use in tensorflow **and** pytorch. You can find the documentation [here](https://deel-ai.github.io/oodeel/).
31
+ <b>Oodeel</b> is a library that performs post-hoc deep OOD (Out-of-Distribution) detection on already trained neural network image classifiers. The philosophy of the library is to favor quality over quantity and to foster easy adoption. As a result, we provide a simple, compact and easily customizable API and carefully integrate and test each proposed baseline into a coherent framework that is designed to enable their use in tensorflow **and** pytorch. You can find the documentation [here](https://deel-ai.github.io/oodeel/).
38
32
 
39
33
  ```python
40
34
  from oodeel.methods import MLS
@@ -54,7 +48,8 @@ scores, info = mls.score(ds) # ds is a tf.data.Dataset or a torch.DataLoader
54
48
  - [Contributing](#contributing)
55
49
  - [See Also](#see-also)
56
50
  - [Acknowledgments](#acknowledgments)
57
- - [Creator](#creator)
51
+ - [Creators](#creators)
52
+ - [Citation](#citation)
58
53
  - [License](#license)
59
54
 
60
55
  # Installation
@@ -181,7 +176,11 @@ Currently, **oodeel** includes the following baselines:
181
176
  | ReAct | [ReAct: Out-of-distribution Detection With Rectified Activations](http://arxiv.org/abs/2111.12797) | NeurIPS 2021 | avail [tensorflow](docs/notebooks/tensorflow/demo_react_tf.ipynb) or [torch](docs/notebooks/torch/demo_react_torch.ipynb) |
182
177
  | NMD | [Neural Mean Discrepancy for Efficient Out-of-Distribution Detection](https://openaccess.thecvf.com/content/CVPR2022/html/Dong_Neural_Mean_Discrepancy_for_Efficient_Out-of-Distribution_Detection_CVPR_2022_paper.html) | CVPR 2022 | planned |
183
178
  | Gram | [Detecting Out-of-Distribution Examples with Gram Matrices](https://proceedings.mlr.press/v119/sastry20a.html) | ICML 2020 | avail [tensorflow](docs/notebooks/tensorflow/demo_gram_tf.ipynb) or [torch](docs/notebooks/torch/demo_gram_torch.ipynb) |
184
-
179
+ | GEN | [GEN: Pushing the Limits of Softmax-Based Out-of-Distribution Detection](https://openaccess.thecvf.com/content/CVPR2023/html/Liu_GEN_Pushing_the_Limits_of_Softmax-Based_Out-of-Distribution_Detection_CVPR_2023_paper.html) | CVPR 2023 | avail [tensorflow](docs/notebooks/tensorflow/demo_gen_tf.ipynb) or [torch](docs/notebooks/torch/demo_gen_torch.ipynb) |
180
+ | RMDS | [A Simple Fix to Mahalanobis Distance for Improving Near-OOD Detection](https://arxiv.org/abs/2106.09022) | preprint | avail [tensorflow](docs/notebooks/tensorflow/demo_rmds_tf.ipynb) or [torch](docs/notebooks/torch/demo_rmds_torch.ipynb) |
181
+ | SHE | [Out-of-Distribution Detection based on In-Distribution Data Patterns Memorization with Modern Hopfield Energy](https://openreview.net/forum?id=KkazG4lgKL) | ICLR 2023 | avail [tensorflow](docs/notebooks/tensorflow/demo_she_tf.ipynb) or [torch](docs/notebooks/torch/demo_she_torch.ipynb) |
182
+ | ASH | [Extremely Simple Activation Shaping for Out-of-Distribution Detection](http://arxiv.org/abs/2310.00227) | ICLR 2023 | avail [tensorflow](docs/notebooks/tensorflow/demo_ash_tf.ipynb) or [torch](docs/notebooks/torch/demo_ash_torch.ipynb) |
183
+ | SCALE | [Scaling for Training Time and Post-hoc Out-of-distribution Detection Enhancement](https://arxiv.org/abs/2111.12797) | ICLR 2024 | avail [tensorflow](docs/notebooks/tensorflow/demo_scale_tf.ipynb) or [torch](docs/notebooks/torch/demo_scale_torch.ipynb) |
185
184
 
186
185
 
187
186
 
@@ -231,6 +230,19 @@ This project received funding from the French ”Investing for the Future – PI
231
230
 
232
231
  The library was created by Paul Novello to streamline DEEL research on post-hoc deep OOD methods and foster their adoption by DEEL industrial partners. He was soon joined by Yann Pequignot, Yannick Prudent, Corentin Friedrich and Matthieu Le Goff.
233
232
 
233
+ # Citation
234
+
235
+ If you use OODEEL for your research project, please consider citing:
236
+ ```
237
+ @misc{oodeel,
238
+ author = {Novello, Paul and Prudent, Yannick and Friedrich, Corentin and Pequignot, Yann and Le Goff, Matthieu},
239
+ title = {OODEEL, a simple, compact, and hackable post-hoc deep OOD detection for already trained tensorflow or pytorch image classifiers.},
240
+ year = {2023},
241
+ publisher = {GitHub},
242
+ journal = {GitHub repository},
243
+ howpublished = {\url{https://github.com/deel-ai/oodeel}},
244
+ }
245
+ ```
234
246
  # License
235
247
 
236
248
  The package is released under [MIT license](LICENSE).
@@ -25,4 +25,4 @@ oodeel
25
25
  -------
26
26
  """
27
27
 
28
- __version__ = "0.2.0"
28
+ __version__ = "0.3.0"
@@ -20,4 +20,5 @@
20
20
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
21
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  # SOFTWARE.
23
- from .ooddataset import OODDataset
23
+ from .data_handler import load_data_handler
24
+ from .deprecated.DEPRECATED_ooddataset import OODDataset
@@ -0,0 +1,304 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright IRT Antoine de Saint Exupéry et Université Paul Sabatier Toulouse III - All
3
+ # rights reserved. DEEL is a research program operated by IVADO, IRT Saint Exupéry,
4
+ # CRIAQ and ANITI - https://www.deel.ai/
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+ import importlib.util
24
+ from abc import ABC
25
+ from abc import abstractmethod
26
+
27
+ import numpy as np
28
+
29
+ from ..types import Callable
30
+ from ..types import DatasetType
31
+ from ..types import ItemType
32
+ from ..types import Optional
33
+ from ..types import TensorType
34
+ from ..types import Tuple
35
+ from ..types import Union
36
+
37
+
38
+ def get_backend():
39
+ """Detects whether TensorFlow or PyTorch is available and returns
40
+ the preferred backend."""
41
+ available_backends = []
42
+ if importlib.util.find_spec("tensorflow"):
43
+ available_backends.append("tensorflow")
44
+ if importlib.util.find_spec("torch"):
45
+ available_backends.append("torch")
46
+
47
+ if len(available_backends) == 1:
48
+ return available_backends[0]
49
+ elif len(available_backends) == 0:
50
+ raise ImportError("Neither TensorFlow nor PyTorch is installed.")
51
+ else:
52
+ raise ImportError(
53
+ "Both TensorFlow and PyTorch are installed. Please specify the backend."
54
+ )
55
+
56
+
57
+ def load_data_handler(backend: str = None):
58
+ if backend is None:
59
+ backend = get_backend()
60
+
61
+ if backend == "tensorflow":
62
+ from .tf_data_handler import TFDataHandler
63
+
64
+ return TFDataHandler()
65
+
66
+ elif backend == "torch":
67
+ from .torch_data_handler import TorchDataHandler
68
+
69
+ return TorchDataHandler()
70
+
71
+
72
+ class DataHandler(ABC):
73
+ """
74
+ Class to manage Datasets. The aim is to provide a simple interface
75
+ for working with datasets (torch, tensorflow or other...) and manage them without
76
+ having to use library-specific syntax.
77
+ """
78
+
79
+ def __init__(self):
80
+ self.backend = None
81
+ self.channel_order = None
82
+
83
+ def split_by_class(
84
+ self,
85
+ dataset: DatasetType,
86
+ in_labels: Optional[Union[np.ndarray, list]] = None,
87
+ out_labels: Optional[Union[np.ndarray, list]] = None,
88
+ ) -> Optional[Tuple[DatasetType]]:
89
+ """Filter the dataset by assigning ood labels depending on labels
90
+ value (typically, class id).
91
+
92
+ Args:
93
+ in_labels (Optional[Union[np.ndarray, list]], optional): set of labels
94
+ to be considered as in-distribution. Defaults to None.
95
+ out_labels (Optional[Union[np.ndarray, list]], optional): set of labels
96
+ to be considered as out-of-distribution. Defaults to None.
97
+
98
+ Returns:
99
+ Optional[Tuple[OODDataset]]: Tuple of in-distribution and
100
+ out-of-distribution OODDatasets
101
+ """
102
+ # Make sure the dataset has labels
103
+ assert (in_labels is not None) or (
104
+ out_labels is not None
105
+ ), "specify labels to filter with"
106
+ assert self.get_item_length(dataset) >= 2, "the dataset has no labels"
107
+
108
+ # Filter the dataset depending on in_labels and out_labels given
109
+ if (out_labels is not None) and (in_labels is not None):
110
+ in_data = self.filter_by_value(dataset, "label", in_labels)
111
+ out_data = self.filter_by_value(dataset, "label", out_labels)
112
+
113
+ if out_labels is None:
114
+ in_data = self.filter_by_value(dataset, "label", in_labels)
115
+ out_data = self.filter_by_value(dataset, "label", in_labels, excluded=True)
116
+
117
+ elif in_labels is None:
118
+ in_data = self.filter_by_value(dataset, "label", out_labels, excluded=True)
119
+ out_data = self.filter_by_value(dataset, "label", out_labels)
120
+
121
+ # Return the filtered OODDatasets
122
+ return in_data, out_data
123
+
124
+ @classmethod
125
+ @abstractmethod
126
+ def prepare(
127
+ cls,
128
+ dataset: DatasetType,
129
+ batch_size: int,
130
+ preprocess_fn: Optional[Callable] = None,
131
+ augment_fn: Optional[Callable] = None,
132
+ columns: Optional[list] = None,
133
+ shuffle: bool = False,
134
+ dict_based_fns: bool = True,
135
+ return_tuple: bool = True,
136
+ **kwargs_prepare,
137
+ ) -> DatasetType:
138
+ """Prepare dataset for scoring or training
139
+
140
+ Args:
141
+ batch_size (int): Batch size
142
+ preprocess_fn (Callable, optional): Preprocessing function to apply to
143
+ the dataset. Defaults to None.
144
+ augment_fn (Callable, optional): Augment function to be used (when the
145
+ returned dataset is to be used for training). Defaults to None.
146
+ columns (list, optional): List of columns
147
+ that will be returned. Keep all columns if None. Defaults to None.
148
+ shuffle (bool, optional): To shuffle the returned dataset or not.
149
+ Defaults to False.
150
+ dict_based_fns (bool): Whether to use preprocess and DA functions as dict
151
+ based (if True) or as tuple based (if False). Defaults to True.
152
+ return_tuple (bool, optional): Whether to return each dataset item
153
+ as a tuple. Defaults to True.
154
+ kwargs_prepare (dict): Additional parameters to be passed to the
155
+ data_handler for backend specific preparation.
156
+
157
+
158
+ Returns:
159
+ DatasetType: prepared dataset
160
+ """
161
+ raise NotImplementedError()
162
+
163
+ @staticmethod
164
+ @abstractmethod
165
+ def load_dataset_from_arrays(
166
+ dataset_id: ItemType, columns: Optional[list] = None
167
+ ) -> DatasetType:
168
+ """Load a DatasetType from a np.ndarray / Tensor
169
+
170
+ Args:
171
+ dataset_id (ItemType): numpy array(s) to load.
172
+ columns (list, optional): Column names to assign. If None,
173
+ assigned as "input_i" for i-th column. Defaults to None.
174
+
175
+ Returns:
176
+ DatasetType
177
+ """
178
+ raise NotImplementedError()
179
+
180
+ @staticmethod
181
+ @abstractmethod
182
+ def load_custom_dataset(
183
+ dataset_id: DatasetType, columns: Optional[list] = None
184
+ ) -> DatasetType:
185
+ """Load a custom dataset by ensuring it is properly formatted.
186
+
187
+ Args:
188
+ dataset_id (DatasetType): dataset
189
+ columns (list, optional): Column names to use for elements if dataset_id is
190
+ tuple based. If None, assigned as "input_i"
191
+ for i-th column. Defaults to None.
192
+
193
+ Returns:
194
+ A properly formatted dataset.
195
+ """
196
+ raise NotImplementedError()
197
+
198
+ @staticmethod
199
+ @abstractmethod
200
+ def map_ds(dataset: DatasetType, map_fn: Callable) -> DatasetType:
201
+ """Map a function to a Dataset
202
+
203
+ Args:
204
+ dataset (DatasetType): Dataset to map the function to
205
+ map_fn (Callable): Function to map
206
+
207
+ Returns:
208
+ DatasetType: Mapped dataset
209
+ """
210
+ raise NotImplementedError()
211
+
212
+ @staticmethod
213
+ @abstractmethod
214
+ def filter_by_value(
215
+ dataset: DatasetType,
216
+ column_name: str,
217
+ values: list,
218
+ excluded: bool = False,
219
+ ) -> DatasetType:
220
+ """Filter the dataset by checking the value of a column is in `values`
221
+
222
+ Args:
223
+ dataset (Dataset): Dataset to filter
224
+ column_name (str): Column to filter the dataset with
225
+ values (list): Column values to keep (if excluded is False)
226
+ or to exclude
227
+ excluded (bool, optional): To keep (False) or exclude (True) the samples
228
+ with column value included in Values. Defaults to False.
229
+
230
+ Returns:
231
+ DatasetType: Filtered dataset
232
+ """
233
+ raise NotImplementedError()
234
+
235
+ @staticmethod
236
+ @abstractmethod
237
+ def get_item_length(dataset: DatasetType) -> int:
238
+ """Number of elements in a dataset item
239
+
240
+ Args:
241
+ dataset (DatasetType): Dataset
242
+
243
+ Returns:
244
+ int: Item length
245
+ """
246
+ raise NotImplementedError()
247
+
248
+ @staticmethod
249
+ @abstractmethod
250
+ def get_dataset_length(dataset: DatasetType) -> int:
251
+ """Number of items in a dataset
252
+
253
+ Args:
254
+ dataset (DatasetType): Dataset
255
+
256
+ Returns:
257
+ int: Dataset length
258
+ """
259
+ raise NotImplementedError()
260
+
261
+ @staticmethod
262
+ @abstractmethod
263
+ def get_column_elements_shape(
264
+ dataset: DatasetType, column_name: Union[str, int]
265
+ ) -> tuple:
266
+ """Get the shape of the elements of a column of dataset identified by
267
+ column_name
268
+
269
+ Args:
270
+ dataset (Dataset): a Dataset
271
+ column_name (Union[str, int]): The column name to get
272
+ the element shape from.
273
+
274
+ Returns:
275
+ tuple: the shape of an element from column_name
276
+ """
277
+ raise NotImplementedError()
278
+
279
+ @staticmethod
280
+ @abstractmethod
281
+ def get_input_from_dataset_item(elem: ItemType) -> TensorType:
282
+ """Get the tensor that is to be feed as input to a model from a dataset element.
283
+
284
+ Args:
285
+ elem (ItemType): dataset element to extract input from
286
+
287
+ Returns:
288
+ TensorType: Input tensor
289
+ """
290
+ raise NotImplementedError()
291
+
292
+ @staticmethod
293
+ @abstractmethod
294
+ def get_label_from_dataset_item(item: ItemType):
295
+ """Retrieve label tensor from item as a tuple/list. Label must be at index 1
296
+ in the item tuple. If one-hot encoded, labels are converted to single value.
297
+
298
+ Args:
299
+ elem (ItemType): dataset element to extract label from
300
+
301
+ Returns:
302
+ Any: Label tensor
303
+ """
304
+ raise NotImplementedError()
@@ -25,12 +25,12 @@ from abc import abstractmethod
25
25
 
26
26
  import numpy as np
27
27
 
28
- from ..types import Callable
29
- from ..types import DatasetType
30
- from ..types import ItemType
31
- from ..types import Optional
32
- from ..types import Tuple
33
- from ..types import Union
28
+ from ...types import Callable
29
+ from ...types import DatasetType
30
+ from ...types import ItemType
31
+ from ...types import Optional
32
+ from ...types import Tuple
33
+ from ...types import Union
34
34
 
35
35
 
36
36
  class DataHandler(ABC):