PNN GridForecast β€” residential grid meter, one day ahead

Β© PreciseStatistics GmbH (Prime Neural Network). Proprietary weights, published for evaluation. Loading requires the PNN evaluation or licence package, version V4.1 or later.

A small Prime Neural Network (PNN) that forecasts the net power through one residential grid meter, every 15 minutes, one day ahead, from the day-ahead weather forecast and the calendar. This is the number an energy supplier settles on. The house has a 13.3 kWp rooftop solar array (southern France), so the meter swings between buying in the evening and exporting at midday. Nothing behind the meter is an input.

Two models, each in int8 (default) and fp32

Model Inputs Test MAE per 15 min, int8 fp32 Daily net-energy error Sign correct
hist/ (shipped) 20 weather and calendar features + 4 from the meter's own history up to day Dβˆ’2 922.7 W 922.7 W 9.53 kWh/d 93.6 %
weather/ 20 weather and calendar features 943.8 W 943.8 W 9.30 kWh/d 93.4 %

The numbers are those of the published files (seed 0 of each training run). Over three training seeds the hist model averages 912 W.

Context (same 218-day test period, 2025-12-03 β†’ 2026-07-11):

Baseline MAE
flat mean 1,811 W
standard load profile 1,085 W
gradient boosting 981 W
dense neural network (same shape) 952 W

The PNN matches the dense network of the same shape (within seed noise) with half the hidden-layer weights.

Architecture

inputs β†’ 64 β†’ [PNN 64 β†’ 64 β†’ 64 β†’ 32] β†’ 1, ReLU. The input and output layers are dense; the three hidden layers are PNN V4.1 layers at 50 % density, so each output reads 32 of its 64 inputs.

int8 (*/int8/, the default): the three PNN layers have int8 weights with one scale per output row and one static int8 input scale each, calibrated on the training days (percentile 99.99, chosen on the validation days). The small dense input and output layers stay fp32. On the test period int8 gives the same MAE as fp32 to 0.1 W, and each PNN layer run on the PNN V4.1 CPU runtime's int8 kernels equals the int8 reference (relative difference below 1e-7).

Files

Folder Weights Size
hist/int8/ int8 15.8 kB
hist/fp32/ fp32 29.4 kB
weather/int8/ int8 14.7 kB
weather/fp32/ fp32 28.4 kB

Each folder holds model.safetensors + config.json in the PNN model file format (pnn-safetensors/1, Hugging Face safetensors with a compressed-tensors style quantization_config). Each PNN layer stores only its own weights, shape (outputs, connections); int8 files add weight_scale (one per row) and input_scale. config.json also records everything needed to use the model. It states the encoding in words: pnn.requires_pnn is the minimum PNN package version (V4.1); pnn.weight_encoding and pnn.activation_encoding give sign, range, zero point and scale. For the int8 files: PNN-layer weights are signed int8 in [βˆ’127, 127], zero point 0, one fp32 scale per output row; their inputs are signed int8, zero point 0, one static fp32 scale per layer. The model itself needs:

  • features: the input order;
  • preprocessing: missing values filled with the stored medians, then standardised with the stored means and standard deviations;
  • output_scale_W: the output Γ— 10,000 is the meter power in W (positive = the household buys).

Loading

import torch, torch.nn as nn
from pnn_circulant import PNNLinearCirculant          # PNN package
from pnn_quant import load_pnn_safetensors

class Regressor(nn.Module):                            # inputs -> 64 -> [PNN 64-64-64-32] -> 1
    def __init__(self, n_in, dims=(64, 64, 64, 32)):
        super().__init__()
        self.inp = nn.Linear(n_in, dims[0])
        self.hidden = nn.ModuleList(PNNLinearCirculant(dims[i], dims[i + 1], 0.5) for i in range(3))
        self.out = nn.Linear(dims[-1], 1)
    def forward(self, x):
        x = torch.relu(self.inp(x))
        for h in self.hidden:
            x = torch.relu(h(x))
        return self.out(x).squeeze(-1)                 # x 10,000 = meter power in W

model = Regressor(n_in=24)                             # 20 for weather/
f = load_pnn_safetensors("hist/int8", model)          # or "hist/fp32"

Loaded into a float model, int8 weights are dequantised (q Γ— weight_scale). For int8 inference, also round each PNN layer's input to int8 with that layer's f.input_scales[name]; that is what the PNN CPU runtime does with its int8 kernels.

Training data and limitations

  • Data: one household, three years of 15-minute meter readings with the day-ahead weather forecast. All times UTC. Split: chronological, the last 20 % of days as the test set.
  • Scope: trained and tested on one meter. It is a demonstration of the method and of PNN layers on a small edge-sized model, not a ready model for other households. Retrain on the target meter's own data.
  • Inputs: the weather features must come from the same kind of day-ahead forecast; an observed weather feed changes the error.

Contact

Prime Neural Network Β· primeneural.net Β· info@primeneural.net

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support