peal.adaptors.didae.DiDAEConfig

class peal.adaptors.didae.DiDAEConfig[source]

Bases: AdaptorConfig

Config for the DiDAE (Dictionary-based Interpretable DAE) adaptor.

Every field is documented by the string literal that follows it below, which is what Sphinx renders as that field’s attribute documentation. The most important groups are summarised here.

Parameters:
  • student (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • generator (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • sparse_dictionary (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • teacher (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • data (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • test_data (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • task (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • training (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • explainer (config or path) – The components DiDAE wires together: the classifier to repair, the diffusion autoencoder whose z_sem is edited, the dictionary of directions swept in that space, the feedback source for step 8, the datasets and the CFKD explainer used in step 9.

  • probe_sparse_dictionary (config, optional) – Separate dictionary spanning the LASSO basis of the distilled probe (step 1); None uses sparse_dictionary.

  • lasso_alpha (float, list) – LASSO strength of the probe fit, and extra strengths to report only.

  • lasso_alphas (float, list) – LASSO strength of the probe fit, and extra strengths to report only.

  • top_k_directions (int) – How many ranked directions are shown to the teacher and how many factual/counterfactual pairs are kept per direction.

  • max_cf_per_direction (int) – How many ranked directions are shown to the teacher and how many factual/counterfactual pairs are kept per direction.

  • component_bounds_scale (sweep knobs) – Control the empirical [c_min, c_max] clamp, edit length, atom subset, line search and decoding batch of the direction sweep.

  • edit_depth_factor (sweep knobs) – Control the empirical [c_min, c_max] clamp, edit length, atom subset, line search and decoding batch of the direction sweep.

  • sweep_atom_subset (sweep knobs) – Control the empirical [c_min, c_max] clamp, edit length, atom subset, line search and decoding batch of the direction sweep.

  • linesearch_factors (sweep knobs) – Control the empirical [c_min, c_max] clamp, edit length, atom subset, line search and decoding batch of the direction sweep.

  • decode_batch_size (sweep knobs) – Control the empirical [c_min, c_max] clamp, edit length, atom subset, line search and decoding batch of the direction sweep.

  • concept_replacement (pair mode) – Pair mode: rank (deactivate, activate) concept pairs instead of single atoms.

  • concept_replacement_candidates (pair mode) – Pair mode: rank (deactivate, activate) concept pairs instead of single atoms.

  • concept_replacement_unique (pair mode) – Pair mode: rank (deactivate, activate) concept pairs instead of single atoms.

  • concept_replacement_unique_strategy (pair mode) – Pair mode: rank (deactivate, activate) concept pairs instead of single atoms.

  • latent_only (bool) – Stop after the latent half of the workflow; where step 1.5 draws the ground-truth attributes from.

  • use_generator_data_for_matching (bool) – Stop after the latent half of the workflow; where step 1.5 draws the ground-truth attributes from.

  • run_cfkd_on_false_directions (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • cfkd_false_direction_min_share (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • cfkd_max_false_directions (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • cfkd_teacher (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • use_true_counterfactuals (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • finetune_iterations (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • min_train_samples (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • max_validation_samples (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • counterfactual_type (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • continuous_learning (step-9 knobs) – Whether and how CFKD finetunes on the directions judged false; the first two sample counts also size the discovery sweep pool.

  • max_decode_directions – Decode budgets; forbidden outside service_mode (see __init__).

  • max_decode_per_direction – Decode budgets; forbidden outside service_mode (see __init__).

  • decode_selection – Decode budgets; forbidden outside service_mode (see __init__).

  • service_mode – Decode budgets; forbidden outside service_mode (see __init__).

  • base_dir – Output directory, caching and evaluation settings.

  • overwrite – Output directory, caching and evaluation settings.

  • seed – Output directory, caching and evaluation settings.

  • in_memory – Output directory, caching and evaluation settings.

  • export_onnx – Output directory, caching and evaluation settings.

  • calculate_group_accuracies – Output directory, caching and evaluation settings.

  • max_test_batches – Output directory, caching and evaluation settings.

  • batch_size – Output directory, caching and evaluation settings.

  • n_samples (int) – Deprecated and ignored.

Methods

Attributes

adaptor_type

The type of adaptor that shall be used.

avg_group_accuracies

Average group accuracies log.

base_dir

Base directory.

batch_size

Batch size for counterfactual generation.

calculate_group_accuracies

Calculate group accuracies.

cfkd_false_direction_min_share

Step 9 hands CFKD only the false directions whose verified flip count is at least this share of the strongest false direction's.

cfkd_max_false_directions

no cap).

cfkd_teacher

Teacher used by step 9's CFKD only; None = the same teacher as steps 7-8.

component_bounds_scale

Widen (>1) or tighten (<1) the empirical [c_min, c_max] clamp about its midpoint.

concept_replacement

Rank pairs of concepts -- turn one currently-active concept off and one currently-inactive concept on -- instead of stepping a single atom toward the decision boundary.

concept_replacement_candidates

How many off- and on-candidates the replacement grid scores, M.

concept_replacement_unique

each concept may be deactivated at most once and activated at most once.

concept_replacement_unique_strategy

How the one-to-one selection is made.

continuous_learning

Continuous learning strategy.

counterfactual_type

Counterfactual type.

current_iteration

Current iteration tracking.

data

Data config.

decode_batch_size

Batch size for decoding latent counterfactuals.

decode_selection

Which of a direction's latent flips max_decode_per_direction decodes: "random" (unbiased rate estimate) or "deepest" (the flips that landed furthest past the boundary, i.e. the ones most likely to survive a decode).

edit_depth_factor

Shorten every rendered edit to this multiple of the smallest step along its direction that crosses the distilled probe's boundary (None: full replacement / full step to the bound).

explainer

Explainer config (for CFKD phase).

export_onnx

Also write the final student as ONNX (model.onnx next to model.cpl).

feedback_accuracies

Feedback accuracies log.

finetune_iterations

Number of CFKD finetuning iterations after user feedback.

generator

Generator config path.

group_accuracies

Group accuracies log.

in_memory

In memory dataset.

is_loaded

Loaded flag.

lasso_alpha

SAE-Sparse LASSO regularization alpha (0.0 = standard least-squares).

lasso_alphas

Extra LASSO strengths to fit and report alongside lasso_alpha, off the same encoding pass, as a distillation-quality vs.

latent_only

distillation (step 1), the ground-truth-to-SAE concept matching (step 1.5) and the direction ranking by latent-space flips (steps 2-3).

linesearch_factors

Linesearch factors for counterfactual generation.

max_cf_per_direction

Max representative counterfactual pairs stored per direction.

max_decode_directions

every latent flip inside the empirical bounds is rendered and checked for an ambient flip, exactly like the classical CFKD explainer renders every counterfactual.

max_decode_per_direction

max_export_per_direction

Verified flips per direction written as images to <base_dir>/successful_flips (at least max_cf_per_direction); None writes every verified flip (the web demo shows them all).

max_test_batches

Max test batches.

max_validation_samples

Max validation samples.

min_train_samples

Minimum training samples for CFKD finetuning.

n_samples

Deprecated.

overwrite

Whether to overwrite cached results.

probe_sparse_dictionary

Dictionary whose atoms form the LASSO basis of the distilled probe (step 1) when it should differ from sparse_dictionary, the direction set of the sweep.

run_cfkd_on_false_directions

Whether step 9 runs at all.

seed

Seed.

service_mode

a public job cannot render every latent flip of every direction, so this re-enables the decode budgets max_decode_directions / max_decode_per_direction that the research runs forbid (see the guard in __init__).

sparse_dictionary

Sparse dictionary config path.

student

Student model path.

student_logits_cache

Optional .npz with keys (image keys) and logits (the student's two outputs per image), e.g. the web demo's peal.web.cache.

sweep_atom_subset

render the flips of these dictionary atoms only (a targeted experiment, e.g. the confounder atom alone); None = every atom with a latent flip.

task

Task config.

teacher

Teacher interface.

test_data

Test data config.

top_k_directions

How many top SAE directions to show the user.

training

Training config.

transition_restrictions

Transition restrictions.

use_generator_data_for_matching

Whether step 1.5 matches ground-truth attributes against SAE concepts on the generator's dataset.

use_true_counterfactuals

Whether step 9 also finetunes on "true" counterfactuals (CFKD discards them by default).

adaptor_type: str = 'DiDAE'

The type of adaptor that shall be used. This is necessary to know which pydantic class to use when loading from yaml.

n_samples: int = 200

Deprecated. The discovery sweep now draws min_train_samples + max_validation_samples rows the way CFKD seeds its counterfactuals, so this knob is ignored; it is kept only so existing configs still load. It used to double as a pool switch – the sweep read the validation split alone unless n_samples exceeded it – which made raising the budget silently change the data as well.

top_k_directions: int = 10

How many top SAE directions to show the user.

max_cf_per_direction: int = 5

Max representative counterfactual pairs stored per direction.

max_export_per_direction: None | pydantic.PositiveInt = 20

Verified flips per direction written as images to <base_dir>/successful_flips (at least max_cf_per_direction); None writes every verified flip (the web demo shows them all).

max_decode_directions: None | pydantic.PositiveInt = None

every latent flip inside the empirical bounds is rendered and checked for an ambient flip, exactly like the classical CFKD explainer renders every counterfactual. A budgeted sweep (8 “deepest” decodes per direction) is not comparable to CFKD and made the discovery of Male on CelebA depend on decode noise. Setting either budget raises.

Type:

DISABLED (2026-09-14)

max_decode_per_direction: None | pydantic.PositiveInt = None
decode_selection: str = 'random'

Which of a direction’s latent flips max_decode_per_direction decodes: “random” (unbiased rate estimate) or “deepest” (the flips that landed furthest past the boundary, i.e. the ones most likely to survive a decode).

edit_depth_factor: float | None = None

Shorten every rendered edit to this multiple of the smallest step along its direction that crosses the distilled probe’s boundary (None: full replacement / full step to the bound). 2-3 keeps most flips with the RAE’s ~0.25 realisation.

student_logits_cache: str | None = None

Optional .npz with keys (image keys) and logits (the student’s two outputs per image), e.g. the web demo’s peal.web.cache. Step 1 then takes the student’s margins from it instead of running the student over the train split again; with a missing key it falls back to the student.

sweep_atom_subset: list | None = None

render the flips of these dictionary atoms only (a targeted experiment, e.g. the confounder atom alone); None = every atom with a latent flip.

Type:

Single-atom mode only

component_bounds_scale: float = 1.0

Widen (>1) or tighten (<1) the empirical [c_min, c_max] clamp about its midpoint. That clamp, not the boundary, is what limits the edit in practice. 1.0 uses the bounds in c_min_and_maxes.txt as written.

concept_replacement: bool = False

Rank pairs of concepts – turn one currently-active concept off and one currently-inactive concept on – instead of stepping a single atom toward the decision boundary. The single-atom step is limited by the [c_min, c_max] clamp rather than by the dictionary; a replacement drives both atoms to the bounds themselves, so it gets two atoms’ full range and the clamp cannot cut it short. Latent-only for now.

concept_replacement_candidates: int = 64

How many off- and on-candidates the replacement grid scores, M. Cost is O(n_samples * M^2), so raising it is cheap.

concept_replacement_unique: bool = False

each concept may be deactivated at most once and activated at most once. The unconstrained ranking repeats its strongest concepts – on NICO/MSAE seven of the top ten all deactivate #2145 crocodile – so it reads as ten findings when it is closer to two. Maximum-weight matching, not a greedy walk down the list.

Type:

Report a one-to-one matching instead of the raw pair ranking

concept_replacement_unique_strategy: str = 'greedy'

How the one-to-one selection is made. “greedy” walks the ranking by flip count and keeps a pair whenever neither concept is spoken for – the best pair survives and each entry is the best remaining claim. “matching” takes the maximum-weight one-to-one matching instead, which maximises total flips and can drop the single strongest pair to do it (on NICO/MSAE: 718 flips without #1, against 698 with it).

run_cfkd_on_false_directions: bool = True

Whether step 9 runs at all. False stops after the teacher’s verdicts, which is the whole of the discovery half and everything a hyperparameter sweep of the sweep reads. Step 9 builds a full nested CFKD – its counterfactual generation reached RSS 16 GB here and the Slurm step’s cgroup SIGKILLed the process mid-stage, so leaving it on costs ~20 min per run and returns nothing.

cfkd_false_direction_min_share: float = 0.25

Step 9 hands CFKD only the false directions whose verified flip count is at least this share of the strongest false direction’s. Every direction given to CFKD takes an equal share of the finetuning counterfactuals (num_attempts == len(component_indices)), so a direction the teacher marked false on 2 verified flips out of 12 latent ones dilutes the confounder’s counterfactuals without adding evidence (2026-09-14: five false directions at batch 80 each gave gain ~0 where the oracle pair at 200 gives 0.25). 0 keeps every false direction.

cfkd_max_false_directions: None | pydantic.PositiveInt = None

no cap).

Type:

Hard cap on how many false directions step 9 finetunes on (None

linesearch_factors: list = ['dynamic']

Linesearch factors for counterfactual generation.

decode_batch_size: int = 32

Batch size for decoding latent counterfactuals.

min_train_samples: pydantic.PositiveInt = 800

Minimum training samples for CFKD finetuning.

max_validation_samples: pydantic.PositiveInt = 200

Max validation samples.

max_test_batches: None | pydantic.PositiveInt = None

Max test batches.

finetune_iterations: int = 1

Number of CFKD finetuning iterations after user feedback.

task: TaskConfig | None = None

Task config.

explainer: dict | ExplainerConfig

Explainer config (for CFKD phase).

training: TrainingConfig | None

Training config.

data: DataConfig = None

Data config.

test_data: DataConfig = None

Test data config.

student: PredictorConfig | str | None = None

Student model path.

teacher: str | dict = 'cluster@8000'

Teacher interface.

generator: GeneratorConfig | None = None

Generator config path.

sparse_dictionary: SparseDictionaryConfig | dict | None = None

Sparse dictionary config path.

probe_sparse_dictionary: SparseDictionaryConfig | dict | str | None = None

Dictionary whose atoms form the LASSO basis of the distilled probe (step 1) when it should differ from sparse_dictionary, the direction set of the sweep. Measured 2026-09-12 on CelebA/OpenAI-CLIP: a probe fitted in the 40-atom Procrustes span (r 0.94) gave 20/259 ambient flips and missed Male, the same directions swept under the probe fitted in the 6144-atom MSAE span (r 0.98) gave 85/258 and found Male. None = use sparse_dictionary.

base_dir: str = 'peal_runs/didae'

Base directory.

current_iteration: int = 0

Current iteration tracking.

continuous_learning: str = 'deep_feature_reweighting'

Continuous learning strategy.

batch_size: pydantic.PositiveInt = 200

Batch size for counterfactual generation.

calculate_group_accuracies: bool = False

Calculate group accuracies.

lasso_alpha: float = 0.0

SAE-Sparse LASSO regularization alpha (0.0 = standard least-squares).

lasso_alphas: list | None = None

Extra LASSO strengths to fit and report alongside lasso_alpha, off the same encoding pass, as a distillation-quality vs. support-size table. Reporting only: the probe that goes into the sweep is always the one at lasso_alpha.

latent_only: bool = False

distillation (step 1), the ground-truth-to-SAE concept matching (step 1.5) and the direction ranking by latent-space flips (steps 2-3). Everything past that – decoding, ambient verification, collages, feedback, CFKD – needs a trained diffusion decoder, so this is the mode to run in while the generator is still untrained.

Type:

Stop after the latent half of the workflow

use_generator_data_for_matching: bool = True

Whether step 1.5 matches ground-truth attributes against SAE concepts on the generator’s dataset. True is right when generator and student share a dataset. Set it False when the generator was trained on something else (a general-purpose ImageNet autoencoder, say): the attributes to look for are the student’s, and the generator’s dataset does not carry them.

overwrite: bool = True

Whether to overwrite cached results.

feedback_accuracies: list = []

Feedback accuracies log.

group_accuracies: list = []

Group accuracies log.

avg_group_accuracies: list = []

Average group accuracies log.

counterfactual_type: str = '1sided'

Counterfactual type.

use_true_counterfactuals: bool = False

Whether step 9 also finetunes on “true” counterfactuals (CFKD discards them by default). With a confounder-only step 9 the “false” verdicts alone can be too few to fill a validation batch, which trips CFKD’s “too empty” guard and skips finetuning.

is_loaded: bool = False

Loaded flag.

seed: int | None = 0

Seed.

in_memory: bool = False

In memory dataset.

transition_restrictions: list | None = None

Transition restrictions.

service_mode: bool = False

a public job cannot render every latent flip of every direction, so this re-enables the decode budgets max_decode_directions / max_decode_per_direction that the research runs forbid (see the guard in __init__). Results of a service_mode run are not comparable to the paper’s CFKD numbers; they are an upper-bound ranking (“deepest” selection) meant to surface the strongest shortcut quickly.

Type:

Service mode (the web demo, peal/web)

cfkd_teacher: str | dict | None = None

Teacher used by step 9’s CFKD only; None = the same teacher as steps 7-8. A direction that a human / LLM judged “false” in step 8 is spurious by that verdict, so its counterfactuals need no further per-sample judgement: “Baseline:false” accepts every swapped counterfactual as a false one and lets step 9 run unattended. Without it a collage-based teacher (web, human, llm) would be asked again for every CFKD counterfactual.

export_onnx: bool = False

Also write the final student as ONNX (model.onnx next to model.cpl). Implied when the student was loaded from an .onnx file.