aucurriculum 0.1.0__py3-none-any.whl

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.
Files changed (79) hide show
  1. aucurriculum/__init__.py +36 -0
  2. aucurriculum/cli/__init__.py +33 -0
  3. aucurriculum/core/__init__.py +0 -0
  4. aucurriculum/core/constants/__init__.py +4 -0
  5. aucurriculum/core/constants/curriculum_constants.py +26 -0
  6. aucurriculum/core/filters/__init__.py +4 -0
  7. aucurriculum/core/filters/filters.py +45 -0
  8. aucurriculum/core/plotting/__init__.py +4 -0
  9. aucurriculum/core/plotting/plot_curriculum.py +274 -0
  10. aucurriculum/core/scripts/__init__.py +28 -0
  11. aucurriculum/core/scripts/cli.py +79 -0
  12. aucurriculum/core/scripts/cli_wrapper.py +96 -0
  13. aucurriculum/core/scripts/create_script.py +77 -0
  14. aucurriculum/core/scripts/curriculum_script.py +88 -0
  15. aucurriculum/core/scripts/group_script.py +69 -0
  16. aucurriculum/core/scripts/list_script.py +50 -0
  17. aucurriculum/core/scripts/postprocess_script.py +74 -0
  18. aucurriculum/core/scripts/show_script.py +55 -0
  19. aucurriculum/core/scripts/train_script.py +99 -0
  20. aucurriculum/core/wrappers/__init__.py +4 -0
  21. aucurriculum/core/wrappers/main.py +65 -0
  22. aucurriculum/curricula/__init__.py +8 -0
  23. aucurriculum/curricula/curriculum_pace_manager.py +232 -0
  24. aucurriculum/curricula/curriculum_score_manager.py +168 -0
  25. aucurriculum/curricula/pacing/__init__.py +17 -0
  26. aucurriculum/curricula/pacing/abstract_pace.py +49 -0
  27. aucurriculum/curricula/pacing/exponential.py +53 -0
  28. aucurriculum/curricula/pacing/logarithmic.py +54 -0
  29. aucurriculum/curricula/pacing/one_step.py +48 -0
  30. aucurriculum/curricula/pacing/polynomial.py +149 -0
  31. aucurriculum/curricula/scoring/__init__.py +22 -0
  32. aucurriculum/curricula/scoring/abstract_score.py +455 -0
  33. aucurriculum/curricula/scoring/ce_loss.py +79 -0
  34. aucurriculum/curricula/scoring/cumulative_accuracy.py +186 -0
  35. aucurriculum/curricula/scoring/cv_loss.py +293 -0
  36. aucurriculum/curricula/scoring/first_iteration.py +176 -0
  37. aucurriculum/curricula/scoring/predefined_score.py +82 -0
  38. aucurriculum/curricula/scoring/prediction_depth.py +360 -0
  39. aucurriculum/curricula/scoring/random_score.py +72 -0
  40. aucurriculum/curricula/scoring/transfer_teacher.py +153 -0
  41. aucurriculum/curricula/scoring/utils.py +179 -0
  42. aucurriculum/postprocessing/__init__.py +10 -0
  43. aucurriculum/postprocessing/aggregate.py +68 -0
  44. aucurriculum/postprocessing/group.py +52 -0
  45. aucurriculum/postprocessing/summarize_curriculum.py +127 -0
  46. aucurriculum-0.1.0.dist-info/LICENSE +21 -0
  47. aucurriculum-0.1.0.dist-info/METADATA +58 -0
  48. aucurriculum-0.1.0.dist-info/RECORD +79 -0
  49. aucurriculum-0.1.0.dist-info/WHEEL +4 -0
  50. aucurriculum-0.1.0.dist-info/entry_points.txt +3 -0
  51. aucurriculum-configurations/_aucurriculum_score_.yaml +15 -0
  52. aucurriculum-configurations/_aucurriculum_train_.yaml +46 -0
  53. aucurriculum-configurations/config.yaml +23 -0
  54. aucurriculum-configurations/curriculum/AntiCurriculum.yaml +12 -0
  55. aucurriculum-configurations/curriculum/Curriculum.yaml +12 -0
  56. aucurriculum-configurations/curriculum/None.yaml +12 -0
  57. aucurriculum-configurations/curriculum/pacing/Exponential.yaml +4 -0
  58. aucurriculum-configurations/curriculum/pacing/Linear.yaml +4 -0
  59. aucurriculum-configurations/curriculum/pacing/Logarithmic.yaml +4 -0
  60. aucurriculum-configurations/curriculum/pacing/None.yaml +4 -0
  61. aucurriculum-configurations/curriculum/pacing/OneStep.yaml +4 -0
  62. aucurriculum-configurations/curriculum/pacing/Quadratic.yaml +4 -0
  63. aucurriculum-configurations/curriculum/pacing/Root.yaml +4 -0
  64. aucurriculum-configurations/curriculum/sampling/Balanced.yaml +2 -0
  65. aucurriculum-configurations/curriculum/sampling/None.yaml +2 -0
  66. aucurriculum-configurations/curriculum/sampling/Original.yaml +2 -0
  67. aucurriculum-configurations/curriculum/sampling/Unbalanced.yaml +2 -0
  68. aucurriculum-configurations/curriculum/scoring/CELoss.yaml +7 -0
  69. aucurriculum-configurations/curriculum/scoring/CVLoss.yaml +26 -0
  70. aucurriculum-configurations/curriculum/scoring/CumulativeAccuracy.yaml +6 -0
  71. aucurriculum-configurations/curriculum/scoring/FirstIteration.yaml +6 -0
  72. aucurriculum-configurations/curriculum/scoring/None.yaml +3 -0
  73. aucurriculum-configurations/curriculum/scoring/Predefined.yaml +8 -0
  74. aucurriculum-configurations/curriculum/scoring/PredictionDepth.yaml +9 -0
  75. aucurriculum-configurations/curriculum/scoring/Random.yaml +6 -0
  76. aucurriculum-configurations/curriculum/scoring/TransferTeacher.yaml +6 -0
  77. aucurriculum-configurations/curriculum.yaml +14 -0
  78. aucurriculum-configurations/hydra/sweeper/aucurriculum_score_sweeper.yaml +6 -0
  79. aucurriculum-configurations/hydra/sweeper/aucurriculum_train_sweeper.yaml +9 -0
@@ -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,4 @@
1
+ from .curriculum_constants import CurriculumConstants
2
+
3
+
4
+ __all__ = ["CurriculumConstants"]
@@ -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,4 @@
1
+ from .filters import FilterPartialCurriculum, FilterPlaceholderScoringFunction
2
+
3
+
4
+ __all__ = ["FilterPartialCurriculum", "FilterPlaceholderScoringFunction"]
@@ -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,4 @@
1
+ from .plot_curriculum import CurriculumPlots
2
+
3
+
4
+ __all__ = ["CurriculumPlots"]
@@ -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()
@@ -0,0 +1,96 @@
1
+ from typing import Optional
2
+
3
+ from autrainer.core.scripts import FetchScript, PreprocessScript
4
+ from autrainer.core.scripts.abstract_script import MockParser
5
+ from autrainer.core.scripts.fetch_script import PreprocessArgs as FetchArgs
6
+ from autrainer.core.scripts.preprocess_script import PreprocessArgs
7
+ from autrainer.core.scripts.utils import (
8
+ add_hydra_args_to_sys,
9
+ catch_cli_errors,
10
+ run_hydra_cmd,
11
+ running_in_notebook,
12
+ )
13
+
14
+
15
+ @catch_cli_errors
16
+ def fetch(
17
+ override_kwargs: Optional[dict] = None,
18
+ cfg_launcher: bool = False,
19
+ config_name: str = "config",
20
+ config_path: Optional[str] = None,
21
+ ) -> None:
22
+ """Fetch the datasets and models specified in a training configuration.
23
+
24
+ Args:
25
+ override_kwargs: Additional Hydra override arguments to pass to the
26
+ train script.
27
+ cfg_launcher: Use the launcher specified in the configuration instead
28
+ of the Hydra basic launcher. Defaults to False.
29
+ config_name: The name of the config (usually the file name without the
30
+ .yaml extension). Defaults to "config".
31
+ config_path: The config path, a directory where Hydra will search for
32
+ config files. If config_path is None no directory is added to the
33
+ search path. Defaults to None.
34
+ """
35
+ if running_in_notebook():
36
+ run_hydra_cmd(
37
+ "fetch -l" if cfg_launcher else "fetch",
38
+ override_kwargs,
39
+ config_name,
40
+ config_path,
41
+ cmd_prefix="aucurriculum",
42
+ )
43
+
44
+ else:
45
+ add_hydra_args_to_sys(override_kwargs, config_name, config_path)
46
+ script = FetchScript()
47
+ script.parser = MockParser()
48
+ script.main(FetchArgs(cfg_launcher))
49
+
50
+
51
+ @catch_cli_errors
52
+ def preprocess(
53
+ override_kwargs: Optional[dict] = None,
54
+ num_workers: int = 1,
55
+ update_frequency: int = 1,
56
+ cfg_launcher: bool = False,
57
+ config_name: str = "config",
58
+ config_path: Optional[str] = None,
59
+ ) -> None:
60
+ """Launch a data preprocessing configuration.
61
+
62
+ Args:
63
+ override_kwargs: Additional Hydra override arguments to pass to the
64
+ train script.
65
+ num_workers: Number of workers (threads) to use for preprocessing.
66
+ Defaults to 1.
67
+ update_frequency: Frequency of progress bar updates for each worker
68
+ (thread). If 0, the progress bar will be disabled. Defaults to 1.
69
+ cfg_launcher: Use the launcher specified in the configuration instead
70
+ of the Hydra basic launcher. Defaults to False.
71
+ config_name: The name of the config (usually the file name without the
72
+ .yaml extension). Defaults to "config".
73
+ config_path: The config path, a directory where Hydra will search for
74
+ config files. If config_path is None no directory is added to the
75
+ search path. Defaults to None.
76
+ """
77
+ if running_in_notebook():
78
+ cmd = "preprocess"
79
+ if cfg_launcher:
80
+ cmd += " -l"
81
+ cmd += f" -n {num_workers} -u {update_frequency}"
82
+ run_hydra_cmd(
83
+ cmd,
84
+ override_kwargs,
85
+ config_name,
86
+ config_path,
87
+ cmd_prefix="aucurriculum",
88
+ )
89
+
90
+ else:
91
+ add_hydra_args_to_sys(override_kwargs, config_name, config_path)
92
+ script = PreprocessScript()
93
+ script.parser = MockParser()
94
+ script.main(
95
+ PreprocessArgs(cfg_launcher, num_workers, update_frequency)
96
+ )