Evaluation¶
Zero-shot / recovery evaluation, baselines, and ensembling.
polyweave.evaluation ¶
Evaluation: zero-shot accuracy, recovery curves, baselines.
The read-side companion to :mod:polyweave.training. Given a trained teacher,
these measure the weights it generates — without fine-tuning (zero-shot) and as a
fine-tuning initialisation (recovery) — and provide the non-hypernetwork
baselines (random, nearest-class-centroid) the teachers are compared against.
centroids_to_fc ¶
Turn class centroids into an equivalent linear head {"weight","bias"}.
For centroid c_k, the score -½‖x - c_k‖² ranks classes identically to
nearest-centroid; dropping the shared -½‖x‖² term leaves the linear form
wₖ·x + bₖ with wₖ = c_k and bₖ = -½‖c_k‖².
Source code in polyweave/evaluation/baselines.py
class_centroids ¶
Mean feature vector per class, [num_classes, feature_dim].
Empty classes get a zero centroid (they contribute nothing discriminative).
Source code in polyweave/evaluation/baselines.py
ncc_fc ¶
Convenience: build the NCC linear head directly from features and labels.
random_like ¶
random_like(reference: WeightStruct, *, scale: float = 1.0, zero_bias: bool = True, fan_in_scale: bool = True) -> WeightStruct
Random weights matching the shapes of a generated structure.
Weight-like tensors (ndim >= 2) are filled with random normal values; 1-D
tensors are treated as biases and zeroed when zero_bias (the experiments'
random baseline uses random weights with zero bias). Recurses over a list of
dicts for the per-layer Q/K structure.
By default (fan_in_scale=True) each weight tensor is scaled to a
Kaiming-linear standard deviation 1/sqrt(fan_in) — matching
nn.init.kaiming_normal_(..., nonlinearity="linear") — so the random
baseline is a well-conditioned initialisation rather than a saturating one.
fan_in is prod(shape[1:]) (input features, times kernel area for
convolutions). scale multiplies on top of this. Passing
fan_in_scale=False recovers the raw scale * randn behaviour.
Note: a unit-variance random head (fan_in_scale=False, scale=1) produces
logits ~sqrt(fan_in) too large, saturating the softmax and stalling
fine-tuning — which is why fan-in scaling is the default for the baseline.
Source code in polyweave/evaluation/baselines.py
accuracy_from_probs ¶
Top-1 accuracy of a [N, C] probability/logit tensor against [N] labels.
Source code in polyweave/evaluation/ensemble.py
disagreement_matrix ¶
Symmetric [M, M] matrix of pairwise prediction-disagreement rates.
Entry (i, j) is the fraction of examples where members i and j
differ; the diagonal is 0. Useful for a heatmap of which members are
redundant vs complementary.
Source code in polyweave/evaluation/ensemble.py
ensemble_accuracy ¶
ensemble_gain ¶
Ensemble accuracy minus mean single-member accuracy (the diversity payoff).
ensemble_probs ¶
Mean soft vote over members: [M, N, C] -> [N, C].
member_accuracies ¶
Per-member top-1 accuracy: [M, N, C], [N] -> [M].
Source code in polyweave/evaluation/ensemble.py
pairwise_disagreement ¶
Mean over distinct member pairs of the fraction of examples they disagree on.
probs is [M, N, C]; predictions are taken as the per-member argmax.
Returns a scalar in [0, 1]: 0 when every member predicts identically,
higher when members make different predictions (error diversity). Undefined
for a single member (returns 0.0).
Source code in polyweave/evaluation/ensemble.py
average_weights ¶
Element-wise mean of a list of identically-structured weight pytrees.
Handles a dict of tensors and a list of such dicts (the two shapes
the teachers emit). Raises on anything else.
Source code in polyweave/evaluation/loops.py
evaluate_accuracy ¶
evaluate_accuracy(student: Module, eval_batches: Iterable[Batch], gen: Any, forward: Forward) -> float
Top-1 accuracy of student over eval_batches using weights gen.
gen is passed straight to forward; pass the generated structure for
zero-shot evaluation, or None to evaluate the student's own (e.g. already
installed / recovered) weights.
Source code in polyweave/evaluation/loops.py
evaluate_macro_f1 ¶
evaluate_macro_f1(student: Module, eval_batches: Iterable[Batch], gen: Any, forward: Forward, num_classes: int) -> float
Macro-averaged F1 of student over eval_batches using weights gen.
The balanced complement to :func:evaluate_accuracy: per-class F1 averaged
with equal weight, so a method cannot score well by ignoring minority classes.
On the (near-)balanced tasks in this paper macro-F1 tracks accuracy closely;
it is provided so a re-run can report both at no extra forward-pass cost.
Classes that are neither present nor predicted are excluded from the mean.
Source code in polyweave/evaluation/loops.py
generate_averaged ¶
generate_averaged(teacher: Module, student: Module, support_batches: Iterable[Batch], build_prototype: Callable[[Module, Batch], Tensor]) -> WeightStruct
Generate weights for student from each support batch and average them.
Averaging over a handful of support batches reduces the variance of the
prototype statistics, matching the experiments' eval_support_batches.
Source code in polyweave/evaluation/loops.py
mean_curves ¶
Average several recovery curves that share the same step grid.
Source code in polyweave/evaluation/loops.py
recovery_curve ¶
recovery_curve(student: Module, *, init: RecoveryInit, sample_batch: Callable[[], Batch], forward: Forward, eval_fn: Callable[[Module], float], steps: int, lr: float = 0.001, eval_every: int = 20, grad_mask: Optional[Callable[[Module], None]] = None) -> List[Tuple[int, float]]
Fine-tune a generated initialisation and record the accuracy curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
student
|
Module
|
the student to recover (modified in place). |
required |
init
|
RecoveryInit
|
installs the initial weights into |
required |
sample_batch
|
Callable[[], Batch]
|
fresh training batch each step. |
required |
forward
|
Forward
|
|
required |
eval_fn
|
Callable[[Module], float]
|
maps |
required |
steps
|
int
|
fine-tuning budget. |
required |
lr
|
float
|
Adam learning rate. |
0.001
|
eval_every
|
int
|
evaluation cadence in steps. |
20
|
grad_mask
|
Optional[Callable[[Module], None]]
|
optional hook run after |
None
|
Returns:
| Type | Description |
|---|---|
List[Tuple[int, float]]
|
A list of |
Source code in polyweave/evaluation/loops.py
reset_bn_stats ¶
reset_bn_stats(model: Module, batches: Iterable[Batch], run: Callable[[Module, Batch], Any], *, max_batches: int = 10) -> None
Re-estimate BatchNorm running statistics after a weight swap.
Resets the running mean/var of every _BatchNorm in model and re-runs
run(model, batch) (a forward pass) in train mode over up to
max_batches batches. Restores eval mode afterwards.