Interactive web application for building, training, and testing Artificial Neural Networks from scratch using Python and NumPy.
🎉 Professional Implementation: Modern architecture with ES6 modules, PostCSS build system, Clean Architecture, and SOLID principles.
ann-from-scratch/
├── backend/ # Python/Flask Backend
│ ├── core/ # ⚙️ ML Algorithms (Pure Python/NumPy)
│ │ ├── neural_network.py # Main NeuralNetwork class
│ │ ├── activation_functions.py # Sigmoid, ReLU, Softmax, Linear, Threshold
│ │ ├── loss_functions.py # MSE, Binary/Categorical Cross-Entropy
│ │ ├── optimizers.py # GD, SGD, Momentum
│ │ └── __init__.py
│ │
│ ├── services/ # 🔧 Business Logic Layer
│ │ ├── network_service.py # Network building & management
│ │ ├── training_service.py # Training orchestration & metrics
│ │ ├── data_service.py # Data processing & validation
│ │ └── __init__.py
│ │
│ ├── api/ # 🌐 REST API Layer
│ │ ├── routes/ # API Endpoints
│ │ │ ├── network_routes.py # /build_network, /network_info
│ │ │ ├── training_routes.py # /train, /backpropagation, /update_weights
│ │ │ ├── prediction_routes.py # /predict, /forward_pass
│ │ │ ├── example_routes.py # /quick_start_binary, /quick_start_multiclass
│ │ │ └── __init__.py
│ │ ├── middleware/ # Error Handling
│ │ │ ├── error_handler.py
│ │ │ └── __init__.py
│ │ ├── app.py # Flask Application Factory
│ │ └── __init__.py
│ │
│ ├── utils/ # 🛠️ Utilities
│ │ ├── validators.py # Input validation
│ │ ├── data_processor.py # Data transformations
│ │ └── __init__.py
│ │
│ ├── config.py # Configuration (Dev, Prod, Test)
│ └── __init__.py
│
├── frontend/ # HTML/CSS/JavaScript Frontend
│ ├── static/
│ │ ├── css/
│ │ │ ├── src/ # 📝 Source CSS (Modular)
│ │ │ │ ├── base/
│ │ │ │ │ ├── variables.css # CSS custom properties
│ │ │ │ │ ├── reset.css # CSS reset & base styles
│ │ │ │ │ ├── layout.css # Page layout & structure
│ │ │ │ │ └── utilities.css # Animations & modals
│ │ │ │ ├── components/
│ │ │ │ │ └── network-canvas.css # Network visualization styles
│ │ │ │ ├── features/
│ │ │ │ │ └── app-features.css # App-specific UI styles
│ │ │ │ └── main.css # Imports all CSS modules
│ │ │ └── dist/ # ⚡ Built CSS (Generated by PostCSS)
│ │ │ └── style.css # Compiled & minified CSS
│ │ │
│ │ └── js/ # 📦 JavaScript (ES6 Modules)
│ │ ├── modules/ # Feature Modules
│ │ │ └── network/
│ │ │ └── network-builder.js # Interactive network visualization
│ │ ├── utils/ # Shared Utilities
│ │ │ ├── api-client.js # Centralized backend communication
│ │ │ └── formatters.js # Number formatting utilities
│ │ ├── config/
│ │ │ └── constants.js # Application constants
│ │ ├── app.js # 🚀 Main Entry Point (ES6 Module)
│ │ └── app.js.backup # Backup of original file
│ │
│ └── templates/ # Jinja2 Templates
│ ├── partials/
│ │ ├── head.html # <head> section with CSS
│ │ ├── navbar.html # Navigation bar
│ │ ├── hero.html # Hero section
│ │ ├── steps.html # Progress indicator
│ │ ├── footer.html # Footer
│ │ ├── modal.html # Modal dialogs
│ │ └── scripts.html # JavaScript includes
│ └── index.html # Main page with 7 interactive tabs
│
├── .dockerignore # Docker build context exclusions
├── .gitignore # Git ignore rules
├── docker-compose.yml # 🐳 One-command container orchestration
├── Dockerfile # 🐳 Multi-stage build (Node CSS + Python app)
├── package.json # 📦 Node.js dependencies (PostCSS build)
├── postcss.config.js # PostCSS configuration
├── requirements.txt # 🐍 Python dependencies
├── run.py # Application entry point
├── run.bat # Windows batch launcher
├── README.md # This file
└── CLAUDE.md # AI assistant project guidance
- Clean Architecture: Core → Services → API layer separation
- SOLID Principles: Applied throughout the codebase
- ES6 Modules: Modern JavaScript with import/export
- PostCSS Build System: Modular CSS compiled to single optimized file
- Design Patterns: Strategy, Factory, Facade
- Flexible Architecture: Build custom networks with any layer configuration
- Activation Functions: Sigmoid, ReLU, Softmax, Linear, Threshold
- Loss Functions: MSE, Binary Cross-Entropy, Categorical Cross-Entropy
- Optimizers: Gradient Descent (GD), SGD, Momentum
- Smart Initialization: Xavier/He initialization prevents vanishing/exploding gradients
- Visual Network Builder: Drag-and-drop interface to create connections
- Real-time Training: Watch loss decrease during training
- 7 Interactive Tabs: Build → Dataset → Forward → Loss → Epoch → Train → Results
- Responsive Design: Works on desktop and mobile (DaisyUI + Tailwind CSS)
- Step-by-Step Workflow: Guided learning experience
- Network Visualization: Interactive canvas showing nodes and connections
- Training Charts: Loss curves with Chart.js
- Evaluation Metrics: Accuracy, Precision, Recall, F1-score
- Confusion Matrix: Per-class performance analysis
- Layer-by-layer Inspection: View activations at each layer
The fastest way to run the app — one command, no local Python or Node.js required.
Prerequisites: Docker Desktop (includes Compose).
git clone https://github.com/yourrepo/ann-from-scratch.git
cd ann-from-scratch
docker compose upOpen http://localhost:5000 in your browser.
The multi-stage build (≈ 1–2 minutes on first run):
- Node stage — installs npm dependencies and compiles PostCSS →
dist/style.css - Python stage — installs pip dependencies and serves via gunicorn (
-w 1) in production mode
Subsequent starts re-use the cached image (a few seconds).
To stop: Ctrl+C then docker compose down.
Deployment note — single-worker only.
The app stores the active neural network as in-process state on the Flask application object (app.current_network). This is safe for a single-worker server (Flask's built-in dev server, orgunicornwith--workers 1), but will cause silent data corruption under any multi-worker WSGI deployment (e.g.gunicorn -w 4): workers share no memory, so one worker can overwrite the network while another is reading it.
Do not increase the worker count without first replacingapp.current_networkwith per-request or per-session state isolation.
CORS and cross-origin security.
CORS headers are derived from theCORS_ORIGINSconfig key (not hardcoded).
Development (python run.py): allowshttp://localhost:5000by default.
Production (wsgi.py/ Docker): emits noAccess-Control-Allow-Originheader by default (same-origin only). Override by setting theCORS_ORIGINSenvironment variable to a comma-separated list of allowed origins (e.g.CORS_ORIGINS=https://myapp.example.com).
All state-mutating POST endpoints requireContent-Type: application/json, which browsers cannot set on simple HTML-form cross-origin requests. This provides an implicit CSRF barrier even without a token-based scheme.
- Python 3.8+ with pip
- Node.js 16+ with npm (for CSS build)
-
Clone Repository
git clone https://github.com/yourrepo/ann-from-scratch.git cd ann-from-scratch -
Install Python Dependencies
# Recommended: Create virtual environment python -m venv venv # Windows venv\Scripts\activate # Linux/Mac source venv/bin/activate # Install dependencies pip install -r requirements.txt
-
Install Node.js Dependencies (for CSS build)
npm install
-
Build CSS (first time or when CSS changes)
npm run build:css
-
Install Playwright browsers (first time, for frontend tests)
npx playwright install chromium
The project uses pytest for backend unit and integration tests.
# Run all backend tests
pytest tests/backend
# Run with verbose output
pytest tests/backend -vtests/
└── backend/
├── conftest.py # Shared fixtures (make_network, xy_binary, xy_multiclass, xy_regression)
└── test_smoke.py # Smoke tests: all modules import and NeuralNetwork instantiates
| Fixture | Description |
|---|---|
make_network() |
Factory that returns a fully-wired NeuralNetwork (default: 2→4→1, sigmoid) |
xy_binary |
32-sample binary classification dataset (2 features) |
xy_multiclass |
30-sample multiclass dataset (3 features, one-hot 3 classes) |
xy_regression |
20-sample regression dataset (2 features, continuous targets) |
All fixtures are seeded (seed=42) for reproducibility.
The project uses Playwright for end-to-end frontend tests.
# Run the full e2e test suite (starts Flask server automatically)
npm run test:e2e
# Run with browser UI visible (useful for debugging)
npx playwright test --headed
# View the HTML test report after a run
npx playwright show-reporttests/
└── frontend/
├── _helpers.js # Shared page helpers
└── smoke.spec.js # Smoke test: homepage loads correctly
To wire this into a CI provider (GitHub Actions, GitLab CI, etc.), add a step that:
- Installs dependencies:
npm install - Installs the browser:
npx playwright install chromium - Installs Python dependencies:
pip install -r requirements.txt - Runs the suite:
npm run test:e2e
The webServer option in playwright.config.js starts the Flask server automatically before the tests run, so no manual server management is needed in CI.
# Start Flask development server
python run.py
# Or on Windows
run.batOpen your browser to http://localhost:5000
-
Build Network (Tab 1)
- Click "Binary Classification (3-4-1)" or "Multi-Class (3-4-2)" for quick start
- Or build custom network using visual builder
- Click "Build Network" button
-
Load Dataset (Tab 2)
- Upload CSV file, or
- Click "Load Example Dataset"
- Click "Save Dataset & Continue"
-
Forward Pass (Tab 3)
- Click "Run Forward Pass"
- View predictions and layer activations
-
Calculate Loss (Tab 4)
- Select loss function
- Click "Calculate Loss"
-
Run Epoch (Tab 5)
- Configure learning rate and optimizer
- Click "Run 1 Epoch"
- See backpropagation and weight updates
-
Train (Tab 6)
- Set number of epochs
- Click "Start Training"
- Watch real-time progress
-
View Results (Tab 7)
- See loss curves
- Review metrics and confusion matrix
from backend.core import NeuralNetwork
import numpy as np
# Create network
network = NeuralNetwork()
network.add_layer(2, 'linear') # 2 inputs
network.add_layer(2, 'sigmoid') # 2 hidden neurons
network.add_layer(1, 'sigmoid') # 1 output
# Set connections (fully connected)
network.set_connections(
1, [[0,1], [0,1]], # Each hidden connects to both inputs
[[0.5,-0.3], [-0.4,0.6]], # Weights
[0.1, -0.2] # Biases
)
network.set_connections(
2, [[0,1]], # Output connects to both hidden
[[0.8,-0.5]], # Weights
[0.2] # Bias
)
# Train (AND gate example)
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [0], [0], [1]])
history = network.train(
X, y,
epochs=500,
learning_rate=0.5,
optimizer='gd',
loss_function='mse'
)
# Predict
y_pred_classes, y_pred_probs = network.predict(X)
print(f"Final Loss: {history['loss'][-1]:.6f}")
print(f"Predictions:\n{y_pred_probs}")import requests
# Load example binary network
response = requests.post('http://localhost:5000/quick_start_binary')
data = response.json()
# Train with example dataset
train_response = requests.post('http://localhost:5000/train', json={
'dataset': data['example_dataset'],
'epochs': 1000,
'learning_rate': 0.5,
'optimizer': 'gd',
'loss_function': 'binary_crossentropy'
})
result = train_response.json()
print(f"Training complete!")
print(f"Accuracy: {result['metrics']['accuracy'] * 100:.2f}%")
print(f"Final Loss: {result['final_loss']:.6f}")Network Building:
POST /build_network- Build custom networkPOST /quick_start_binary- Load binary classification example (3-4-1)POST /quick_start_multiclass- Load multi-class example (3-4-2)GET /network_info- Get current network information
Predictions:
POST /predict- Make predictions on datasetPOST /forward_pass- Get detailed layer-by-layer activations
Training:
POST /train- Train network with datasetPOST /calculate_loss- Calculate current lossPOST /backpropagation- Calculate gradients (educational)POST /update_weights- Single weight update step (educational)
- Python 3.8+ - Core language
- Flask - Web framework
- NumPy - Numerical computations
- Pandas - Data processing
- HTML5 - Markup
- Tailwind CSS + DaisyUI - UI framework
- JavaScript (ES6 Modules) - Application logic
- Chart.js - Visualizations
- PostCSS - CSS processing
- Autoprefixer - Browser compatibility
- cssnano - CSS minification
MIT License - Free to use for educational and commercial purposes.
Inspired by best practices from:
- Robert C. Martin - Clean Architecture & SOLID Principles
- Gang of Four - Design Patterns
- Martin Fowler - Refactoring
- Miguel Grinberg - Flask Web Development
- Create an issue on GitHub for bugs or questions
- See
CLAUDE.mdfor AI assistant guidance - Check inline code documentation for implementation details
Built with ❤️ for Deep Learning Education
Learn by building. Understand by implementing. Master by teaching.