wikillm

Paper · 2025-12-07 · cs.LG, cs.AI, cs.RO

A Novel Deep Neural Network Architecture for Real-Time Water Demand Forecasting

Short-term water demand forecasting with a small GRU network (DCGRU) whose inputs add k-means class features (m=4), plus an EDCGRU variant that inserts one virtual value between readings to reduce error at extreme points. Author-reported one-step MAPE 1.26-1.31% on two district metering areas, with AIC about six times lower than a GRUN baseline.

Time series forecastingRecurrent neural network (RNN)k-means clusteringData augmentationtime-seriesforecastinggruwater-demand

arXivPDFMarkdown14 min read

AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

Water utilities need to know how much water customers will use in the next quarter hour, so they can run pumps ahead of demand. This paper builds a small neural network that predicts that number from the recent history of readings.

Two ideas make it work. First, the readings are sorted into a few groups by size (a standard clustering method), and the group each reading falls into is handed to the network as an extra hint. Second, a single made-up reading is placed between every pair of real readings. This smooths out the sharp jumps in demand, which are the moments where forecasts usually go most wrong.

The network stays small, so it has far fewer settings to learn than the comparison model. The price is longer training when the made-up readings are added.

TL;DR

  • Forecasts water demand 15 minutes ahead from the previous 24 hours of readings, in two modes: one step, and 96 steps fed back iteratively §3.2.
  • Adds k-means class features (m = 4) to each reading and feeds 96 rows into a dense block and a small GRU block (DCGRU, 4,187 parameters) §3.3 §3.4 tab. 5.
  • The EDCGRU variant inserts ρ = 1 virtual value between readings, which doubles the input to 192 rows and raises training time §3.5 §4.2.
  • Author-reported MAPE for DCGRU is 1.26–1.50% across two DMAs, against 2.06–4.96% for the GRUN baseline tab. 6. Results come from one data set, so treat them as unverified elsewhere.

Problem

Short-term water demand forecasting underpins control of water supply systems. The authors name three obstacles for deep-learning models: model size (time and space complexity), error that accumulates over multi-step forecasts when predictions are fed back in, and large errors at extreme points where demand changes sharply from one period to the next §1. They argue that models already in the literature rarely address the third problem, and that the second is usually handled by adding parameters §1.

The data are 15-minute demand totals from two district metering areas (DMAs), one residential and one industrial, collected in 2016 §3.1 tab. 1. The paper uses only the demand history as input, because other factors such as weather are hard to collect in real time §1 §3.3.

Method

Data. Total demand for each DMA is recorded every 15 minutes, giving 96 readings per day. The database is refreshed once every 24 hours, so the most recent day of actual values is not available during a live forecast §3.1. Each DMA has 25,000 readings. The first 22,500 form the training set (15% of it is held out for validation); the last 2,500 form the test set §3.1.

Scenarios. Scenario 1 is one-step forecasting: all required history is actual. Scenario 2 forecasts 96 steps (24 hours) iteratively. Only the first step sees actual values; later steps use earlier predictions §3.2.

Step 1: classify the history. The history is grouped with k-means on the one-dimensional demand values into m classes. The class count m is chosen from an elbow plot of the within-cluster error; the authors report m = 4 for both DMAs §3.3 fig. 3 §4.1. Initial centres are drawn at random around the data mean, scaled by the data standard deviation §3.3 eq. 3. The within-cluster error is the quantity plotted for the elbow §3.3 eq. 1.

Step 2: build input rows. Each reading becomes one row holding its demand value and m class features, so a window is 96 rows of m + 1 values. The text says the class feature is set as in the membership indicator of eq. 2 (1 if the reading belongs to the class, else 0) §3.3. See Pitfalls.

Step 3: DCGRU forward pass. The dense block applies three time-distributed dense layers to every row separately, producing one value per row. The GRU block then reads those 96 values in order §3.4.1 §3.4.2. The GRU update follows eq. 4 to eq. 6:

z_t = \sigma_g (W_z x_t + U_z h_{t-1} + b_z) eq. 4

r_t = \sigma_g (W_r x_t + U_r h_{t-1} + b_r) eq. 5

h_t = (1 - z_t) \odot h_{t-1} + z_t \odot \sigma_h (W_h x_t + U_h (r_t \odot h_{t-1}) + b_h) eq. 6

Here σ_g is the sigmoid and σ_h is tanh §3.4.2. The hidden GRU layer has 32 units and a single-unit GRU cell gives the output, with a linear output function tab. 5 §4.1.

Pseudocode
# DCGRU one-step forecast  [§3.4] [tab. 5]
# Input:  window (96, m + 1), each row = value + class features
# Output: scalar demand for the next 15-minute period
def dcgru_forecast(window, params):
    # Per-row dense layers: 5 -> 50 -> 10 -> 1  [tab. 5]
    hidden = relu(window @ params.w1 + params.b1)   # (96, 50)
    hidden = relu(hidden @ params.w2 + params.b2)   # (96, 10)
    sequence = hidden @ params.w3 + params.b3       # (96, 1)
    # Hidden GRU layer over the 96 values, 32 units  [§3.4.2] [tab. 5]
    states = gru_layer(sequence, params.gru_hidden)   # (96, 32)
    # Single-unit GRU output cell, linear output  [§4.1]
    return gru_cell(states, params.gru_output)[-1]

Step 4: EDCGRU (data expansion). Between every two consecutive actual readings, ρ virtual values are inserted and classified with the same k-means step. The window grows to 96(ρ + 1) rows §3.5. The authors choose ρ = 1 as the best value they tried, and state that more virtual values did not help §4.2 §6 §7. In Scenario 1 the model predicts the virtual value first, then the actual value. In Scenario 2 it predicts 96(ρ + 1) values in a row and keeps every (ρ + 1)-th one as the forecast §3.5 §4.2.

Pseudocode
# Expand the series with virtual values  [§3.5]
# Input:  actual readings (T,), rho virtual values per gap
# Output: expanded series (T + (T - 1) * rho,)
def expand_series(readings, rho):
    expanded = []
    for each pair (a, b) of consecutive readings:
        # Insert rho virtual values between a and b; the method of
        # generating them is not stated (see Pitfalls)  [§3.5]
        expanded.append(a)
        expanded.extend(virtual_values(a, b, rho))
    expanded.append(readings[-1])
    return expanded

Training. All models use Xavier uniform initialisation and Adam, with mini-batches, and the training data are reshuffled after every epoch §3.6. Training stops early when the validation error rises for two consecutive epochs for DCGRU, or four for EDCGRU §3.6.1 §3.6.2.

Pseudocode
# Mini-batch Adam training with early stopping  [§3.6] [tab. 4]
# Input:  training windows, validation windows
# Output: trained weights
def train(model, train_set, val_set):
    for epoch in range(max_epochs):
        # Reshuffle the training windows every epoch  [§3.6]
        shuffle(train_set)
        for batch in batches(train_set, size=100):
            # Average the prediction error over the batch, then
            # back-propagate it  [§3.6]
            loss = mean_error(model(batch.x), batch.y)   # loss not stated
            update_adam(model, loss, lr=0.002, beta1=0.9, beta2=0.999)
        # Stop when validation error rises for two epochs in a row
        # (DCGRU; four for EDCGRU)  [§3.6.1] [§3.6.2]
        if validation_error_rising(val_set, patience=2):
            break
    return model

Baselines. BGRU is the DCGRU GRU block without the class features, with a 32-unit hidden GRU layer and one output cell §3.7.1 fig. 2. GRUN is the model of Guancheng2018: three GRU branches over lagged readings (recent, near and distant lags of 5 values each), seven dense layers and a correction dense layer for Scenario 2 §3.7.2 tab. 2 tab. 3. The paper also lists six published one-step results from other methods (SVM, ELM, LSTM and others) for comparison §3.7 tab. 7.

Evaluation. Forecast accuracy is MAE and MAPE on the 2,500 test records §3.8. Complexity is the corrected Akaike Information Criterion (AIC) with n = 25,000 observations, k the number of weights and biases, and RSS the sum of squared output errors §3.8 eq. 7 eq. 8. The correction is used because n/k falls between 1 and 40 §3.8.

AIC = n \ln\left(\frac{RSS}{n}\right) + 2k eq. 7

AIC = n \ln\left(\frac{RSS}{n}\right) + 2k + \frac{2k(k+1)}{n - k - 1} eq. 8

Training time is measured on the training and validation data, and forecast time is averaged over 1,000 repeats per scenario §3.8.

Data set table. tab. 1

StatisticDMA1 (residential)DMA2 (industrial)
Readings25,00025,000
Minimum (m³/15 min)30.040.0
Quartile 0.255664
Median8689
Quartile 0.7594104
Maximum157.0149.0
Mean81.487.0
Standard deviation24.421.1
Mode9292
Skewness−0.478−0.116
Kurtosis−1.07−1.23

Hyperparameters

NameValueWhereNotes
Sampling interval15 min§3.1Total demand for the whole DMA
Input window96 rows (last 24 h)§3.2 §3.4.1Each row holds value + m class features
Classes m4§4.1 fig. 3Chosen by elbow plot; SSE values not tabulated
Virtual values per gap ρ1§4.2EDCGRU only
Dense layer 150 units, ReLUtab. 5Input is 5 features per row
Dense layer 210 units, ReLUtab. 5§4.1 text says linear; see Pitfalls
Dense layer 31 unit, lineartab. 5 §4.1Output (96, 1)
GRU hidden layer32 units; sigmoid inner, tanh outputtab. 5 §4.1Unit count "as suggested" in §3.4.2
GRU output cell1 unit; sigmoid inner, linear outputtab. 5 §4.1
Weight initialisationXavier uniform§3.6 tab. 4
OptimiserAdam; β1 = 0.9, β2 = 0.999§3.6.1ε not stated
Learning rate, DCGRU0.002 (DMA1); 0.001 (DMA2)§3.6.1 tab. 4Chosen from values near 0.001
Learning rate, EDCGRU0.002, halved every 5 epochs§3.6.2
Learning rate, BGRU0.001 (both DMAs)§3.7.1
Learning rate, GRUN0.002 (DMA1); 0.001 (DMA2)tab. 4
Batch size100 (BGRU, DCGRU, EDCGRU); 60 (GRUN)tab. 4
Epochs (final)DCGRU 15 / 18; EDCGRU 17 / 21; BGRU 19 / 23; GRUN 16 / 20§3.6.1 §3.6.2 tab. 4DMA1 / DMA2
Early-stop toleranceDCGRU 2 epochs; EDCGRU 4 epochs§3.6.1 §3.6.2
Validation split15% of training data§3.1Random or time-ordered not stated
Train / test split22,500 / 2,500 records§3.1Position of the split not stated
Parameter count kDCGRU 4,187; EDCGRU 4,187; BGRU 3,366; GRUN 30,403§4.2 tab. 6Verified below
Loss functionnot stated§3.6
Feature scaling / normalisationnot stated—
Grid-search rangesnot stated§3.4.1Only "small number of units" preferred

The stated count k = 4,187 for DCGRU can be reproduced from tab. 5 (derived, not in the paper): time-distributed dense layers 5→50, 50→10 and 10→1 give 300 + 510 + 11 parameters; the 32-unit GRU with one input gives 3 × 32 × (1 + 32 + 1) = 3,264; the one-unit output GRU with 32 inputs gives 3 × 1 × (32 + 1 + 1) = 102. The total is 4,187, which matches tab. 6.

Results

Author-reported. Setup: two DMAs in one Chinese city, 2016 data, training and testing on the same DMA, 2,500-record test window, CPU only (Intel Core i7 laptop, 16 GB RAM, Python 3.6, Keras with a TensorFlow backend) §2. The paper does not state library versions §2.

Headline comparison, from tab. 6 and §4.2:

  • DCGRU one-step MAPE: 1.26% (DMA1) and 1.31% (DMA2), against GRUN at 2.06% and 2.46% tab. 6.
  • DCGRU 96-step MAPE: 1.50% and 1.38%, against GRUN at 4.33% and 4.96% tab. 6.
  • EDCGRU MAPE: 0.98% and 0.99% one-step; 1.03% and 1.04% 96-step tab. 6.
  • AIC: DCGRU 20,633 and 29,396; GRUN 172,225 and 176,019 tab. 6 §4.2.

Full evaluation table tab. 6. Each cell gives DMA1 / DMA2.

ParameterBGRUDCGRUGRUNEDCGRU
k3,3664,18730,4034,187
AIC51,915 / 74,86520,633 / 29,396172,225 / 176,0199,176 / 11,873
S1 MAE (m³/15 min)1.91 / 3.220.92 / 1.111.58 / 2.000.59 / 0.63
S2 MAE (m³/15 min)3.69 / 5.961.01 / 1.173.64 / 4.030.72 / 0.73
S1 MAPE (%)2.49 / 3.581.26 / 1.312.06 / 2.460.98 / 0.99
S2 MAPE (%)5.11 / 7.031.50 / 1.384.33 / 4.961.03 / 1.04
Training time (s)205 / 248192 / 23480 / 105850 / 1,055
Forecast time (ms), S1 / S27.31 / 735.17.65 / 757.361.04 / 105.4216.8 / 1,712.8

S1 = Scenario 1 (one step), S2 = Scenario 2 (96 steps). tab. 6

Comparison with published one-step and 96-step results tab. 7. These come from different data sets, horizons and time resolutions, so they are not a controlled comparison.

ResearchTechnologyScenarioMAPEAIC
Antunes2018Ensemble of ANN, SVM, k-NN and random forest regressorsOne-step daily9.1%Not discussed
Brentan2017SVM plus a Fourier-based methodOne-step daily3.41%Not discussed
Mouatadid2017ELMOne-step daily9.7%Not discussed
Tiwari2016ELM combined with a wavelet-based ANNOne-step daily6.09%Not discussed
Candelieri2017CSVMClustering-enhanced SVMOne-step hourly5.9%Not discussed
Du2021LSTMWavelet-transform and PCA preprocessing feeding an LSTMOne-step daily1.83%Not discussed
Guancheng2018GRUNOne-step quarterly2.06%179,019
Guancheng2018GRUN96-step quarterly4.33%179,019
This paperGRU with k-means classesOne-step quarterly1.31%29,396
This paperGRU with k-means classes96-step quarterly1.5%29,396

tab. 7. The "This paper" rows mix DMA2 one-step (1.31%) with DMA1 96-step (1.50%) tab. 6.

Figures fig. 5–fig. 12 plot predictions and absolute errors for each DMA and scenario, before and after data expansion. They are described in the text only; no numeric values are read from them. fig. 1 is a map of the two DMAs; fig. 2 and fig. 4 are the BGRU and DCGRU structures; fig. 3 is the elbow plot used to pick m = 4 §4.1.

Training-time results: the authors report that GRUN trains faster than their model, owing to a 15-value input against 96 for DCGRU and BGRU and 192 for EDCGRU §4.2 §5.

Paper vs code

No official code.

Search, in order: the paper text, abstract and arXiv metadata contain no repository or project page link [raw/arxiv/2512.06714.json]. A GitHub search for "DCGRU" returned two unrelated repositories (DCGRU in the diffusion- convolution sense, not this model). A search for "water demand forecasting GRU k-means" returned none. A search for "Salloom water demand" returned none, and a user search for "Salloom" returned 14 accounts that could not be tied to the authors. No repository could be attributed to the authors, so none was used.

Pitfalls

  • Loss, scaling and optimiser details are missing. The loss function, the input normalisation and output denormalisation, the Adam ε and the random seed are not stated §3.6. An implementer must choose them and report the choice.
  • Class feature meaning is ambiguous. Section 3.3 says the class value is set by the membership indicator of eq. 2 (1 or 0). Taken literally, each reading then gets an indicator for each class, but the text also calls these "values of the class" §3.3. The paper does not say whether class features hold indicators, distances to centres, or the centre values.
  • k-means details are missing. The stopping rule, the tie-breaking rule and whether centres are refitted when virtual values are added are not stated §3.3 §3.5. The paper says new virtual values are classified "based on k-means" §3.5, which implies fixed centres, but this is not explicit.
  • Centre initialisation. eq. 3 writes randn(1,m) * Std + mean, which gives a vector of m values. The data are one-dimensional, so a single centre per class is what is meant. The text does not say whether Std and mean are computed per DMA or on the full data set §3.3.
  • Number of classes. m = 4 is read from the elbow plot fig. 3 §4.1. The distortion values are not tabulated, so the choice cannot be checked numerically.
  • Virtual values are not defined. The method says virtual values are inserted "to relieve nonlinearity" §3.5, but it never gives the formula. Linear interpolation is the likely reading, yet it is not stated. Whether they are placed at the midpoint or spaced evenly is also unstated.
  • Dense-block activations conflict. §4.1 says the second hidden layer uses a linear activation, while tab. 5 lists ReLU for layers 1 and 2 and linear for layer 3. The text in §3.4.1 does not settle it. This card follows the table; check against code if available.
  • Scenario 2 step count for EDCGRU. §4.2 says 196 steps. The method gives 96(ρ + 1) = 192 §3.5, and §5 gives an input of 192. The 196 is most likely a typo.
  • Validation split. The 15% validation split is not said to be random or time-ordered §3.1. For time-series data, a time-ordered split is the safer reading, but the paper does not confirm it.
  • Early-stop rule. The text describes a rule that combines falling training error and rising validation error §3.6.1. Implement it as validation-based early stopping, and note that the weights kept on stopping are not stated.
  • AIC uses in-sample error. §3.8 computes RSS over "the whole data", n = 25,000, which includes the training data. The AIC values in tab. 6 are therefore in-sample, and the comparison favours models with low training error. This is not flagged in the paper.
  • "Six times" complexity claim. From tab. 6, the AIC ratio of GRUN to DCGRU is 176,019 / 29,396 ≈ 6.0 for DMA2 and 172,225 / 20,633 ≈ 8.3 for DMA1 (derived). The parameter ratio is 30,403 / 4,187 ≈ 7.3 (derived).
  • The "30%" error reduction is not defined. The abstract and conclusion say expansion cuts error by about 30% §7. From tab. 6, EDCGRU against DCGRU gives MAPE drops of 22% and 24% for one-step, and 31% and 25% for 96-step (derived). MAE drops are 36% and 43% for one-step (derived). The paper does not say which metric the 30% refers to.
  • Claim against table. §6 says the MAE of DCGRU and EDCGRU in Scenario 1 "does not exceed 1". DCGRU's DMA2 one-step MAE is 1.11 tab. 6.
  • Typos in the conclusion. The conclusion writes "98:69%" and "98:5%" §7. These are presumably 100 − 1.31 and 100 − 1.50, but the paper does not say so. The model name is also spelled "CDGRU" and "ECDGRU" in §6.
  • Inconsistent GRUN AIC. tab. 7 gives 179,019 for GRUN, but tab. 6 gives 172,225 (DMA1) and 176,019 (DMA2). The paper does not explain the difference.
  • Are GRUN numbers re-run or quoted? The GRUN results in tab. 6 are described as produced on the same data §3.7.2. The literature rows in tab. 7 come from other data sets and horizons, so the "best MAPE" claim holds only for this data set.
  • Single data set, no public release. The data come from two DMAs, shared by a third party [Acknowledgment]. The paper gives no data release, so exact replication is not possible from the paper alone.
  • Hardware timing. Timings were measured on a CPU laptop, averaged over 1,000 forecasts §2 §3.8. They are not comparable across machines.
  • Unit count. The GRU hidden size of 32 is said to follow "previous research" §3.4.2. The cited source does not state a rule for this, so the choice rests on the grid search (not reported) §3.4.1.
  • The "nine parameters" claim. §5 says a GRU cell has nine parameters. The k values in tab. 6 match counting weights and biases for all three gates (see Hyperparameters), not nine.
  • Extreme points are evaluated visually. Improvement at extreme points is shown in figures fig. 5–fig. 12 and claimed in text §6, but no extreme-point metric is reported.

Lineage

  • Builds on: GRU recurrent cell (cited as Chung et al. 2014 for the unit-count choice §3.4.2); k-means clustering; Elbow method §3.3.
  • Compared against: GRUN (Guancheng2018) §3.7.2; BGRU, an ablation of this paper §3.7.1; published water-demand methods Antunes2018, Brentan2017, Mouatadid2017, Tiwari2016, Candelieri2017CSVM and Du2021LSTM §3.7 tab. 7.
  • Superseded by: not known from content on this wiki.

Source and license

Adapted from “A Novel Deep Neural Network Architecture for Real-Time Water Demand Forecasting” by Tony Salloom, Okyay Kaynak, Wei He (arXiv:2512.06714), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors.