ForeBlocks Custom Blocks Guide¶
This guide covers the current ForecastingModel customization points for feature preprocessing, normalization, graph blocks, and output post-processing.
Related docs: - Documentation Overview - Getting Started - Transformer - Preprocessor - DARTS
Core idea¶
ForecastingModel is a modular wrapper around an encoder/decoder/head stack.
You can inject processing blocks at stable extension points without rewriting training code.
Supported forecasting strategies¶
seq2seqautoregressivedirecttransformer_seq2seq
Supported model types¶
lstmtransformerinformer-likehead_only
Processing blocks (constructor)¶
from foreblocks import ForecastingModel
model = ForecastingModel(
encoder=...,
decoder=...,
forecasting_strategy="seq2seq",
model_type="lstm",
target_len=24,
output_size=1,
input_preprocessor=..., # default: Identity
input_normalization=..., # default: Identity
output_block=..., # default: Identity
output_normalization=..., # default: Identity
output_postprocessor=..., # default: Identity
input_skip_connection=False,
)
Block order¶
input_preprocessor- optional input skip connection
input_normalization- encoder/decoder (or direct head path)
output_blockoutput_normalizationoutput_postprocessor
Add/replace blocks after model creation¶
Use add_head(...) to modify blocks in-place.
Valid position values¶
encoderdecoderattentioninputoutputinput_normoutput_normhead
import torch.nn as nn
model.add_head(nn.LayerNorm(64), position="input_norm")
model.add_head(nn.Sequential(nn.Linear(1, 1)), position="output")
Remove with:
Inspect with:
Graph block injection¶
Register graph modules at these stages:
pre_encoderpost_encoderpost_decoder
Expected graph block interface:
- inputs: (x, adj)
- x shape: [B, T, N, F] or [B, N, F]
- adj shape: [N, N] or [B, N, N]
Minimal custom preprocessor example¶
import torch
import torch.nn as nn
class ConvPre(nn.Module):
def __init__(self, in_features: int, hidden: int):
super().__init__()
self.net = nn.Sequential(
nn.Conv1d(in_features, hidden, kernel_size=3, padding=1),
nn.GELU(),
nn.Conv1d(hidden, in_features, kernel_size=1),
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# x: [B, T, F]
y = x.transpose(1, 2)
y = self.net(y)
return y.transpose(1, 2)
model = ForecastingModel(
encoder=...,
decoder=...,
forecasting_strategy="seq2seq",
model_type="lstm",
target_len=24,
output_size=1,
input_preprocessor=ConvPre(in_features=8, hidden=32),
input_skip_connection=True,
)
Practical recommendations¶
- Start with identity blocks and add one custom block at a time.
- Enable
input_skip_connection=Truewhen your preprocessor is aggressive. - For long horizons, pair custom blocks with transformer backbones (
transformer_seq2seq). - Keep post-processing simple (monotonic constraints, scaling, clipping) and test it independently.
Version notes¶
This page reflects the current foreblocks.core.model.ForecastingModel API.
If you are migrating from older examples that mention TimeSeriesSeq2Seq, switch to ForecastingModel.