An implementation of Augmented Population-Based Training (APBT) - a hyperparameter optimization and neural architecture search algorithm that evolves neural networks through competitive training.
Your dashboard is running at: http://localhost:8501
- Open http://localhost:8501 in your browser
- Configure: Iris dataset, 40 networks, 100 epochs
- Click "
βΆοΈ Start Training" - Watch neural networks compete and evolve in real-time!
- Iris (150 samples, 4 features, 3 classes) - Classic flower classification
- Tennis (14 samples, 4 features, 2 classes) - Weather prediction
- Identity (100 samples, 5 features, 5 classes) - Synthetic dataset
- MNIST (10,000 samples, 784 features, 10 classes) - Handwritten digits (requires setup)
- Fashion MNIST (10,000 samples, 784 features, 10 classes) - Clothing items (requires setup)
python download_mnist.py # Download real MNIST & Fashion MNIST data
streamlit run app.py # Start dashboardconda activate torch
streamlit run app.py- What is APBT?
- Dashboard Features
- Installation
- Usage
- How It Works
- Understanding the Algorithm
- Visualization Guide
- Advanced Topics
- Examples & Results
Augmented Population-Based Training combines three powerful ideas:
- Multiple neural networks (population of 20-100) train in parallel
- Networks compete for survival based on performance
- Bottom 20% copy weights from top 20% (exploitation)
- Automatic hyperparameter optimization
- Networks can dynamically add/remove units
- Finds optimal topology automatically
- Balances accuracy vs complexity
Fitness Function: f(accuracy, size) = 1.09^(accuracyΓ100) / 1.02^size
- Rewards accuracy exponentially
- Penalizes large models
- Finds the optimal tradeoff automatically
Initialize Population (random hyperparameters & architectures)
β
βββββββββββββββββββββββββββββββββββββββ
β For each epoch: β
β 1. Train all networks (parallel) β
β 2. Evaluate fitness β
β 3. Update leaderboard β
β 4. Exploit (copy winners) β
β 5. Explore (mutate & try new) β
βββββββββββββββββββββββββββββββββββββββ
β
Return Best Network
Result: Automatically discovers optimal hyperparameters AND architecture without manual tuning!
The Streamlit dashboard provides 5 comprehensive visualization tabs:
- Real-time performance metrics
- Accuracy evolution (best vs most accurate)
- Model size changes over time
- Average population statistics
- Live progress bar
- Top 20 networks ranked by performance
- Gold/Silver/Bronze highlighting
- Full hyperparameter details
- Population distribution histograms
- Watch exploitation events happen!
- Interactive network topology visualization
- Layer-by-layer breakdown
- Parameter counts
- Color-coded nodes (input/hidden/output)
- See optimal structure emerge
- Learning rate evolution
- Momentum tracking
- Weight decay changes
- Statistics with deltas
- Understand adaptation patterns
- 3D surface plot (interactive, rotatable!)
- Accuracy vs Size tradeoff visualization
- Current best network position marked
- Population scatter plot (Pareto front)
- Color-coded by rank
- Python 3.8+
- Conda (recommended)
# Activate your environment
conda activate torch
# Install required packages
pip install streamlit pandas numpy plotlyOr use the requirements file:
pip install -r requirements.txtStart the interactive dashboard:
conda activate torch
streamlit run app.pyThen open http://localhost:8501 in your browser.
Dashboard Configuration:
- Dataset: Choose from Iris, Tennis, Identity, MNIST, or Fashion MNIST
- Population Size: 10-500 networks (40 recommended, 20 for MNIST)
- Epochs: 10-1000 (100+ for good results, 50+ for MNIST)
- Advanced Settings: Learning rate range, readiness threshold (defaults to 5% of epochs), truncation %
Note: MNIST and Fashion MNIST use 784 input features (28x28 images), so training takes longer. The app automatically adjusts default parameters for these datasets.
Run training from the command line:
python source/main.py \
-a data/iris/iris-attr.txt \
-d data/iris/iris-train.txt \
-t data/iris/iris-test.txt \
-w models/weights.txt \
-k 40 \
-e 100 \
--debugArguments:
-a, --attributes: Path to attributes file (required)-d, --training: Path to training data (required)-t, --testing: Path to test data (optional)-w, --weights: Path to save weights (optional)-k, --k-inds: Population size (required)-e, --epochs: Number of epochs (required)--debug: Enable debug output (optional)
Pre-configured experiments:
python source/testIris.py
python source/testTennis.py
python source/testIdentity.pyFeed-forward neural network with backpropagation:
- Flexible topology:
[input, hidden1, hidden2, ..., output] - Hyperparameters: learning rate, momentum, decay
- Activation: Sigmoid function
- Training: Stochastic Gradient Descent (SGD)
Population-based training manager:
- Initialization: Create k networks with random hyperparameters & architectures
- Training: Each network trains for 1 epoch per iteration
- Evaluation: Fitness = f(accuracy, model_size)
- Exploitation: Bottom 20% copy from top 20% (every ~5% of total epochs by default)
- Exploration: Perturb hyperparameters (Γ0.8 or Γ1.2) and architecture (Β±1 unit)
# Hyperparameter Ranges
LR_RANGE = (1e-4, 1e-1) # Learning rate
M_RANGE = (0.0, 0.9) # Momentum
D_RANGE = (0.0, 0.1) # Decay
HL_RANGE = (1, 4) # Hidden layers
HUPL_RANGE = (2, 10) # Units per layer
# Algorithm Parameters
READINESS = 5% of epochs # Epochs before exploitation (dynamic)
TRUNC = 0.2 # Top/bottom 20%
PERTS = (0.8, 1.2) # Perturbation factors
X, Y = 1.09, 1.02 # Fitness function factorsdef f(accuracy, size):
return 1.09 ** (accuracy * 100) / 1.02 ** sizeExamples:
- Network A: 95% acc, 100 params β fitness = 4,371 β
- Network B: 98% acc, 200 params β fitness = 3,812
- Network C: 90% acc, 50 params β fitness = 3,103
Network A wins! Best balance of accuracy and size.
Every ~5% of total epochs (configurable), if a network is in the bottom 20%:
if my_rank > 80th_percentile:
top_performer = random.choice(top_20%)
copy(top_performer.weights)
copy(top_performer.hyperparameters)Why it works:
- Poor performers don't waste time training from scratch
- Copies proven successful configurations
- Maintains diversity by choosing randomly from top 20%
After exploitation, explore nearby solutions:
# Hyperparameter perturbation (Β±20%)
learning_rate *= random.choice([0.8, 1.2])
momentum *= random.choice([0.8, 1.2])
decay *= random.choice([0.8, 1.2])
# Architecture perturbation (Β±1 unit)
random_layer = pick_random_hidden_layer()
random_layer.units += random.choice([-1, 0, 1])
# Adjust weights accordingly
if added_unit:
add_new_random_weights()
elif removed_unit:
delete_associated_weights()Why it works:
- Small changes prevent wild swings
- Explores nearby solutions
- Maintains good performance while searching
Generation 0 (Random initialization):
- Network #27: [4,8,4,3] - 38% accuracy, performance: 18.7 (Best)
- Network #12: [4,3,7,3] - 35% accuracy, performance: 15.3
- Network #35: [4,2,9,6,3] - 33% accuracy, performance: 12.1
Generation 50 (Learning & exploitation):
- Network #27: [4,8,4,3] - 89% accuracy, performance: 1,285 (Still best)
- Network #12: [4,8,4,3] - 87% accuracy, performance: 1,103 (Copied #27!)
- Network #8: [4,7,5,3] - 85% accuracy, performance: 978
Generation 200 (Converged):
- Network #27: [4,7,5,3] - 97% accuracy, performance: 5,820 (Evolved!)
- Network #12: [4,7,5,3] - 96% accuracy, performance: 5,231
- Network #8: [4,7,5,3] - 96% accuracy, performance: 5,231
Result: Population discovers optimal architecture: [4, 7, 5, 3]
Sudden performance jumps at readiness intervals (default: every 5% of total epochs)
- Bottom 20% of networks copy weights from top 20%
- Performance chart shows dramatic vertical jumps
- Leaderboard shows major reshuffling
- This is "survival of the fittest" in action!
Model size fluctuations throughout training
- Networks add/remove units during exploration
- Size chart shows spikes and dips
- Eventually converges to optimal complexity
- Shows the architecture search process
Distribution narrowing over time
- Early training: Wide spread in leaderboard, diverse architectures
- Mid training: Some clustering, common patterns emerging
- Late training: Tight cluster, similar architectures
- Population agrees on optimal solution
The fitness landscape shows the optimization objective:
- X-axis: Accuracy (%)
- Y-axis: Model Size (parameters)
- Z-axis: Fitness value
- Peak: Optimal accuracy/size balance
- Red Diamond: Your current best network
Ideal position: Bottom-right area = High accuracy, small size!
Edit source/apbt.py line 309:
def f(self, acc, size):
# Current: Exponential reward/penalty
return self.X ** (acc * 100) / self.Y ** size
# Alternative: Stronger size penalty
# return acc ** 2 / (size ** 0.8)
# Alternative: Linear tradeoff
# return acc * 1000 - size * 0.1In the dashboard's Advanced Settings, adjust the Readiness Threshold slider. Default: 5% of total epochs (e.g., 5 epochs for 100 total, 50 epochs for 1000 total)
Or edit source/apbt.py line 73:
self.READINESS = 220 # Custom value: lower for more frequent, higher for less frequentEdit source/apbt.py line 74:
self.TRUNC = 0.2 # Try: 0.1 (top 10%), 0.3 (top 30%)- Create attribute file:
data/mydata/mydata-attr.txt - Create training file:
data/mydata/mydata-train.txt - Create test file:
data/mydata/mydata-test.txt - Add to dashboard: Edit
app.pydataset_map dictionary
Configuration:
Population: 40 networks
Epochs: 100
Time: ~2 minutes
Expected Results:
Accuracy: 94-97%
Model Size: 60-100 parameters
Best Topology: [4, 6-8, 4-6, 3]
Learning Rate: ~0.02-0.05
Configuration:
Population: 20 networks
Epochs: 100
Time: ~30 seconds
Expected Results:
Accuracy: 85-100%
Model Size: 40-60 parameters
Best Topology: [10, 3-5, 2]
Learning Rate: ~0.01-0.03
Configuration:
Population: 40 networks
Epochs: 200
Time: ~3 minutes
Expected Results:
Accuracy: 90-98%
Model Size: Variable
Best Topology: Depends on problem size
Learning Rate: ~0.03-0.07
Configuration:
Population: 20 networks (smaller due to network size)
Epochs: 50-100
Time: ~10-20 minutes
Expected Results:
Accuracy: 70-85% (with limited training)
Model Size: 2000-5000 parameters
Best Topology: [784, 32-64, 16-32, 10]
Learning Rate: ~0.001-0.01
Setup:
python download_mnist.py # Downloads real MNIST datasetConfiguration:
Population: 20 networks (smaller due to network size)
Epochs: 50-100
Time: ~10-20 minutes
Expected Results:
Accuracy: 65-80% (with limited training)
Model Size: 2000-5000 parameters
Best Topology: [784, 32-64, 16-32, 10]
Learning Rate: ~0.001-0.01
Setup: Same as MNIST - run download_mnist.py (downloads real Fashion MNIST images)
Fashion MNIST Classes:
- 0: T-shirt/top
- 1: Trouser
- 2: Pullover
- 3: Dress
- 4: Coat
- 5: Sandal
- 6: Shirt
- 7: Sneaker
- 8: Bag
- 9: Ankle boot
When using MNIST or Fashion MNIST, the dashboard includes:
Sample Image Display:
- 5 sample images displayed horizontally
- Ground truth labels shown under each image
- After training: Model predictions with confidence %
- β Green checkmark for correct predictions
- β Red X for incorrect predictions
Automatic Optimizations:
- Smaller default population (20 vs 40) for faster training
- Adjusted epoch recommendations (100-200 epochs)
- Warning about large input size (784 features)
- Real-time visualization updates during training
Data Source:
- Uses PyTorch's torchvision to download official datasets
- 10,000 training + 2,000 test samples (subsets for speed)
- Full datasets available: 60,000 training + 10,000 test images
- To use full datasets, modify
subset_size_trainandsubset_size_testindownload_mnist.py
| Method | Hyperparameters | Architecture | Parallel | Manual Tuning |
|---|---|---|---|---|
| Grid Search | β Exhaustive | β Fixed | β Yes | β Required |
| Random Search | β Random | β Fixed | β Yes | β Required |
| Bayesian Opt | β Smart | β Fixed | β No | β Required |
| NAS | β Fixed | β Search | β Yes | β Required |
| APBT | β Evolving | β Evolving | β Yes | β None! |
Advantages:
- β No manual hyperparameter tuning
- β Automatic architecture search
- β Parallel efficiency (all networks train simultaneously)
- β Multi-objective optimization (accuracy vs size)
- β Adaptive (hyperparameters evolve during training)
βββ app.py # Streamlit dashboard (600+ lines)
βββ requirements.txt # Python dependencies
βββ source/
β βββ ann.py # Neural network implementation
β βββ apbt.py # APBT algorithm
β βββ main.py # Command-line interface
β βββ utils.py # Utility functions
β βββ testIris.py # Iris experiment
β βββ testTennis.py # Tennis experiment
β βββ testIdentity.py # Identity experiment
βββ data/
β βββ iris/ # Iris dataset
β βββ tennis/ # Tennis dataset
β βββ identity/ # Identity dataset
βββ models/ # Saved weights
βββ docs/ # Original documentation
- Start Small: Use Iris dataset with 40 networks for quick experiments
- Be Patient: Real improvements often take 200+ epochs
- Watch Leaderboard: See competitive dynamics and exploitation events
- Check Architecture Tab: See how optimal network structure evolves
- Monitor Fitness Landscape: Understand why certain networks win
- Export Charts: Hover over charts and click camera icon to save
- Ensure Streamlit is running:
streamlit run app.py - Check http://localhost:8501
- Try refreshing the page
- Reduce population size (try 20)
- Reduce epochs (try 50)
- Use simpler dataset (Tennis)
# Stop
pkill -f "streamlit run app.py"
# Restart
conda activate torch
streamlit run app.pyThis implementation is based on:
- Population Based Training (DeepMind, 2017)
- Neural Architecture Search (Google Brain, 2017)
- Regularized Evolution (Google, 2019)
Key Innovation: Combines hyperparameter optimization WITH architecture search in a single unified framework.
See LICENSE file for details.
Original implementation by Josias Moukpe (Machine Learning Course, April 2022)
Interactive dashboard and comprehensive documentation added to make the algorithm accessible and understandable through beautiful visualizations.
Enjoy exploring evolutionary neural network training! π§¬π
For questions or issues, check the dashboard help tooltips or review the inline code comments.