Train expert predictor and evaluate prediction accuracy. Accepts pre-loaded numpy arrays (from load_multiple_routing_files). Supports loading a checkpoint for finetuning via load_model_path. The loss combines standard BCE with a hinge penalty on false positives above `threshold` (d
(layers, hiddens, experts, K, n_tokens,
hidden_size=256, epochs=20, lr=1e-3, K_pred=4,
model_type='mlp',
hidden_dim=HIDDEN_DIM,
num_experts=NUM_EXPERTS,
num_layers=NUM_LAYERS,
load_model_path=None,
save_model_path=None,
threshold=0.75,
fp_penalty_weight=5.0,
skip_layers=None,
dropout=0.1)
| 398 | |
| 399 | |
| 400 | def train_and_evaluate(layers, hiddens, experts, K, n_tokens, |
| 401 | hidden_size=256, epochs=20, lr=1e-3, K_pred=4, |
| 402 | model_type='mlp', |
| 403 | hidden_dim=HIDDEN_DIM, |
| 404 | num_experts=NUM_EXPERTS, |
| 405 | num_layers=NUM_LAYERS, |
| 406 | load_model_path=None, |
| 407 | save_model_path=None, |
| 408 | threshold=0.75, |
| 409 | fp_penalty_weight=5.0, |
| 410 | skip_layers=None, |
| 411 | dropout=0.1): |
| 412 | """Train expert predictor and evaluate prediction accuracy. |
| 413 | |
| 414 | Accepts pre-loaded numpy arrays (from load_multiple_routing_files). |
| 415 | Supports loading a checkpoint for finetuning via load_model_path. |
| 416 | |
| 417 | The loss combines standard BCE with a hinge penalty on false positives above |
| 418 | `threshold` (default 0.75). Any expert the model predicts with probability |
| 419 | >= threshold must be in the actual top-4; `fp_penalty_weight` (beta) controls |
| 420 | how hard the model is pushed to suppress confident-but-wrong predictions. |
| 421 | """ |
| 422 | try: |
| 423 | import torch |
| 424 | from torch.utils.data import DataLoader, TensorDataset |
| 425 | except ImportError: |
| 426 | print("ERROR: pip install torch") |
| 427 | sys.exit(1) |
| 428 | |
| 429 | cross_layer = model_type.endswith('-cross') |
| 430 | |
| 431 | print(f" {len(layers)} samples, K={K}, layers 0-{layers.max()}") |
| 432 | print(f" Hidden state shape: {hiddens.shape}") |
| 433 | print(f" Hidden RMS: {np.sqrt(np.mean(hiddens**2)):.4f}") |
| 434 | print(f" Model type: {model_type}") |
| 435 | |
| 436 | # Temporal locality baseline |
| 437 | print("\n=== Temporal Locality Baseline ===") |
| 438 | prev_experts = {} |
| 439 | temporal_hits = 0 |
| 440 | temporal_total = 0 |
| 441 | for i in range(len(layers)): |
| 442 | li = int(layers[i]) |
| 443 | ei = set(int(x) for x in experts[i] if x >= 0) # drop -1 padding |
| 444 | if li in prev_experts: |
| 445 | temporal_hits += len(ei & prev_experts[li]) |
| 446 | temporal_total += len(ei) # real experts only, not padded K |
| 447 | prev_experts[li] = ei |
| 448 | if temporal_total > 0: |
| 449 | print(f" Temporal hit rate: {temporal_hits}/{temporal_total} = " |
| 450 | f"{temporal_hits/temporal_total*100:.1f}%") |
| 451 | |
| 452 | # Cosine similarity analysis (Fate §4.2) |
| 453 | print("\n=== Adjacent-Layer Cosine Similarity (Fate §4.2) ===") |
| 454 | layer_sims = analyze_cosine_similarity(layers, hiddens, num_layers) |
| 455 | avg_sim = layer_sims.mean() |
| 456 | print(f" Mean cos(h[l], h[l+1]): {avg_sim:.4f} Min: {layer_sims.min():.4f}") |
| 457 | print(" Per-layer: " + |
no test coverage detected