Expand description
Level 3: what is above one training run.
The graph is a network — one forward. The Trainer is a training run — an
afternoon. This is the level above, and it has no type: N training runs
are a for. What lives here are the pieces that for asks for, and they all
have one shape:
indices and keys in, indices out. Never a tensor.
That is what lets all of it be Rust while the loop stays in Python. The step
that cannot move here is train, because training is torch — and a trait
that calls back out for it is not an abstraction, it is the loop leaking. The
original measured this: its TrialExecutor has one implementor, a closure.
| cutting the samples | |
|---|---|
Samples | how many, and their class and group |
KFold | k parts, each held out in turn |
Stratified | a k-fold inside each class |
Grouped | a k-fold over the groups, so a group never splits |
StratifiedGrouped | both, as far as both can be had at once |
TimeSeries | growing prefixes, so nothing trains on its own future |
Partition, Fold | the family, and one cut |
| where to look next | looks at |
|---|---|
Space, Point | the knobs, and one configuration — also a trial’s name |
Grid | the space’s shape, and the one that runs out |
Random | nothing; over a space where few knobs matter it beats a grid |
Halton, Sobol | nothing either, but uniform for every prefix |
Tpe | what already happened |
Sampler | the family |
ask is a function of the index and not of what was asked before, so a
machine that claimed trial 7 out of a shared folder derives the same point
without replaying six. Tpe is the exception and says so. Uniform for
every prefix is what stops two machines proposing neighbours — Random is
uniform only in expectation, so it merely makes it unlikely.
| when to give up | judged against |
|---|---|
Percentile | the others at the same step; the median pruner is p = 50 |
Threshold | a constant already known to be hopeless |
Patience | itself: it has stopped improving |
Pruner, Goal | the family, and which way is better |
A pruner stops nothing: it answers Verdict and the loop stops calling the
trainer, so none of this added a line to level 2.
Five cutting schemes and not sklearn’s fifteen, because stratifying and
grouping are not different algorithms and the rest are parameters:
LeaveOneOut is KFold { k: n } and purged cross-validation is
TimeSeries { gap }. Not called Split, because somatize.torch.Split is
already split learning.
Structs§
- Fold
- One cut: who trains and who is held out. Both sides in ascending order — shuffling decides who is in each fold, never the order they are listed in, so a fold reads the same whatever produced it.
- Grid
- Walk the whole space and stop.
- Grouped
- Grouping is a k-fold over the groups, with the samples following theirs.
Needs
in_groupsand takes no seed: it places the biggest groups first into whichever fold is emptiest, which is what keeps the folds comparable when the groups are not. - Halton
- Cover the space evenly instead of drawing from it evenly.
- KFold
- The plain cut: the samples in
kparts, each one held out while the rest train. - Patience
- Prune what has stopped improving on its own best. Early stopping, and the third thing a verdict can be measured against: the others, a constant, itself. Unlike both of the others it can prune a run that is doing perfectly well in the field and simply is not going anywhere.
- Percentile
- Prune what is doing worse at this step than
ppercent of the others. - Point
- One point of the space: every knob, set.
- Random
- Uniform in every knob, independently.
- Samples
- How many samples there are, and what is known about each. Built up, because most cuts need only the count:
- Sobol
- Cover the space evenly, one binary bisection per knob.
- Space
- The knobs, in the order they were declared.
- Stratified
- Stratifying is not a different algorithm: it is a
KFoldapplied inside each class, the folds concatenated. That is why there is one scheme here and not sklearn’sKFold/StratifiedKFoldpair. - Stratified
Grouped - The two constraints at once, which is where they stop composing cleanly:
with the groups kept whole, exact strata are usually not reachable at
all. So this is greedy and approximate, and says so — sklearn’s
StratifiedGroupKFoldis greedy for the same reason, because the exact problem is a bin packing. - Threshold
- Prune what leaves the bounds you already know are hopeless. The only scheme
that needs no other trial, so it works on the very first one — where a
diverged configuration costs most and the other two have nothing to compare
against. With neither bound it still prunes what is not a number, which is
what
divergedis. - Time
Series - The one scheme that is deliberately not a partition: the first block has nothing before it to learn from, so it only ever trains and is never held out. Every other scheme here holds out each sample exactly once.
- Tpe
- Tree-structured Parzen Estimator: model what the good trials did, model what the bad ones did, and propose where the first is likely and the second is not.
Enums§
- Dimension
- One knob and what it may be. Three kinds and not more: a bool is a
Choiceof two, and a power of two between 16 and 512 is anIntread as a log. Not here: a conditional dimension, which needs a consumer first. - Goal
- Which way is better.
- Goal
Error - Why that does not say which way is better.
- Partition
- Whichever of the schemes a cut is.
- Partition
Error - Why the samples cannot be cut that way.
- Pruner
- Whichever of the schemes a pruner is.
- Read
Error - Why that text is not a point of this space.
- Reason
- Why a trial is not worth another epoch. Structured and not a string, because how many were pruned, and for which of the three reasons is the question you ask of a search that pruned too much.
- Sampler
- Whichever of the schemes a sampler is.
- Samples
Error - Why that is not one key per sample.
- Setting
- What one knob was set to.
- Space
Error - Why that is not a knob that can be searched.
- Verdict
- What a pruner answers.
Constants§
- KNOBS
- How many knobs the table reaches, and so how many this can search.