You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Keras将ResNet适配到时间序列数据?

Hey there! I totally get where you're coming from—adapting ResNet from 2D image tasks to 1D time series classification can feel a bit daunting at first, since most pre-built implementations are tailored for images. But the good news is it’s just a matter of swapping out 2D layers for their 1D equivalents and tweaking the residual connection logic to fit sequential data. Let’s break this down step by step.

Step 1: Build the 1D Residual Block

The core of ResNet is the residual block, which lets the model learn identity mappings (making it easier to train deeper networks). For time series, we’ll replace every Conv2D with Conv1D, keep BatchNormalization (it works for any dimension), and adjust the shortcut path to handle changes in sequence length or feature count.

Here’s the code for a basic 1D residual block:

from tensorflow.keras import layers, Model

def residual_block_1D(inputs, filters, stride=1):
    # Main path: two consecutive 1D convolutions
    x = layers.Conv1D(filters, kernel_size=3, strides=stride, padding='same')(inputs)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    
    x = layers.Conv1D(filters, kernel_size=3, strides=1, padding='same')(x)
    x = layers.BatchNormalization()(x)
    
    # Shortcut path: adjust dimensions if needed to match the main path
    shortcut = inputs
    if stride != 1 or inputs.shape[-1] != filters:
        # Use a 1x1 convolution to resize the shortcut
        shortcut = layers.Conv1D(filters, kernel_size=1, strides=stride, padding='same')(inputs)
        shortcut = layers.BatchNormalization()(shortcut)
    
    # Add the shortcut to the main path and activate
    x = layers.add([x, shortcut])
    x = layers.Activation('relu')(x)
    return x
Step 2: Assemble the Full 1D ResNet Model

Now we’ll stack these residual blocks to create a complete ResNet architecture, starting with an initial convolution and pooling layer, then ending with a global average pooling and classification head.

This example mimics ResNet18 (4 groups of 2 residual blocks each), but you can adjust the number of blocks or filters for your specific task:

def build_resnet1D(input_shape, num_classes):
    # Input layer: expects (timesteps, features)
    inputs = layers.Input(shape=input_shape)
    
    # Initial convolution to extract low-level features
    x = layers.Conv1D(64, kernel_size=7, strides=2, padding='same')(inputs)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.MaxPooling1D(pool_size=3, strides=2, padding='same')(x)
    
    # Stack residual blocks
    # First block group: 64 filters
    x = residual_block_1D(x, 64, stride=1)
    x = residual_block_1D(x, 64, stride=1)
    
    # Second block group: 128 filters (downsample with stride=2)
    x = residual_block_1D(x, 128, stride=2)
    x = residual_block_1D(x, 128, stride=1)
    
    # Third block group: 256 filters
    x = residual_block_1D(x, 256, stride=2)
    x = residual_block_1D(x, 256, stride=1)
    
    # Fourth block group: 512 filters
    x = residual_block_1D(x, 512, stride=2)
    x = residual_block_1D(x, 512, stride=1)
    
    # Global average pooling to reduce sequence to a single vector
    x = layers.GlobalAveragePooling1D()(x)
    # Classification head
    outputs = layers.Dense(num_classes, activation='softmax')(x)
    
    # Create and return the model
    model = Model(inputs=inputs, outputs=outputs)
    return model
How to Use This Model

Let’s say you have univariate time series data with 100 time steps per sample, and you’re classifying into 5 categories. Here’s how you’d initialize and compile the model:

# Define your input shape: (number_of_timesteps, number_of_features)
input_shape = (100, 1)
num_classes = 5

# Build the model
model = build_resnet1D(input_shape, num_classes)

# Compile with appropriate loss and optimizer
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# Check the model architecture
model.summary()
Key Tips for Time Series Adaptation
  • Input Reshaping: Make sure your data is in the shape (samples, timesteps, features). For univariate data, use np.expand_dims(your_data, axis=-1) to add the feature dimension.
  • Kernel Size: Choose a kernel size that aligns with your time series patterns—common choices are 3, 5, or 7 (e.g., a kernel size of 3 looks at 3 consecutive time steps).
  • Downsampling: Use stride=2 in residual blocks to reduce the sequence length gradually, which helps the model capture higher-level patterns.
  • Batch Normalization: Keep this in place—it stabilizes training by normalizing layer inputs, just like in 2D ResNets.

内容的提问来源于stack exchange,提问作者Pavithran Ravichandiran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:28:11