From 1D-CNN temporal filters and 2D spatial-temporal kernels to Dilated Causal Convolutions (WaveNet/TCN) and end-to-end PyTorch modeling.
While Convolutional Neural Networks (CNNs) were initially popularized in computer vision, their parameter efficiency, parallel training capabilities, and translation-invariant feature extraction make them exceptionally powerful for multivariate time series (MTS). In multi-sensor telemetry, multi-lead ECGs, audio signals, and high-frequency quantitative finance, signals arrive not as isolated scalars, but as multi-channel trajectories evolving simultaneously across time.
Unlike Recurrent Neural Networks (RNNs) and LSTMs—which process time steps sequentially and suffer from vanishing gradients across long horizons—CNNs evaluate receptive fields across time concurrently. However, applying convolutions to multivariate time series requires solving a critical structural challenge: how to extract local temporal patterns within channels while simultaneously capturing cross-channel correlations without distorting the chronological order of events.
1. Mathematical Formulation: Convolving Across Time and Channels
Consider an input sample X ∈ ℝC × T, where C denotes the number of channels (variables) and T is the sequence length in discrete time steps:
X = [x1, x2, …, xT] ∈ ℝC × T
1D Convolutions with Multi-Channel Inputs (Conv1D)
In standard 1D convolutional layers, a filter kernel W has dimensions (C, K), where K is the temporal kernel size (window length). The kernel slides strictly along the time dimension, performing a dot product across all C channels simultaneously. The feature map activation at time step t for the j-th filter is defined as:
yj, t = σ( ∑c=1C ∑k=0K−1 Wj, c, k · Xc, t − k + bj )
Where σ(·) is a non-linear activation function (such as ReLU or GELU) and bj is a scalar bias term. Notice that while Conv1D compresses all C variables into a single scalar per filter at each step, it treats the spatial ordering of channels as permutation-invariant.
2. Core Architectural Paradigms for Multivariate Time Series
| Paradigm | Kernel Geometry | Channel Interaction | Best Use Case |
|---|---|---|---|
| 1D Temporal CNN | (C × K) sliding across T | Collapses all channels simultaneously at layer 1 | General sensor classification, forecasting where all channels interact globally |
| 2D Spatio-Temporal CNN | (H × K) sliding across both C and T | Preserves local channel topology (e.g., adjacent grid sensors) | Gridded sensor arrays, EEG electrode topological maps, traffic networks |
| Temporal Convolutional Networks (TCN) | Dilated causal 1D kernels with residual links | Exponentially expanding receptive field without future leakage | Long-range multivariate sequence forecasting and seq-to-seq tasks |
| Multi-Scale (InceptionTime) | Parallel 1D kernels of diverse lengths (e.g., K ∈ {10, 20, 40}) | Captures short-term spikes and long-term trends concurrently | Complex multivariate time-series classification benchmarks |
Temporal Convolutional Networks (TCNs) & Dilated Causal Convolutions
For forecasting tasks, conventional convolutions suffer from two structural flaws: they leak future information into the past, and their receptive field scales linearly with layer depth (O(L · K)). TCNs address this via two mechanisms:
- Causal Convolutions: A filter at step t can only compute operations on inputs at step t and earlier (t, t − 1, …), ensuring no information leaks from t + 1.
- Dilated Convolutions: An operational dilation factor d introduces gaps between kernel points. For a filter w with size K and dilation factor d:
By doubling the dilation factor at each successive layer (d = 1, 2, 4, 8, …), the model’s effective receptive field scales exponentially:yt = ∑k=0K−1 wk · xt − d · k
This allows deep CNNs to capture dependencies across thousands of steps with modest depth and no recurrence bottleneck.Receptive Field = 1 + ∑ℓ=0L−1 2 · (K − 1) · dℓ
3. PyTorch Implementation: 1D-CNN for Multivariate Forecasting
The following modular PyTorch implementation constructs a multi-channel 1D Convolutional Network designed to take an input tensor of shape (batch_size, channels, seq_len) and output a multi-step forecast across channels.
import torch
import torch.nn as nn
class MultivariateTimeSeriesCNN(nn.Module):
def __init__(self, in_channels: int, out_channels: int, seq_len: int, pred_len: int):
super().__init__()
self.pred_len = pred_len
self.out_channels = out_channels
# 1. Feature extraction with multi-layer 1D convolutions
self.feature_extractor = nn.Sequential(
nn.Conv1d(in_channels=in_channels, out_channels=64, kernel_size=5, padding=2),
nn.BatchNorm1d(64),
nn.ReLU(),
nn.Conv1d(in_channels=64, out_channels=128, kernel_size=5, padding=2),
nn.BatchNorm1d(128),
nn.ReLU(),
nn.AdaptiveAvgPool1d(16) # Compress temporal dimension to fixed length 16
)
# 2. Projection head to future horizon
self.head = nn.Sequential(
nn.Linear(128 * 16, 256),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(256, pred_len * out_channels)
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# Expected input shape: (batch_size, in_channels, seq_len)
batch_size = x.size(0)
features = self.feature_extractor(x) # Shape: (batch_size, 128, 16)
flat_features = features.view(batch_size, -1)
out = self.head(flat_features)
return out.view(batch_size, self.out_channels, self.pred_len)
# Verification & Dimension Check
if __name__ == "__main__":
batch, channels, seq_len, pred_len = 32, 7, 96, 24
dummy_input = torch.randn(batch, channels, seq_len)
model = MultivariateTimeSeriesCNN(
in_channels=channels,
out_channels=channels,
seq_len=seq_len,
pred_len=pred_len
)
predictions = model(dummy_input)
print(f"Input Shape : {dummy_input.shape}")
print(f"Output Shape : {predictions.shape}") # (32, 7, 24)
4. Critical Engineering Considerations
- Data Layout (Channels First vs. Channels Last): Standard deep learning libraries differ in layout expectations. PyTorch
nn.Conv1dexpects(batch_size, channels, time_steps), whereas TensorFlow/Keras expects(batch_size, time_steps, channels). Transposing tensors properly before convolutional passes is essential. - Dilated Causal Padding: When implementing causal convolutions manually, symmetric padding (
padding = kernel_size // 2) causes future-to-past data leakage. One must use asymmetric left-padding of size(kernel_size − 1) · dilationand slice off future activations. - Channel Permutation Sensitivity: While 2D-CNNs work well when channels have a physical grid geometry (such as EEG caps or weather stations), arbitrary ordering of financial or industrial variables makes 2D convolutions sensitive to row permutations. For non-spatial variables, stick to 1D multi-channel convolutions or Graph Neural Network (GNN) + CNN hybrid architectures.