BREAKING CHANGES: - Removed orphaned dqn.rs monolithic trainer (4,975 lines) - Removed orphaned dqn_ensemble.rs module (816 lines) - Removed orphaned tft.rs and tft_complete_int8_integration_test.rs - TFT trainer split into modular directory structure DQN Module Refactoring: - Split trainers/dqn.rs into modular structure (config.rs, statistics.rs, trainer.rs) - Fixed hyperopt 39D search space (continuous params only) - Boolean flags (use_dueling, use_double_dqn, use_per, use_noisy_nets) are now FIXED architectural decisions - use_distributional defaults to false (Candle BUG #36 - scatter_add gradient issues) Clean Module Structure: - ml/src/trainers/dqn/ directory with proper mod.rs exports - ml/src/trainers/tft/ directory with config.rs, types.rs, model.rs, trainer.rs, tests.rs - All P0 features validated: TD-error clamping, batch diversity, LR scheduler, priority staleness Documentation: - Added comprehensive docs in docs/codebase-cleanup/ - ADR-001 for DQN refactoring decisions - Rainbow DQN component matrix and quick reference guides Build Status: Compiles with zero errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
199 lines
5.1 KiB
Markdown
199 lines
5.1 KiB
Markdown
# Spectral Normalization Quick Reference - Agent 15
|
||
|
||
## TL;DR - Decision Summary
|
||
|
||
**FEASIBILITY**: ✅ **YES - Can be implemented**
|
||
**COMPLEXITY**: 🟡 **Medium** (custom power iteration, ~300 LOC)
|
||
**DEVELOPMENT TIME**: ⏱️ **5-8 days**
|
||
**PERFORMANCE COST**: 📊 **5-10% slower training**
|
||
**RECOMMENDATION**: ⚠️ **Implement if overfitting is critical issue**
|
||
|
||
---
|
||
|
||
## Quick Facts
|
||
|
||
### What is Spectral Normalization?
|
||
Constrains the Lipschitz constant of neural network layers by normalizing weights to have spectral norm ≤ 1. Prevents overfitting by limiting how much outputs can change for small input changes.
|
||
|
||
### Candle Support
|
||
- ❌ **NOT built-in** to candle-nn
|
||
- ✅ **CAN implement** using power iteration
|
||
- ✅ **Example code exists** in codebase for power iteration
|
||
|
||
### Implementation Approach
|
||
```rust
|
||
// Power iteration to find largest singular value
|
||
for _ in 0..n_iterations {
|
||
v = W^T * u / ||W^T * u||
|
||
u = W * v / ||W * v||
|
||
}
|
||
sigma = u^T * W * v
|
||
W_normalized = W / sigma
|
||
```
|
||
|
||
---
|
||
|
||
## Should We Implement It?
|
||
|
||
### ✅ YES, if:
|
||
- Validation loss >> Training loss (severe overfitting)
|
||
- Current regularization (dropout=0.3, layer norm) insufficient
|
||
- Need state-of-the-art anti-overfitting technique
|
||
- Can afford 5-8 days development + 5-10% performance cost
|
||
|
||
### ❌ NO, if:
|
||
- Overfitting manageable with current techniques
|
||
- Development time/resources limited
|
||
- Performance overhead unacceptable
|
||
- Simple alternatives untried
|
||
|
||
### 🟡 ALTERNATIVES (easier/faster):
|
||
1. **Increase dropout** (0.3 → 0.5) - 1 line change
|
||
2. **Add weight decay** - already in optimizer
|
||
3. **Early stopping** - simple to implement
|
||
4. **Reduce network size** - config change
|
||
|
||
---
|
||
|
||
## Implementation Plan (If Approved)
|
||
|
||
### Phase 1: Core (2-3 days)
|
||
```rust
|
||
// File: ml/src/dqn/spectral_norm.rs
|
||
pub struct SpectralNorm {
|
||
u: Tensor, // [out_features]
|
||
v: Tensor, // [in_features]
|
||
n_power_iterations: usize,
|
||
}
|
||
|
||
impl SpectralNorm {
|
||
fn normalize_weights(&mut self, weight: &Tensor) -> Result<Tensor> {
|
||
// Power iteration algorithm
|
||
// Returns normalized weight
|
||
}
|
||
}
|
||
|
||
// Tests: correctness, convergence, performance
|
||
```
|
||
|
||
### Phase 2: DQN Integration (1-2 days)
|
||
```rust
|
||
// File: ml/src/dqn/rainbow_network.rs
|
||
pub struct RainbowNetworkConfig {
|
||
pub use_spectral_norm: bool, // NEW
|
||
// ... existing fields
|
||
}
|
||
|
||
// Wrap NoisyLinear with SpectralNorm
|
||
```
|
||
|
||
### Phase 3: Validation (2-3 days)
|
||
- Hyperopt with/without spectral norm
|
||
- Compare validation metrics
|
||
- Measure overfitting reduction
|
||
|
||
---
|
||
|
||
## Key Metrics to Watch
|
||
|
||
### Before Implementation
|
||
- Current validation loss vs training loss gap
|
||
- Overfitting severity on evaluation set
|
||
|
||
### After Implementation
|
||
- Validation loss improvement (target: 10-20%)
|
||
- Training time overhead (expect: 5-10%)
|
||
- Gradient stability (should improve)
|
||
- Generalization to new market regimes
|
||
|
||
---
|
||
|
||
## Technical Details
|
||
|
||
### Memory Cost
|
||
Per layer: 2 * hidden_dim additional parameters (u, v vectors)
|
||
- Hidden dim 256: +512 params
|
||
- Hidden dim 512: +1024 params
|
||
**Total**: Negligible (~0.1% increase)
|
||
|
||
### Computation Cost
|
||
Per forward pass: 2-3 power iterations
|
||
- Each iteration: 2 matrix-vector multiplies + 2 normalizations
|
||
- Asymptotic: O(d²) where d = hidden_dim
|
||
**Overhead**: ~5-10% training time increase
|
||
|
||
### Convergence
|
||
- Typically converges in 1-3 power iterations
|
||
- Can start with n_iters=1, increase if unstable
|
||
- Track ||σ_new - σ_old|| to verify convergence
|
||
|
||
---
|
||
|
||
## Integration Points
|
||
|
||
### Current Architecture
|
||
```rust
|
||
// ml/src/dqn/rainbow_network.rs
|
||
- ✅ LayerNorm (lines 44, 59)
|
||
- ✅ Dropout (lines 40, 55)
|
||
- ✅ NoisyLinear (line 14)
|
||
- 🆕 SpectralNorm (proposed wrapper)
|
||
```
|
||
|
||
### Recommended Wrapper
|
||
```rust
|
||
pub struct SpectralNoisyLinear {
|
||
noisy_linear: NoisyLinear,
|
||
spectral_norm: Option<SpectralNorm>, // Enable/disable
|
||
}
|
||
|
||
impl Module for SpectralNoisyLinear {
|
||
fn forward(&self, x: &Tensor) -> Result<Tensor> {
|
||
let weight = if let Some(sn) = &mut self.spectral_norm {
|
||
sn.normalize_weights(self.noisy_linear.weight())?
|
||
} else {
|
||
self.noisy_linear.weight().clone()
|
||
};
|
||
// Use normalized weight...
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## References
|
||
|
||
### Papers
|
||
1. **Miyato et al. (2018)** - "Spectral Normalization for GANs"
|
||
- Original algorithm, power iteration method
|
||
|
||
2. **Gouk et al. (2021)** - "Regularization via Lipschitz Constants"
|
||
- Theoretical foundations
|
||
|
||
3. **Yoshida & Miyato (2017)** - "Spectral Norm for DRL"
|
||
- Application to reinforcement learning
|
||
|
||
### Code Examples
|
||
- Power iteration: `ml/src/regime/transition_matrix.rs:273`
|
||
- Eigenvalue estimation: `ml/src/checkpoint/enterprise_implementations.rs:308`
|
||
|
||
---
|
||
|
||
## Decision Checklist
|
||
|
||
Before implementing, confirm:
|
||
- [ ] Overfitting is measurably severe (validation >> training)
|
||
- [ ] Team approved 5-8 days development time
|
||
- [ ] Performance overhead (5-10%) acceptable
|
||
- [ ] Current regularization proven insufficient
|
||
- [ ] Alternative simple solutions tried
|
||
|
||
If all checked → **IMPLEMENT**
|
||
If any unchecked → **CONSIDER ALTERNATIVES**
|
||
|
||
---
|
||
|
||
**Full Research**: See `spectral_normalization_research.md`
|
||
**Agent**: Research Agent 15
|
||
**Status**: ✅ Research Complete, Awaiting Decision
|