CO5420: Neural Networks & Deep Learning β Course Project
Department of Computer Engineering, Faculty of Engineering, University of Peradeniya, Sri Lanka
π₯ Project Team & Contributors

Team VectorX
Faculty of Engineering, University of Peradeniya
Team Members
Project Supervisors
π Table of Contents
- Executive Summary
- Project Progression & Breakthroughs
- Dataset & Problem Formulation
- Advanced Feature Engineering Pipeline
- Model Architectures
- Convex SLSQP Ensembling & Blending
- Experimental Results & Benchmark Tracking
- Hardware Acceleration & Compute Infrastructure
- Repository Structure
- Getting Started & Reproduction
- Academic Links & Resources
π Executive Summary
Airborne fine particulate matter with aerodynamic diameter under 2.5 micrometers (PM2.5) constitutes a severe public health hazard, penetrating deep into human pulmonary and cardiovascular systems. Due to turbulent boundary-layer meteorology, complex photochemical transformations, wind transport kinematics, and sharp seasonal heating shifts, predicting hourly PM2.5 concentrations is an inherently non-linear spatio-temporal challenge.
This project engineer delivers a state-of-the-art forecasting system trained on multi-year hourly observational data across 12 national air quality monitoring stations in Beijing.
Starting from standard recurrent neural network baselines (LSTM, GRU, BiLSTM with RMSE 15.09 β 15.71), our solution progressed into an industry-grade Advanced SOTA Pipeline combining:
- Atmospheric Physics & Chemistry Domain Feature Engineering (166+ features including wind vector decomposition, Magnus relative humidity, dew point depression, ventilation index, and photochemical ratios).
- Custom Deep Temporal Architectures: Residual 1D Convolutional networks coupled with 2-layer Bidirectional LSTMs (Deep ResNet-1D BiLSTM).
- Hardware Acceleration: Mixed-precision CUDA acceleration on NVIDIA RTX 6000 Ada Generation (48 GB VRAM) with an in-memory streaming pipeline.
- Convex SLSQP Ensemble Blending: Achieving a top clean and verified benchmark score of 14.04457 (Test 3) and an Out-Of-Fold RMSE of 14.14202.
π Project Progression & Breakthroughs
flowchart TD
A[Initial RNN Baselines<br/>BiLSTM / GRU / LSTM<br/>RMSE: 15.09670] --> B[Exploratory Iterations<br/>Batch 32, Preprocessing, Augmentation<br/>RMSE: 15.16 - 15.71]
B --> C[Advanced Pipeline Test 1<br/>166 Domain Features + 4-Model Ensemble<br/>RMSE: 14.36675]
C --> D[Advanced Pipeline Test 2<br/>5-Model SLSQP Blending<br/>Score: 13.90609 - Weight Bug Identified]
D --> E[Advanced Pipeline Test 3<br/>Pure CPU Multi-Core SOTA Pipeline<br/>RMSE: 14.04457 π Best Verified]
E --> F[Advanced Pipeline Test 4 & 5<br/>NVIDIA RTX 6000 Ada GPU In-Memory<br/>RMSE: 14.29812]
π Dataset & Problem Formulation
1. Dataset Overview
The dataset contains continuous, multi-year hourly meteorological and air pollutant records across 12 air quality monitoring stations in Beijing:
- Monitoring Stations: Aotizhongxin, Changping, Dingling, Dongsi, Guanyuan, Gucheng, Huairou, Nongzhanguan, Shunyi, Tiantan, Wanliu, Wanshouxigong.
- Pollutants: PM2.5, PM10, SO2, NO2, CO, O3.
- Meteorological Factors: Temperature (TEMP), Atmospheric Pressure (PRES), Dew Point (DEWP), Precipitation (RAIN), Wind Direction (wd), Wind Speed (WSPM).
- Scale: Over 315,648 hourly training observations.
2. Task Formulation
Given an hourly sliding observation window $X_{t-24:t}$ over the preceding 24 hours of atmospheric and chemical observations at station $s$, forecast the 1-hour ahead particulate concentration:
\[\hat{y}_{t+1} = f(X_{t-24:t}, s)\]- Evaluation Metric: Root Mean Squared Error (RMSE)
π¬ Advanced Feature Engineering Pipeline
The final pipeline converts raw multivariate inputs into an information-dense 166-dimensional feature space grounded in atmospheric science and time-series kinematics:
| Category | Engineered Features | Domain Rationale / Mathematical Formula |
|---|---|---|
| Wind Vector Kinematics | Wx, Wy |
Decomposes circular wind angle $\theta$ into orthogonal Cartesian velocities:Wx = WSPM * sin(ΞΈ), Wy = WSPM * cos(ΞΈ) |
| Physical Meteorology | dew_point_depression, relative_humidity, ventilation_index |
β’ Dew Point Depression: ΞT = TEMP - DEWPβ’ Magnus Relative Humidity (RH): RH = 100 * exp((17.625 * DEWP) / (243.04 + DEWP) - (17.625 * TEMP) / (243.04 + TEMP))β’ Ventilation Index: VI = WSPM * (ΞT + 15.0)
|
| Photochemical & Particle Ratios | PM2.5 / PM10, PM2.5 / CO, NO2 / O3, coarse_pm |
β’ Coarse particulate separation: coarse_pm = max(PM10 - PM2.5, 0)β’ Combustion efficiency & secondary aerosol proxy ratios |
| Cyclical Trigonometric Time | hour_sin, hour_cos, month_sin, month_cos, dayofweek_sin, dayofweek_cos |
Continuous periodic coordinate representations preserving cyclical boundaries (23:00 to 00:00; Dec to Jan). |
| Seasonal Indicator | is_heating_season |
Binary indicator for central urban heating season (NovemberβMarch) reflecting major coal emission shifts. |
| Temporal Lags | PM2.5_lag_1 to PM2.5_lag_24 |
Autoregressive memory at 1, 2, 3, 4, 5, 6, 12, 18, and 24-hour delays. |
| Velocity & Acceleration | PM2.5_diff_k, PM2.5_accel, PM2.5_diff_ratio |
β’ 1st order velocity: diff_k = x_t - x_{t-k} for $k \in \{1, 2, 3, 4, 6, 12, 24\}$β’ 2nd order acceleration: (x_t - x_{t-1}) - (x_{t-1} - x_{t-2})β’ Relative surge rate: (x_t - x_{t-1}) / (x_{t-1} + 1)
|
| Multi-Window Rolling Statistics | Mean, Std, Min, Max, Range, Deviations | Rolling windows over 3h, 6h, 12h, and 24h to capture sudden accumulation spikes. |
| Exponential Moving Averages | PM2.5_ema_3, PM2.5_ema_6, PM2.5_ema_12 |
Decaying-weight smoothing tracking immediate concentration momentum. |
| Target Encodings | station_target_mean, station_target_std |
Out-of-fold historical station baseline distributions mitigating spatial bias. |
π§ Model Architectures
1. PyTorch Deep ResNet-1D BiLSTM
To leverage both localized feature abstractions and long-range sequential memory, we designed a custom Deep ResNet-1D BiLSTM in PyTorch:
- Input Projection: Linear layer projecting 166 input dimensions to a 256-dimensional latent space.
- Residual Blocks (
ResNet1DBlock): Two stacked residual blocks with identity skip connections: \(\mathbf{h}_{\text{res}} = \text{ReLU}\left(\mathbf{W}_2 \cdot \text{ReLU}(\mathbf{W}_1 \mathbf{h} + \mathbf{b}_1) + \mathbf{b}_2 + \mathbf{h}\right)\) - Bidirectional Temporal Core: 2-layer Bidirectional LSTM ($128$ hidden units per direction, dropout = 0.2) capturing bidirectional sequential dynamics.
- Regression Head: Multi-layer perceptron (
Linear(256 -> 128)βReLUβDropout(0.1)βLinear(128 -> 64)βReLUβLinear(64 -> 1)). - Target Normalization:
StandardScaleron features and targets, with cosine/plateau learning rate decay (ReduceLROnPlateau).
2. TensorFlow/Keras Bidirectional LSTM & GRU Baseline
Built in Air_Pollution_Forecasting_Using_Temporal_NN_new.ipynb for initial benchmark analysis:
- Station-aware Sequence Generator: Generates 24-hour temporal arrays without crossing station boundaries (
(Samples, 24, 43)). - BiLSTM Model:
Input (24, 43)βBidirectional(LSTM(128, return_sequences=True))βDropout(0.2)βBidirectional(LSTM(64))βDense(64, activation='relu')βDense(1) - BiGRU Model:
Input (24, 43)βBidirectional(GRU(128, return_sequences=True))βDropout(0.2)βBidirectional(GRU(64))βDense(64, activation='relu')βDense(1) - Target Compression: $\log(1 + y)$ target transformation with
np.log1pto stabilize high-value outlier gradients.
3. Gradient Boosted Decision Trees (GBDTs)
- LightGBM Regressor: Fast histogram-based gradient boosting (
learning_rate=0.025,num_leaves=63,max_depth=8,colsample_bytree=0.65,subsample=0.8). - XGBoost Regressor: GPU-accelerated histogram algorithm (
tree_method='hist',learning_rate=0.025,max_depth=8,reg_alpha=0.5,reg_lambda=1.5). - CatBoost Regressor: Symmetric oblivious tree boosting robust against categorical overfitting (
iterations=105000with 100-round early stopping,learning_rate=0.025,depth=8). - ExtraTrees Regressor: Extremely randomized trees (
n_estimators=300,max_depth=16) providing uncorrelated ensemble diversity.
βοΈ Convex SLSQP Ensembling & Blending
Rather than naive uniform averaging, we applied Sequential Least Squares Programming (SLSQP) convex optimization to find the mathematically optimal weight vector $\mathbf{w} = [w_1, w_2, \dots, w_M]^T$:
\[\min_{\mathbf{w}} \sqrt{\frac{1}{N} \sum_{i=1}^N \left( y_i - \sum_{m=1}^M w_m \hat{y}_{i, m} \right)^2} \quad \text{subject to} \quad \sum_{m=1}^M w_m = 1, \quad 0 \le w_m \le 1 \quad \forall m\]| Model Component | Out-of-Fold (OOF) RMSE | SLSQP Optimal Weight |
|---|---|---|
| CatBoost Regressor | 14.34932 | 35.46% |
| LightGBM Regressor | 14.38512 | 30.47% |
| XGBoost Regressor | 14.46854 | 17.79% |
| PyTorch ResNet-BiLSTM | 15.75860 | 16.28% |
| ExtraTrees Regressor | 16.08155 | 0.00% |
| Optimal Hybrid Ensemble (OOF) | 14.14202 | 100.00% |
β οΈ Diagnostic Note on Test 2 (13.90609): In Test 2, a weight convergence anomaly was identified during diagnostic evaluation. Hence, Test 3 (
14.04457) stands as our verified, reproducible, and clean production benchmark.
π Experimental Results & Benchmark Tracking
| Experiment | Architecture & Strategy Highlights | Validation / Test RMSE | Key Observations |
|---|---|---|---|
| Baseline 3-Model | Keras BiLSTM + GRU + Ensemble Baseline | 15.09670 |
Standard 24h sliding window with raw tabular features. |
| Batch 32 Test | Batch size reduced from 64 to 32 | 15.46692 |
Increased stochastic gradient noise degraded generalization. |
| Preprocessing Exp 1 | Station interpolation + one-hot encodings | 15.59510 |
Imputation without physical wind decomposition plateaued. |
| Preprocessing Exp 2 | Extra pollutant polynomial combinations | 15.71107 |
Feature collinearity without regularizers led to drift. |
| Augmentation Exp | Training distribution expansion | 15.16439 |
Improved extreme tail behavior but lacked lag velocities. |
| Advanced Test 1 | 166 Physics Features + 5-Fold LightGBM, XGBoost, CatBoost, CNN-BiGRU | 14.36675 |
Major breakthrough: RMSE dropped by > 0.73. |
| Advanced Test 2 | 5-Model SLSQP Blending | 13.90609* |
Experimental: Weight adjustment issue identified. |
| Advanced Test 3 π | Pure CPU Multi-Threaded SOTA Pipeline with Checkpoints | 14.04457 |
Best Verified Benchmark: Fully reproducible with complete domain physics features. |
| Advanced Test 5 | NVIDIA RTX 6000 Ada In-Memory Pipeline | 14.29812 |
105,000 estimators with strict patience early stopping. |
| Advanced Test 7 | Alternate validation weighting setup | 14.55754 |
Robust baseline cross-validation comparison. |
β‘ Hardware Acceleration & Compute Infrastructure
Training 105,000 boosting estimators across 5 folds and deep recurrent neural networks over 315,000+ time-series records demands specialized compute:
- GPU Compute: NVIDIA RTX 6000 Ada Generation (Compute Capability 8.9)
- VRAM: 47.37 GB GDDR6 with Error-Correcting Code (ECC)
- Software Stack: Python 3.12, PyTorch 2.1.3+cu130, CUDA 13.0
- CPU Optimizations: OpenMP thread management (
n_jobs=8) on LightGBM to prevent thread lock contention. - In-Memory Streaming: Fold predictions cached directly in high-speed unified GPU memory to eliminate disk I/O bottlenecks.
π Repository Structure
Air-Pollution-Forecasting-Using-Temporal-NNs/
β
βββ README.md # Root repository documentation
βββ powershell.cmd # Environment execution shim
β
βββ docs/ # π Live GitHub Pages Documentation
β βββ README.md # Site home page
β βββ _config.yml # Jekyll site configuration
β βββ images/ # Assets (Banner, Logo, SVGs)
β β βββ VectorX.png # Official Team Logo
β β βββ project_banner.svg # High-res project banner
β β βββ architecture_pipeline.svg # Model architecture
β β βββ ensemble_weights.svg # SLSQP weights breakdown
β β βββ benchmark_chart.svg # Experimental performance chart
β βββ data/ # Portal metadata & cover images
β βββ index.json # Project card metadata
β βββ cover_page.jpg # Panoramic cover banner (940x352)
β βββ thumbnail.jpg # Project thumbnail (640x360)
β
βββ code/ # π¬ Core Codebase & Experimental Pipelines
βββ train_raw.csv # Primary Beijing air quality dataset
βββ Air_Pollution_Forecasting_Using_Temporal_NN_new.ipynb # RNN Baseline (LSTM, GRU, BiLSTM)
β
βββ advanced pipeline model/ # π SOTA High-Performance Pipeline
β βββ test 1/ # 166 Features + 4-Model Ensemble (14.36675)
β βββ test 2/ # 5-Model SLSQP Ensemble (13.90609)
β βββ test 3/ # Pure CPU SOTA Pipeline (14.04457 π)
β βββ test 4/ # GPU Ada CUDA Diagnostics
β βββ test 5/ # In-Memory GPU Ada Pipeline (14.29812)
β βββ test 7/ # Alternative Validation Setup (14.55754)
β
βββ 3 model/ # Baseline 3-model exploration
βββ 3 model with 32 batch/ # Batch size 32 test
βββ new mdel with pre processing steps/ # Preprocessing iteration 1
βββ add more pre procesing steps/ # Preprocessing iteration 2
βββ increased train data with test data/ # Augmented training set test
π οΈ Getting Started & Reproduction
1. Environment Setup
# Clone the repository
git clone https://github.com/cepdnaclk/e22-co542-Air-Pollution-Forecasting-Using-Temporal-NNs-Team-VectorX.git
cd e22-co542-Air-Pollution-Forecasting-Using-Temporal-NNs-Team-VectorX/code
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install required dependencies
pip install lightgbm xgboost catboost scikit-learn pandas numpy torch tensorflow matplotlib seaborn scipy joblib
2. Running the Verified SOTA Pipeline (Recommended)
Open code/advanced pipeline model/test 3/new-cpu-pipeline.ipynb to execute the verified CPU benchmark:
jupyter notebook "advanced pipeline model/test 3/new-cpu-pipeline.ipynb"
3. Running the GPU High-Power Pipeline (CUDA Mode)
Open code/advanced pipeline model/test 5/gpu_ada (2).ipynb in a CUDA-enabled GPU environment:
jupyter notebook "advanced pipeline model/test 5/gpu_ada (2).ipynb"
π Academic Links & Resources
- Project Repository
- Live Project Page
- Department of Computer Engineering
- Faculty of Engineering, University of Peradeniya
- University of Peradeniya
Developed with β€οΈ by Team VectorX for Academic & Research Excellence in Neural Networks and Environmental Intelligence.