NARX
Keras
Machine Learning
Time Series
Neural Networks

NARX implementation using keras

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Nonlinear autoregressive models with exogenous inputs, or NARX models, predict a future output from two kinds of history: past values of the output itself and past values of external driving signals. In practice, a Keras implementation usually turns that idea into a supervised learning problem over lagged windows.

That means the hard part is usually not the neural network layer choice. It is building the training matrix so each sample contains the right slices of past output and exogenous input values.

What a NARX Model Uses

A NARX-style predictor estimates the next output from:

  • previous output values
  • previous exogenous input values

For example, if you are predicting system temperature, your model might use:

  • past temperatures
  • past heater power settings
  • past ambient conditions

One common implementation does not use a special built-in Keras NARX layer. Instead, it creates lagged features and trains a standard dense network or sequence model.

Building Lagged Training Windows

Suppose y is the target series and u is the exogenous input series. We can prepare samples by concatenating the last ny values of y and the last nu values of u.

python
1import numpy as np
2
3def make_narx_dataset(y, u, ny=3, nu=3):
4    X = []
5    targets = []
6    start = max(ny, nu)
7
8    for t in range(start, len(y)):
9        y_lags = y[t - ny:t]
10        u_lags = u[t - nu:t]
11        X.append(np.concatenate([y_lags, u_lags]))
12        targets.append(y[t])
13
14    return np.array(X, dtype=np.float32), np.array(targets, dtype=np.float32)
15
16
17y = np.array([10, 11, 13, 12, 14, 15, 16, 18], dtype=np.float32)
18u = np.array([1, 0, 1, 1, 0, 1, 0, 1], dtype=np.float32)
19
20X, target = make_narx_dataset(y, u, ny=3, nu=3)
21print(X.shape)
22print(target.shape)

This converts a sequential problem into a normal supervised learning dataset.

Training a Keras Model

Once the lagged matrix is prepared, a small feedforward network is often enough for a basic NARX implementation:

python
1import numpy as np
2import tensorflow as tf
3
4def make_narx_dataset(y, u, ny=5, nu=5):
5    X = []
6    targets = []
7    start = max(ny, nu)
8
9    for t in range(start, len(y)):
10        y_lags = y[t - ny:t]
11        u_lags = u[t - nu:t]
12        X.append(np.concatenate([y_lags, u_lags]))
13        targets.append(y[t])
14
15    return np.array(X, dtype=np.float32), np.array(targets, dtype=np.float32)
16
17
18timesteps = 300
19u = np.sin(np.linspace(0, 12, timesteps)).astype(np.float32)
20y = np.zeros(timesteps, dtype=np.float32)
21
22for t in range(2, timesteps):
23    y[t] = 0.6 * y[t - 1] - 0.2 * y[t - 2] + 0.5 * u[t - 1]
24
25X, target = make_narx_dataset(y, u, ny=5, nu=5)
26
27model = tf.keras.Sequential([
28    tf.keras.layers.Input(shape=(10,)),
29    tf.keras.layers.Dense(32, activation="relu"),
30    tf.keras.layers.Dense(16, activation="relu"),
31    tf.keras.layers.Dense(1),
32])
33
34model.compile(optimizer="adam", loss="mse")
35model.fit(X, target, epochs=20, batch_size=16, verbose=0)
36
37prediction = model.predict(X[:5], verbose=0)
38print(prediction[:, 0])

This is a practical NARX-style model even though the network itself is a standard multilayer perceptron.

Open-Loop Versus Closed-Loop Thinking

During training, many NARX workflows use true past outputs from the dataset. That is sometimes called open-loop training. At inference time, if you predict multiple future steps, you may feed the model's own previous predictions back into the lag window. That becomes closed-loop forecasting.

The distinction matters because models often perform better in one-step prediction than in multi-step recursive forecasting. Error can accumulate once predicted outputs replace real historical outputs.

When to Use Recurrent Layers

You can also implement a NARX-like predictor with sequence models such as LSTM or GRU, but the conceptual core is the same: the model still needs access to output history and exogenous input history.

For many industrial or control-style NARX problems, explicitly engineered lag windows plus a dense network are easier to debug than a more opaque recurrent architecture.

Common Pitfalls

  • A lag window that accidentally includes the target at time t leaks future information and invalidates training results.
  • One-step prediction accuracy does not guarantee stable multi-step closed-loop forecasting.
  • Random train-test splitting can mislead on time-series data; keep temporal order in validation.
  • Using one arbitrary lag size for both output and exogenous inputs is convenient but not always appropriate.

Summary

  • A NARX model predicts future output from past outputs and past exogenous inputs.
  • In Keras, the usual implementation is a lagged supervised dataset plus a normal neural network.
  • Data preparation is the critical step; the model only works if lag windows are built correctly.
  • One-step training and recursive forecasting are different evaluation scenarios.
  • A simple dense network is often a practical starting point for NARX-style prediction.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.