Evaluating Convolutional Dynamic Models#

This page explains how to run inference (evaluation) on trained NeurEco Convolutional Dynamic models.

Understanding Convolutional Dynamic Evaluation#

Convolutional Dynamic models use a sliding window to process time-series data. Unlike ODE models, they need no initialization data: the model makes its first prediction as soon as a full window of inputs is available.

Key characteristics:

  • No initialization data needed

  • The first window_size - 1 time steps cannot be predicted: the model needs a full window of past inputs before it produces an output, so a sequence of N time steps gives N - window_size + 1 predictions, the first one at the window_size-th time step

  • The model predicts every time step, whatever the window_stride used for training

  • Simpler evaluation workflow than ODE models

Note

The GUI’s evaluation export accounts for the window: the exported file contains input steps - window_size + 1 rows and its time column starts at the time of the window_size-th input step, so the leading unpredicted steps are not included. The Python evaluate method returns the same rows.

Evaluating a Convolutional Dynamic Model#

Loading a Model

  1. Open your project or load a saved model

  2. Switch to the Evaluation panel

Providing Evaluation Data

  1. Click + next to Evaluation files

  2. Select your input (excitation) file

  3. Optionally select an output file (for comparison/metrics)

Running Evaluation

  1. Click Evaluate

  2. View results in the plot panel

  3. Use the Sample slider to browse through sequences

  4. Compare predictions (blue) with reference (orange) if provided

If the input and reference output files do not have the same number of rows, the evaluation still runs and the status bar warns that the plots compare the available data only.

Metrics

Switch to the Metrics panel to see:

  • L2 relative error for each output

  • Per-sequence error breakdown

  • Training vs. validation vs. test performance

Method Reference#

predictions = model.evaluate(
    excitations=None,   # Input array(s), time in column 0
    *,
    time=None,          # Deprecated: separate time array(s)
)

Parameters:

Parameter

Required

Description

excitations

Yes

Input array(s) with time in the first column. Shape (n_samples, 1 + n_inputs) or a list of such arrays.

time

No

Deprecated (keyword-only). Separate time array(s); emits a DeprecatedParameterWarning and returns predictions without a leading time column.

Returns:

  • Single sequence: NumPy array of shape (n_samples - window_size + 1, 1 + n_outputs), with time in the first column: one row per predicted time step, from the window_size-th time step on

  • Multiple sequences: List of such NumPy arrays

Note

When excitations carries the time in its first column, the returned predictions are time-first (time in column 0). The deprecated separate-time form returns predictions without a leading time column.

Complete Evaluation Example#

import numpy as np
from NeurEco import NeurEcoDynamic as Dynamic

# Load model
model = Dynamic.ConvolutiveDynamic()
model.load("my_convolutive_model.ecnn")

# Get model information
window_size = model.get_window_size()
print(f"Window size: {window_size}")

# Prepare test data (time in column 0)
dt = 0.01
time = np.arange(0, 10, dt)
eval_exc = np.column_stack([time, np.random.randn(len(time), 3)])
reference_outputs = np.column_stack([time, np.random.randn(len(time), 2)])

# Evaluate
# eval_exc has time in its first column; predictions are returned time-first.
predictions = model.evaluate(eval_exc)

# Align the reference with the predictions (window drops the leading steps)
aligned_ref = reference_outputs[window_size - 1:]

# Compute error (compute_error takes outputs only: drop the leading time column)
error = model.compute_error(predictions[:, 1:], aligned_ref[:, 1:])
print(f"L2 relative error: {error:.6f}")

# Per-output analysis (column 0 is time, so outputs start at column 1)
for i in range(1, predictions.shape[1]):
    output_error = np.sqrt(np.mean((predictions[:, i] - aligned_ref[:, i])**2))
    print(f"Output {i - 1} RMSE: {output_error:.6f}")

Model Information#

# Number of inputs and outputs
print(f"Inputs: {model.get_input_count()}")
print(f"Outputs: {model.get_output_count()}")

# Window size used during training
print(f"Window size: {model.get_window_size()}")

Comparison with ODE Evaluation#

Aspect

Convolutional Dynamic

ODE

Initialization

Not required

Required (explicit or steady-state)

Start of the sequence

First window_size - 1 time steps not predicted

Initial conditions

Memory

Window history

Hidden states

Output length

Input length minus window_size - 1 steps

Matches input length

Note

In both solutions the model’s internal memory is managed automatically and is not exposed to the user.

Best Practices#

  1. Match time step: The evaluation time step must match the training time step

  2. Provide enough history: The first window_size - 1 time steps are not predicted, so start the input data window_size - 1 time steps before the first time you need a prediction for

  3. Handle multiple sequences: Use list format for batch evaluation of multiple sequences

  4. Validate window size: Check that your evaluation data has enough time steps for the model’s window size

Next Steps#