Leave-one-sequence-out cross-validation objective for sequence regression.
Ported from the training path used by spotpython.fun.hyperlight.HyperLight with fun_control["hacky"]=True (spotpython.light.trainmodel), without Lightning: for every sequence of a spotoptim.data.manydataset.ManyToManyDataset, a fresh model is trained on all remaining sequences for the full number of epochs and evaluated on the held-out sequence; the objective value is the mean of the held-out losses. As in spotPython, training runs the complete epoch budget (the patience hyperparameter is accepted but has no effect, because the reference implementation never attached a validation loader during fitting) and the loss is computed on zero-padded batches without masking.
Requires the torch optional extra (pip install 'spotoptim[torch]').
The experiment’s dataset must be a spotoptim.core.data.SpotDataFromTorchDataset whose training dataset yields variable-length (features, targets) sequence pairs (e.g. a spotoptim.data.manydataset.ManyToManyDataset). For each hyperparameter configuration, every sequence is held out once: a fresh model is trained on the remaining sequences and scored on the held-out one, and the mean held-out loss is returned. A configuration whose training fails (e.g. an optimizer incompatible with dense gradients) evaluates to np.nan, to be repaired by SpotOptim’s penalty handling.
The tuned hyperparameters follow the spotPython ManyToManyRNNRegressor convention: epochs, batch_size, optimizer, and lr_mult drive training via spotoptim.nn.optimizer.optimizer_handler and a MultiStepLR schedule (three milestones at 1/4, 2/4, and 3/4 of the epoch budget, decay factor 0.1); all remaining parameters are passed to the model constructor.
Per-parameter functions applied to the decoded hyperparameter values before training, e.g. {"epochs": lambda v: 2 ** int(v)} to reproduce spotPython’s transform_power_2_int. Defaults to None.