# FedQAP Experiments

This directory contains experiment scripts for running FedQAP with different time series forecasting models.

## Available Models

| Model | Description |
|-------|-------------|
| **SpikeRNN** | Spiking neural network for time series forecasting |
| **iTransformer** | Inverted transformer architecture |
| **Spikformer** | Spike-based transformer model |
| **TimeMixer** | Time mixing neural network |
| **DLinear** | Decomposition linear model |

## Files

### Individual Model Scripts
- `run_spikernn.py` - Run SpikeRNN experiment
- `run_itransformer.py` - Run iTransformer experiment
- `run_spikformer.py` - Run Spikformer experiment
- `run_timemixer.py` - Run TimeMixer experiment
- `run_dlinear.py` - Run DLinear experiment

### Batch Scripts
- `run_all_models.py` - Run all models sequentially
- `fedqap_experiments.ipynb` - Jupyter notebook for interactive experiments

## Usage

### 1. Run Individual Model

```bash
cd experiments
python run_spikernn.py
```

### 2. Run All Models

**⚠️ Warning**: This takes several hours!

```bash
cd experiments
python run_all_models.py
```

### 3. Interactive Jupyter Notebook

```bash
cd experiments
jupyter notebook fedqap_experiments.ipynb
```

## Configuration

All scripts use the following default configuration:

```python
{
    "dataset": "electricity",
    "num_clients": 20,
    "max_features": 20,
    "window": 96,
    "horizon": 48,
    "batch_size": 128,
    "global_epochs": 50,
    "local_epochs": 1,
    "lr": 1e-3,
    "optimizer": "adam",
    "dim": 128,
    "early_stop": True,
    "patience": 10
}
```

## Customization

To modify experiment settings, edit the `sys.argv` configuration in each script:

```python
sys.argv = [
    "main.py",
    "--dataset", "electricity",
    "--model_name", "spikernn",
    "--dim", "256",          # Change hidden dimension
    "--lr", "5e-4",          # Change learning rate
    "--global_epochs", "100", # Change number of epochs
    # ... other parameters
]
```

## Local-Only Training

To run without federation (local training only), add the `--local_only` flag:

```python
sys.argv.extend(["--local_only"])
```

## Results

Results are saved in the `../output/` directory with the following structure:

```
output/
├── electricity_spikernn_50global_96-48_dim128/
│   ├── results/
│   │   ├── meta.json
│   │   ├── global_best.pth
│   │   └── client_*_best.pth
│   └── tb_logs/
└── electricity_itransformer_50global_96-48_dim128/
    ├── results/
    └── tb_logs/
```

## Visualization

Use TensorBoard to compare results:

```bash
# Compare all experiments
tensorboard --logdir=../output/

# View specific experiment
tensorboard --logdir=../output/electricity_spikernn_50global_96-48_dim128/

# Open http://localhost:6006
```

## Tips

1. **GPU Memory**: If you encounter CUDA out of memory errors, reduce `--batch_size`
2. **Training Time**: Use `--early_stop` and adjust `--patience` to control training duration
3. **Reproducibility**: Keep `--seed` consistent across experiments for fair comparison
4. **Monitoring**: Use TensorBoard to monitor training progress in real-time

## Experiment Naming Convention

Experiment names follow the pattern:
```
{dataset}_{model}_{global_epochs}global_{window}-{horizon}_dim{hidden_dim}
```

Example: `electricity_spikernn_50global_96-48_dim128`