aucurriculum 0.1.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.
- aucurriculum-0.1.0/LICENSE +21 -0
- aucurriculum-0.1.0/PKG-INFO +58 -0
- aucurriculum-0.1.0/README.md +34 -0
- aucurriculum-0.1.0/aucurriculum/__init__.py +36 -0
- aucurriculum-0.1.0/aucurriculum/cli/__init__.py +33 -0
- aucurriculum-0.1.0/aucurriculum/core/__init__.py +0 -0
- aucurriculum-0.1.0/aucurriculum/core/constants/__init__.py +4 -0
- aucurriculum-0.1.0/aucurriculum/core/constants/curriculum_constants.py +26 -0
- aucurriculum-0.1.0/aucurriculum/core/filters/__init__.py +4 -0
- aucurriculum-0.1.0/aucurriculum/core/filters/filters.py +45 -0
- aucurriculum-0.1.0/aucurriculum/core/plotting/__init__.py +4 -0
- aucurriculum-0.1.0/aucurriculum/core/plotting/plot_curriculum.py +274 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/__init__.py +28 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/cli.py +79 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/cli_wrapper.py +96 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/create_script.py +77 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/curriculum_script.py +88 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/group_script.py +69 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/list_script.py +50 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/postprocess_script.py +74 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/show_script.py +55 -0
- aucurriculum-0.1.0/aucurriculum/core/scripts/train_script.py +99 -0
- aucurriculum-0.1.0/aucurriculum/core/wrappers/__init__.py +4 -0
- aucurriculum-0.1.0/aucurriculum/core/wrappers/main.py +65 -0
- aucurriculum-0.1.0/aucurriculum/curricula/__init__.py +8 -0
- aucurriculum-0.1.0/aucurriculum/curricula/curriculum_pace_manager.py +232 -0
- aucurriculum-0.1.0/aucurriculum/curricula/curriculum_score_manager.py +168 -0
- aucurriculum-0.1.0/aucurriculum/curricula/pacing/__init__.py +17 -0
- aucurriculum-0.1.0/aucurriculum/curricula/pacing/abstract_pace.py +49 -0
- aucurriculum-0.1.0/aucurriculum/curricula/pacing/exponential.py +53 -0
- aucurriculum-0.1.0/aucurriculum/curricula/pacing/logarithmic.py +54 -0
- aucurriculum-0.1.0/aucurriculum/curricula/pacing/one_step.py +48 -0
- aucurriculum-0.1.0/aucurriculum/curricula/pacing/polynomial.py +149 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/__init__.py +22 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/abstract_score.py +455 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/ce_loss.py +79 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/cumulative_accuracy.py +186 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/cv_loss.py +293 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/first_iteration.py +176 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/predefined_score.py +82 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/prediction_depth.py +360 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/random_score.py +72 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/transfer_teacher.py +153 -0
- aucurriculum-0.1.0/aucurriculum/curricula/scoring/utils.py +179 -0
- aucurriculum-0.1.0/aucurriculum/postprocessing/__init__.py +10 -0
- aucurriculum-0.1.0/aucurriculum/postprocessing/aggregate.py +68 -0
- aucurriculum-0.1.0/aucurriculum/postprocessing/group.py +52 -0
- aucurriculum-0.1.0/aucurriculum/postprocessing/summarize_curriculum.py +127 -0
- aucurriculum-0.1.0/aucurriculum-configurations/_aucurriculum_score_.yaml +15 -0
- aucurriculum-0.1.0/aucurriculum-configurations/_aucurriculum_train_.yaml +46 -0
- aucurriculum-0.1.0/aucurriculum-configurations/config.yaml +23 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/AntiCurriculum.yaml +12 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/Curriculum.yaml +12 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/None.yaml +12 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/Exponential.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/Linear.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/Logarithmic.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/None.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/OneStep.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/Quadratic.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/pacing/Root.yaml +4 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/sampling/Balanced.yaml +2 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/sampling/None.yaml +2 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/sampling/Original.yaml +2 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/sampling/Unbalanced.yaml +2 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/CELoss.yaml +7 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/CVLoss.yaml +26 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/CumulativeAccuracy.yaml +6 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/FirstIteration.yaml +6 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/None.yaml +3 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/Predefined.yaml +8 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/PredictionDepth.yaml +9 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/Random.yaml +6 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum/scoring/TransferTeacher.yaml +6 -0
- aucurriculum-0.1.0/aucurriculum-configurations/curriculum.yaml +14 -0
- aucurriculum-0.1.0/aucurriculum-configurations/hydra/sweeper/aucurriculum_score_sweeper.yaml +6 -0
- aucurriculum-0.1.0/aucurriculum-configurations/hydra/sweeper/aucurriculum_train_sweeper.yaml +9 -0
- aucurriculum-0.1.0/pyproject.toml +94 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Simon Rampp, Manuel Milling, Andreas Triantafyllopoulos, Björn W. Schuller.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: aucurriculum
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Curriculum Learning Toolkit for Deep Learning Tasks built on top of autrainer.
|
|
5
|
+
Home-page: https://github.com/autrainer/aucurriculum
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: curriculum learning,autrainer,computer audition,deep learning,artificial intelligence,pytorch,hydra-core,command-line,yaml
|
|
8
|
+
Author: Simon Rampp
|
|
9
|
+
Author-email: simon.rampp@tum.de
|
|
10
|
+
Requires-Python: >=3.9,<4.0
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Requires-Dist: autrainer (==0.4.0)
|
|
20
|
+
Project-URL: Documentation, https://autrainer.github.io/aucurriculum/
|
|
21
|
+
Project-URL: Repository, https://github.com/autrainer/aucurriculum
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
<div align="center">
|
|
25
|
+
<img src="https://autrainer.github.io/aucurriculum/_images/logo_banner.png" alt="aucurriculum — A Curriculum Learning Toolkit for Deep Learning Tasks built on top of autrainer">
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
# aucurriculum
|
|
29
|
+
|
|
30
|
+
[](https://pypi.org/project/aucurriculum/)
|
|
31
|
+
[](https://pypi.org/project/aucurriculum/)
|
|
32
|
+
[](https://github.com/autrainer/aucurriculum/blob/main/LICENSE)
|
|
33
|
+
|
|
34
|
+
A Curriculum Learning Toolkit for Deep Learning Tasks built on top of [autrainer](https://github.com/autrainer/autrainer).
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
To install _aucurriculum_, first ensure that PyTorch (along with torchvision and torchaudio) version 2.0 or higher is installed.
|
|
39
|
+
For installation instructions, refer to the [PyTorch website](https://pytorch.org/get-started/locally/).
|
|
40
|
+
|
|
41
|
+
It is recommended to install _aucurriculum_ within a virtual environment.
|
|
42
|
+
To create a new virtual environment, refer to the [Python venv documentation](https://docs.python.org/3/library/venv.html).
|
|
43
|
+
|
|
44
|
+
Next, install _aucurriculum_ using _pip_.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install aucurriculum
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
To install _aucurriculum_ from source, refer to the [contribution guide](https://autrainer.github.io/aucurriculum/development/contributing.html).
|
|
51
|
+
|
|
52
|
+
## Next Steps
|
|
53
|
+
|
|
54
|
+
To get started using _aucurriculum_, the [quickstart guide](https://autrainer.github.io/aucurriculum/usage/quickstart.html) outlines the creation of a simple training configuration
|
|
55
|
+
and [tutorials](https://autrainer.github.io/aucurriculum/usage/tutorials.html) provide examples for implementing custom scoring and pacing functions including their configurations.
|
|
56
|
+
|
|
57
|
+
For a complete list of available CLI commands, refer to the [CLI reference](https://autrainer.github.io/aucurriculum/usage/cli_reference.html) or the [CLI wrapper](https://autrainer.github.io/aucurriculum/usage/cli_wrapper.html).
|
|
58
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://autrainer.github.io/aucurriculum/_images/logo_banner.png" alt="aucurriculum — A Curriculum Learning Toolkit for Deep Learning Tasks built on top of autrainer">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# aucurriculum
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/aucurriculum/)
|
|
8
|
+
[](https://pypi.org/project/aucurriculum/)
|
|
9
|
+
[](https://github.com/autrainer/aucurriculum/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
A Curriculum Learning Toolkit for Deep Learning Tasks built on top of [autrainer](https://github.com/autrainer/autrainer).
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
To install _aucurriculum_, first ensure that PyTorch (along with torchvision and torchaudio) version 2.0 or higher is installed.
|
|
16
|
+
For installation instructions, refer to the [PyTorch website](https://pytorch.org/get-started/locally/).
|
|
17
|
+
|
|
18
|
+
It is recommended to install _aucurriculum_ within a virtual environment.
|
|
19
|
+
To create a new virtual environment, refer to the [Python venv documentation](https://docs.python.org/3/library/venv.html).
|
|
20
|
+
|
|
21
|
+
Next, install _aucurriculum_ using _pip_.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install aucurriculum
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To install _aucurriculum_ from source, refer to the [contribution guide](https://autrainer.github.io/aucurriculum/development/contributing.html).
|
|
28
|
+
|
|
29
|
+
## Next Steps
|
|
30
|
+
|
|
31
|
+
To get started using _aucurriculum_, the [quickstart guide](https://autrainer.github.io/aucurriculum/usage/quickstart.html) outlines the creation of a simple training configuration
|
|
32
|
+
and [tutorials](https://autrainer.github.io/aucurriculum/usage/tutorials.html) provide examples for implementing custom scoring and pacing functions including their configurations.
|
|
33
|
+
|
|
34
|
+
For a complete list of available CLI commands, refer to the [CLI reference](https://autrainer.github.io/aucurriculum/usage/cli_reference.html) or the [CLI wrapper](https://autrainer.github.io/aucurriculum/usage/cli_wrapper.html).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from autrainer.core.constants import (
|
|
2
|
+
ExportConstants,
|
|
3
|
+
NamingConstants,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
from aucurriculum.core.constants import CurriculumConstants
|
|
7
|
+
from aucurriculum.core.wrappers import main
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# always overlay the autrainer constants
|
|
11
|
+
NamingConstants().CONFIG_DIRS = (
|
|
12
|
+
NamingConstants().CONFIG_DIRS + CurriculumConstants().CONFIG_DIRS
|
|
13
|
+
)
|
|
14
|
+
NamingConstants().NAMING_CONVENTION = NamingConstants().NAMING_CONVENTION[
|
|
15
|
+
:-1
|
|
16
|
+
] + [
|
|
17
|
+
"curriculum",
|
|
18
|
+
"curriculum.sampling",
|
|
19
|
+
"curriculum.scoring",
|
|
20
|
+
"curriculum.pacing",
|
|
21
|
+
"curriculum.pacing.initial_size",
|
|
22
|
+
"curriculum.pacing.final_iteration",
|
|
23
|
+
"seed",
|
|
24
|
+
]
|
|
25
|
+
NamingConstants().VALID_AGGREGATIONS = list(
|
|
26
|
+
set(NamingConstants().NAMING_CONVENTION)
|
|
27
|
+
- set(NamingConstants().INVALID_AGGREGATIONS)
|
|
28
|
+
)
|
|
29
|
+
ExportConstants().LOGGING_DEPTH = 3
|
|
30
|
+
ExportConstants().IGNORE_PARAMS = ExportConstants().IGNORE_PARAMS + [
|
|
31
|
+
"curriculum.short",
|
|
32
|
+
"curriculum.sampling.short",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
__version__ = "0.1.0"
|
|
36
|
+
__all__ = ["main"]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from autrainer.core.scripts import (
|
|
2
|
+
inference,
|
|
3
|
+
rm_failed,
|
|
4
|
+
rm_states,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from aucurriculum.core.scripts import (
|
|
8
|
+
create,
|
|
9
|
+
curriculum,
|
|
10
|
+
fetch,
|
|
11
|
+
group,
|
|
12
|
+
postprocess,
|
|
13
|
+
preprocess,
|
|
14
|
+
show,
|
|
15
|
+
train,
|
|
16
|
+
)
|
|
17
|
+
from aucurriculum.core.scripts import list_configs as list
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"create",
|
|
22
|
+
"curriculum",
|
|
23
|
+
"fetch",
|
|
24
|
+
"group",
|
|
25
|
+
"inference",
|
|
26
|
+
"list",
|
|
27
|
+
"postprocess",
|
|
28
|
+
"preprocess",
|
|
29
|
+
"rm_failed",
|
|
30
|
+
"rm_states",
|
|
31
|
+
"show",
|
|
32
|
+
"train",
|
|
33
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from autrainer.core.constants import AbstractConstants
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CurriculumConstants(AbstractConstants):
|
|
7
|
+
"""Singleton for managing the curriculum configurations of
|
|
8
|
+
`aucurriculum`."""
|
|
9
|
+
|
|
10
|
+
_config_dirs = [
|
|
11
|
+
"curriculum",
|
|
12
|
+
"curriculum/pacing",
|
|
13
|
+
"curriculum/sampling",
|
|
14
|
+
"curriculum/scoring",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def CONFIG_DIRS(self) -> List[str]:
|
|
19
|
+
"""Get the curriculum configuration directories for Hydra
|
|
20
|
+
configurations. Defaults to :attr:`["curriculum", "curriculum/pacing",
|
|
21
|
+
"curriculum/sampling", "curriculum/scoring"]`.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Curriculum configuration directories for Hydra configurations.
|
|
25
|
+
"""
|
|
26
|
+
return self._config_dirs
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from hydra_filter_sweeper import AbstractFilter
|
|
2
|
+
from omegaconf import DictConfig
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FilterPlaceholderScoringFunction(AbstractFilter): # pragma: no cover
|
|
6
|
+
def filter(self, config: DictConfig, directory: str) -> bool:
|
|
7
|
+
"""Filter out run configurations with placeholder (None) scoring
|
|
8
|
+
functions.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
config: Run configuration.
|
|
12
|
+
directory: Directory where the run configuration is stored.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
Whether to filter out the run configuration.
|
|
16
|
+
"""
|
|
17
|
+
return config.curriculum.scoring.id == "None"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class FilterPartialCurriculum(AbstractFilter): # pragma: no cover
|
|
21
|
+
def filter(self, config: DictConfig, directory: str) -> bool:
|
|
22
|
+
"""Filter out run configurations with partial curricula.
|
|
23
|
+
A partial curriculum is one where the id is not "None" but one or more
|
|
24
|
+
of the sampling, scoring, and pacing ids are "None".
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
config: Run configuration.
|
|
28
|
+
directory: Directory where the run configuration is stored.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Whether to filter out the run configuration.
|
|
32
|
+
"""
|
|
33
|
+
c = config.curriculum
|
|
34
|
+
if c.id == "None":
|
|
35
|
+
if any(
|
|
36
|
+
id != "None"
|
|
37
|
+
for id in [c.sampling.id, c.scoring.id, c.pacing.id]
|
|
38
|
+
):
|
|
39
|
+
return True
|
|
40
|
+
return False
|
|
41
|
+
if any(
|
|
42
|
+
id == "None" for id in [c.sampling.id, c.scoring.id, c.pacing.id]
|
|
43
|
+
):
|
|
44
|
+
return True
|
|
45
|
+
return False
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import warnings
|
|
3
|
+
|
|
4
|
+
from autrainer.core.plotting import PlotBase
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import seaborn as sns
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CurriculumPlots(PlotBase):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
output_directory: str,
|
|
15
|
+
training_type: str,
|
|
16
|
+
figsize: tuple,
|
|
17
|
+
latex: bool,
|
|
18
|
+
filetypes: list,
|
|
19
|
+
pickle: bool,
|
|
20
|
+
context: str,
|
|
21
|
+
palette: str,
|
|
22
|
+
replace_none: bool,
|
|
23
|
+
add_titles: bool,
|
|
24
|
+
add_xlabels: bool,
|
|
25
|
+
add_ylabels: bool,
|
|
26
|
+
rcParams: dict,
|
|
27
|
+
) -> None:
|
|
28
|
+
"""Plot the sample difficulty scores and pace of curricula.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
output_directory: Output directory to save plots to.
|
|
32
|
+
training_type: Type of training in ["Epoch", "Step"].
|
|
33
|
+
figsize: Figure size in inches.
|
|
34
|
+
latex: Whether to use LaTeX in plots. Requires the `latex` package.
|
|
35
|
+
To install all necessary dependencies, run:
|
|
36
|
+
`pip install autrainer[latex]`.
|
|
37
|
+
filetypes: Filetypes to save plots as.
|
|
38
|
+
pickle: Whether to save additional pickle files of the plots.
|
|
39
|
+
context: Context for seaborn plots.
|
|
40
|
+
palette: Color palette for seaborn plots.
|
|
41
|
+
replace_none: Whether to replace "None" in labels with "~".
|
|
42
|
+
add_titles: Whether to add titles to plots.
|
|
43
|
+
add_xlabels: Whether to add x-labels to plots.
|
|
44
|
+
add_ylabels: Whether to add y-labels to plots.
|
|
45
|
+
rcParams: Additional Matplotlib rcParams to set.
|
|
46
|
+
"""
|
|
47
|
+
super().__init__(
|
|
48
|
+
output_directory,
|
|
49
|
+
training_type,
|
|
50
|
+
figsize,
|
|
51
|
+
latex,
|
|
52
|
+
filetypes,
|
|
53
|
+
pickle,
|
|
54
|
+
context,
|
|
55
|
+
palette,
|
|
56
|
+
replace_none,
|
|
57
|
+
add_titles,
|
|
58
|
+
add_xlabels,
|
|
59
|
+
add_ylabels,
|
|
60
|
+
rcParams,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def plot_score(self, df: pd.DataFrame, score_id: str, num_bins=20) -> None:
|
|
64
|
+
"""Plot the sample difficulty scores by creating histograms,
|
|
65
|
+
facet grids, and ridge plots visualizing the global and per class
|
|
66
|
+
sample difficulty distributions.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
df: DataFrame containing the sample difficulty scores ("mean",
|
|
70
|
+
"ranks") and corresponding labels ("decoded").
|
|
71
|
+
score_id: ID of the scoring function.
|
|
72
|
+
num_bins: Number of bins for the histogram. Defaults to 20.
|
|
73
|
+
"""
|
|
74
|
+
df["decoded"] = df["decoded"].astype(str)
|
|
75
|
+
order = sorted(df["decoded"].unique())
|
|
76
|
+
sample_counts = df["decoded"].value_counts().sort_index().values
|
|
77
|
+
|
|
78
|
+
self._plot_fn(
|
|
79
|
+
df=df,
|
|
80
|
+
score_id=score_id,
|
|
81
|
+
name="histogram",
|
|
82
|
+
x="mean",
|
|
83
|
+
y_label="count",
|
|
84
|
+
fn=sns.histplot,
|
|
85
|
+
fn_kargs={"bins": num_bins},
|
|
86
|
+
)
|
|
87
|
+
self._plot_facet_grid(
|
|
88
|
+
df=df,
|
|
89
|
+
score_id=score_id,
|
|
90
|
+
name="Count per Class",
|
|
91
|
+
y_label="count",
|
|
92
|
+
fn_map=sns.histplot,
|
|
93
|
+
fn_kargs={
|
|
94
|
+
"bins": np.arange(0, 1 + (1 / num_bins), 1 / num_bins),
|
|
95
|
+
"stat": "count",
|
|
96
|
+
},
|
|
97
|
+
col_order=order,
|
|
98
|
+
)
|
|
99
|
+
percent_char = "\\%" if self.latex else "%"
|
|
100
|
+
self._plot_facet_grid(
|
|
101
|
+
df=df,
|
|
102
|
+
score_id=score_id,
|
|
103
|
+
name="Percent per Class",
|
|
104
|
+
y_label=f"ratio [{percent_char}]",
|
|
105
|
+
fn_map=sns.histplot,
|
|
106
|
+
fn_kargs={
|
|
107
|
+
"bins": np.arange(0, 1 + (1 / num_bins), 1 / num_bins),
|
|
108
|
+
"stat": "percent",
|
|
109
|
+
},
|
|
110
|
+
col_order=order,
|
|
111
|
+
sample_counts=sample_counts,
|
|
112
|
+
)
|
|
113
|
+
self._plot_ridge(
|
|
114
|
+
df=df, score_id=score_id, name="Ridge per Class", row_order=order
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def _plot_facet_grid(
|
|
118
|
+
self,
|
|
119
|
+
df: pd.DataFrame,
|
|
120
|
+
score_id: str,
|
|
121
|
+
name: str,
|
|
122
|
+
y_label: str,
|
|
123
|
+
fn_map: callable,
|
|
124
|
+
fn_kargs: dict,
|
|
125
|
+
col_order: list = None,
|
|
126
|
+
sample_counts: list = None,
|
|
127
|
+
) -> None:
|
|
128
|
+
fg = sns.FacetGrid(
|
|
129
|
+
df,
|
|
130
|
+
col="decoded",
|
|
131
|
+
col_order=col_order,
|
|
132
|
+
hue="decoded",
|
|
133
|
+
col_wrap=5,
|
|
134
|
+
height=self.figsize[1] / 2,
|
|
135
|
+
aspect=self.figsize[0] / (self.figsize[1] * 2),
|
|
136
|
+
)
|
|
137
|
+
fg.set_titles(col_template="{col_name}")
|
|
138
|
+
if sample_counts is not None:
|
|
139
|
+
for ax, ct in zip(fg.axes.flat, sample_counts):
|
|
140
|
+
ax.set_title(f"{ax.get_title()} ({ct} samples)")
|
|
141
|
+
fg.map_dataframe(fn_map, x="ranks", **fn_kargs)
|
|
142
|
+
if self.add_xlabels:
|
|
143
|
+
fg.set_xlabels("ranks")
|
|
144
|
+
else:
|
|
145
|
+
fg.set_xlabels("")
|
|
146
|
+
if self.add_ylabels:
|
|
147
|
+
fg.set_ylabels(y_label)
|
|
148
|
+
else:
|
|
149
|
+
fg.set_ylabels("")
|
|
150
|
+
if self.add_titles:
|
|
151
|
+
fg.figure.suptitle(f"{score_id} {name}", y=0.975)
|
|
152
|
+
else:
|
|
153
|
+
fg.figure.suptitle("")
|
|
154
|
+
path = os.path.join("_plots", score_id)
|
|
155
|
+
self.save_plot(fg.figure, name.lower().replace(" ", "_"), path)
|
|
156
|
+
|
|
157
|
+
def _plot_fn(
|
|
158
|
+
self,
|
|
159
|
+
df: pd.DataFrame,
|
|
160
|
+
score_id: str,
|
|
161
|
+
name: str,
|
|
162
|
+
x: str,
|
|
163
|
+
y_label: str,
|
|
164
|
+
fn: callable,
|
|
165
|
+
fn_kargs: dict,
|
|
166
|
+
) -> None:
|
|
167
|
+
fig = plt.figure(figsize=self.figsize)
|
|
168
|
+
fn(data=df, x=x, **fn_kargs)
|
|
169
|
+
self._add_label(fig.gca(), x, y_label)
|
|
170
|
+
path = os.path.join("_plots", score_id)
|
|
171
|
+
self.save_plot(fig, name.lower().replace(" ", "_"), path)
|
|
172
|
+
|
|
173
|
+
def _plot_ridge(
|
|
174
|
+
self, df: pd.DataFrame, score_id: str, name: str, row_order: list
|
|
175
|
+
) -> None:
|
|
176
|
+
_old_warn = warnings.filters[:]
|
|
177
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
|
178
|
+
height = (self.figsize[1] / 10) * 1.25
|
|
179
|
+
fg = sns.FacetGrid(
|
|
180
|
+
df,
|
|
181
|
+
row="decoded",
|
|
182
|
+
row_order=row_order,
|
|
183
|
+
hue="decoded",
|
|
184
|
+
height=height,
|
|
185
|
+
aspect=(self.figsize[0] * 1.25) / height,
|
|
186
|
+
)
|
|
187
|
+
fg.map_dataframe(
|
|
188
|
+
sns.kdeplot,
|
|
189
|
+
x="ranks",
|
|
190
|
+
bw_adjust=0.5,
|
|
191
|
+
fill=True,
|
|
192
|
+
)
|
|
193
|
+
for ax in fg.axes.flat:
|
|
194
|
+
ax.patch.set_facecolor("none")
|
|
195
|
+
ax.xaxis.grid(False)
|
|
196
|
+
fg.set_titles("")
|
|
197
|
+
fg.set(yticks=[], ylabel="")
|
|
198
|
+
|
|
199
|
+
def label(x, color, label):
|
|
200
|
+
ax = plt.gca()
|
|
201
|
+
ax.text(
|
|
202
|
+
x=0.04,
|
|
203
|
+
y=0,
|
|
204
|
+
s=label,
|
|
205
|
+
ha="right",
|
|
206
|
+
va="bottom",
|
|
207
|
+
transform=ax.transAxes,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
fg.map(label, "ranks")
|
|
211
|
+
fg.despine(left=True)
|
|
212
|
+
if self.add_titles:
|
|
213
|
+
fg.figure.suptitle(f"{score_id} {name}", y=0.975)
|
|
214
|
+
else:
|
|
215
|
+
fg.figure.suptitle("")
|
|
216
|
+
|
|
217
|
+
path = os.path.join("_plots", score_id)
|
|
218
|
+
self.save_plot(fg.figure, name.lower().replace(" ", "_"), path)
|
|
219
|
+
warnings.filters = _old_warn
|
|
220
|
+
|
|
221
|
+
def plot_correlation_matrix(self, df: pd.DataFrame, name: str) -> None:
|
|
222
|
+
"""Create and plot the correlation matrix of the scoring functions.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
df: DataFrame containing multiple scoring functions per column.
|
|
226
|
+
name: Name of the correlation matrix plot.
|
|
227
|
+
"""
|
|
228
|
+
df.sort_index(axis="columns", inplace=True)
|
|
229
|
+
fig_height = int(1 + len(df.columns))
|
|
230
|
+
fig = plt.figure(
|
|
231
|
+
figsize=(max(self.figsize[0], fig_height), fig_height)
|
|
232
|
+
)
|
|
233
|
+
correlation_matrix = df.corr(method="spearman")
|
|
234
|
+
correlation_matrix.to_csv(
|
|
235
|
+
os.path.join(self.output_directory, f"{name}.csv")
|
|
236
|
+
)
|
|
237
|
+
percent_char = "\\%" if self.latex else "%"
|
|
238
|
+
|
|
239
|
+
def escape_percent(x):
|
|
240
|
+
return f"{(x*100):.2f}{percent_char}"
|
|
241
|
+
|
|
242
|
+
sns.heatmap(
|
|
243
|
+
correlation_matrix,
|
|
244
|
+
annot=correlation_matrix.map(escape_percent),
|
|
245
|
+
fmt="",
|
|
246
|
+
cbar=False,
|
|
247
|
+
cmap="crest",
|
|
248
|
+
)
|
|
249
|
+
fig.gca().set_xticklabels(df.columns, rotation=25)
|
|
250
|
+
self.save_plot(fig, name)
|
|
251
|
+
|
|
252
|
+
def plot_run(self, df: pd.DataFrame) -> None:
|
|
253
|
+
"""Plot the dynamic dataset size determined by the curriculum.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
df: DataFrame containing the run metrics and dataset sizes.
|
|
257
|
+
"""
|
|
258
|
+
fig = plt.figure(figsize=self.figsize)
|
|
259
|
+
sns.lineplot(
|
|
260
|
+
data=df["dataset_size"], dashes=False, drawstyle="steps-post"
|
|
261
|
+
)
|
|
262
|
+
self._add_label(fig.gca(), self.training_type, "dataset size")
|
|
263
|
+
self.save_plot(fig, "pace")
|
|
264
|
+
|
|
265
|
+
def plot_pace(self, df: pd.DataFrame) -> None:
|
|
266
|
+
"""Plot the dynamic dataset size of multiple runs.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
df: DataFrame containing multiple runs and their dataset sizes.
|
|
270
|
+
"""
|
|
271
|
+
fig = plt.figure(figsize=self.figsize)
|
|
272
|
+
sns.lineplot(data=df, dashes=False, drawstyle="steps-post")
|
|
273
|
+
self._add_label(fig.gca(), self.training_type, "dataset size")
|
|
274
|
+
self.save_plot(fig, "pace")
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from .cli_wrapper import fetch, preprocess
|
|
2
|
+
from .create_script import CreateCurriculumScript, create
|
|
3
|
+
from .curriculum_script import CurriculumScript, curriculum
|
|
4
|
+
from .group_script import GroupCurriculumScript, group
|
|
5
|
+
from .list_script import ListCurriculumScript, list_configs
|
|
6
|
+
from .postprocess_script import PostprocessCurriculumScript, postprocess
|
|
7
|
+
from .show_script import ShowCurriculumScript, show
|
|
8
|
+
from .train_script import TrainCurriculumScript, train
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"create",
|
|
13
|
+
"CreateCurriculumScript",
|
|
14
|
+
"curriculum",
|
|
15
|
+
"CurriculumScript",
|
|
16
|
+
"fetch",
|
|
17
|
+
"group",
|
|
18
|
+
"GroupCurriculumScript",
|
|
19
|
+
"list_configs",
|
|
20
|
+
"ListCurriculumScript",
|
|
21
|
+
"postprocess",
|
|
22
|
+
"PostprocessCurriculumScript",
|
|
23
|
+
"preprocess",
|
|
24
|
+
"show",
|
|
25
|
+
"ShowCurriculumScript",
|
|
26
|
+
"train",
|
|
27
|
+
"TrainCurriculumScript",
|
|
28
|
+
]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from autrainer.core.scripts import (
|
|
5
|
+
AbstractScript,
|
|
6
|
+
CommandLineError,
|
|
7
|
+
DeleteFailedScript,
|
|
8
|
+
DeleteStatesScript,
|
|
9
|
+
FetchScript,
|
|
10
|
+
InferenceScript,
|
|
11
|
+
PreprocessScript,
|
|
12
|
+
)
|
|
13
|
+
from autrainer.core.scripts.cli import CLI as AutrainerCLI
|
|
14
|
+
|
|
15
|
+
import aucurriculum
|
|
16
|
+
from aucurriculum.core.scripts import (
|
|
17
|
+
CreateCurriculumScript,
|
|
18
|
+
CurriculumScript,
|
|
19
|
+
GroupCurriculumScript,
|
|
20
|
+
ListCurriculumScript,
|
|
21
|
+
PostprocessCurriculumScript,
|
|
22
|
+
ShowCurriculumScript,
|
|
23
|
+
TrainCurriculumScript,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CLI(AutrainerCLI):
|
|
28
|
+
def __init__(self) -> None:
|
|
29
|
+
super().__init__()
|
|
30
|
+
self._update_metadata()
|
|
31
|
+
|
|
32
|
+
def _init_scripts(self) -> List[AbstractScript]:
|
|
33
|
+
return [
|
|
34
|
+
# configuration management
|
|
35
|
+
CreateCurriculumScript(),
|
|
36
|
+
ListCurriculumScript(),
|
|
37
|
+
ShowCurriculumScript(),
|
|
38
|
+
# preprocessing
|
|
39
|
+
FetchScript(),
|
|
40
|
+
PreprocessScript(),
|
|
41
|
+
# training
|
|
42
|
+
TrainCurriculumScript(),
|
|
43
|
+
# inference
|
|
44
|
+
InferenceScript(),
|
|
45
|
+
# postprocessing
|
|
46
|
+
PostprocessCurriculumScript(),
|
|
47
|
+
DeleteFailedScript(),
|
|
48
|
+
DeleteStatesScript(),
|
|
49
|
+
GroupCurriculumScript(),
|
|
50
|
+
# curriculum learning
|
|
51
|
+
CurriculumScript(),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
def _update_metadata(self) -> None:
|
|
55
|
+
self.parser.prog = "aucurriculum"
|
|
56
|
+
self.parser.description = (
|
|
57
|
+
"A Curriculum Learning Toolkit for Deep Learning Tasks "
|
|
58
|
+
"built on top of autrainer."
|
|
59
|
+
)
|
|
60
|
+
for action in self.parser._actions:
|
|
61
|
+
if isinstance(action, argparse._VersionAction):
|
|
62
|
+
action.version = f"%(prog)s {aucurriculum.__version__}"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def main() -> None:
|
|
66
|
+
cli = CLI()
|
|
67
|
+
try:
|
|
68
|
+
cli.main()
|
|
69
|
+
except CommandLineError as e:
|
|
70
|
+
e.handle()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_parser() -> argparse.ArgumentParser:
|
|
74
|
+
cli = CLI() # pragma: no cover
|
|
75
|
+
return cli.parser # pragma: no cover
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
main()
|