feat(ml): WAVE 29 DQN Codebase Cleanup & Refactoring Campaign
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>
This commit is contained in:
198
docs/codebase-cleanup/spectral_norm_quick_ref.md
Normal file
198
docs/codebase-cleanup/spectral_norm_quick_ref.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user