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

基于TSMixer的时间序列序列分类TensorFlow ValueError问题求助

问题:TSMixer适配时间序列全序列二分类的形状不匹配错误

问题背景

尝试用时间序列预测架构TSMixer完成全序列二分类任务:每个时长5.5秒、128Hz采样(共704个数据点)、含3个特征的序列对应一个类别标签。

数据集生成代码

def _split_window(self, data, label):
    inputs = data[:, : self.seq_len, :]
    # 手动设置形状保留静态信息
    inputs.set_shape([None, self.seq_len, None])
    return inputs, label

def _make_dataset(self, data, label, shuffle=True,):
    data = np.array(data, dtype=np.float32)
    label = np.array(label, dtype=np.float32)
    ds = tf.keras.utils.timeseries_dataset_from_array(
        data=data,
        targets=label,
        sequence_length=self.seq_len,
        sequence_stride=1,
        shuffle=shuffle,
        batch_size=self.batch_size
    )
    ds = ds.map(self._split_window)
    return ds

生成的数据集张量规格:

train data Tensor:  <_MapDataset element_spec=(TensorSpec(shape=(None, 704, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None, 1), dtype=tf.float32, name=None))>
val data Tensor:  <_MapDataset element_spec=(TensorSpec(shape=(None, 704, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None, 1), dtype=tf.float32, name=None))>
test data Tensor:  <_MapDataset element_spec=(TensorSpec(shape=(None, 704, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None, 1), dtype=tf.float32, name=None))>

模型结构代码

def res_block(inputs, norm_type, activation, dropout, ff_dim):
    """Residual block of TSMixer."""
    norm = (
        layers.LayerNormalization
        if norm_type == 'L'
        else layers.BatchNormalization
    )

    # Temporal Linear
    x = norm(axis=-1)(inputs)
    x = ops.transpose(x, axes=[0, 2, 1])  # [Batch, Channel, Input Length]
    x = layers.Dense(x.shape[-1], activation=activation)(x)
    x = ops.transpose(x, axes=[0, 2, 1])  # [Batch, Input Length, Channel]
    x = layers.Dropout(dropout)(x)
    res = x + inputs

    # Feature Linear
    x = norm(axis=-1)(res)
    x = layers.Dense(ff_dim, activation=activation)(x)  # [Batch, Input Length, FF_Dim]
    x = layers.Dropout(dropout)(x)
    x = layers.Dense(inputs.shape[-1])(x)  # [Batch, Input Length, Channel]
    x = layers.Dropout(dropout)(x)
    return x + res

def build_model(
    input_shape,
    pred_len,
    norm_type,
    activation,
    n_block,
    dropout,
    ff_dim,
    target_slice,
):
    """Build TSMixer model."""
    inputs = tf.keras.Input(shape=input_shape)
    x = inputs  # [Batch, Input Length, Channel]
    print('inputs shape: ', x.shape)
    for _ in range(n_block):
        x = res_block(x, norm_type, activation, dropout, ff_dim)
        print('1', x.shape)
    # 原输出层:逐时间步预测
    outputs = layers.Dense(pred_len, activation='sigmoid')(x)
    # outputs = tf.reduce_mean(outputs, axis=1)
    print('outputs shape:', outputs.shape)

    return tf.keras.Model(inputs, outputs)

训练错误信息

inputs shape:  (None, 704, 3)
...
1:  (None, 704, 3)
outputs shape: (None, 704, 1)
Epoch 1/3
Traceback (most recent call last):
  File "/home/maven96/workspace/tsmixer_PR/run.py", line 342, in <module>
    main()
  File "/home/maven96/workspace/tsmixer_PR/run.py", line 287, in main
    history = model.fit(
  File "/home/maven96/workspace/venv_dir/test_env/lib/python3.10/site-packages/keras/src/utils/traceback_utils.py", line 122, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/home/maven96/workspace/venv_dir/test_env/lib/python3.10/site-packages/keras/src/backend/tensorflow/nn.py", line 689, in binary_crossentropy
    raise ValueError(
ValueError: Arguments `target` and `output` must have the same shape. Received: target.shape=(None, 1), output.shape=(None, 704)

错误原因

TSMixer原本是为时间序列逐点预测设计的,原模型最后一层layers.Dense(pred_len, activation='sigmoid')(x)会输出形状为(None,704,1)的张量(每个时间步对应一个预测),但我们的任务是全序列分类,标签形状为(None,1)(每个序列对应一个标签),两者形状不匹配导致损失计算报错。

解决思路与修改方案

核心是聚合时序维度的特征,将序列级的特征压缩为样本级的特征,再输出分类结果。具体修改如下:

修改模型构建函数

def build_model(
    input_shape,
    norm_type,
    activation,
    n_block,
    dropout,
    ff_dim,
):
    """Build TSMixer model for sequence classification."""
    inputs = tf.keras.Input(shape=input_shape)
    x = inputs  # [Batch, Input Length, Channel]
    print('inputs shape: ', x.shape)
    for _ in range(n_block):
        x = res_block(x, norm_type, activation, dropout, ff_dim)
        print('1', x.shape)
    
    # 聚合时序维度信息(二选一即可)
    # 方案1:全局平均池化,自动压缩时序维度,输出(None, 3)
    x = layers.GlobalAveragePooling1D()(x)
    # 方案2:手动计算时序维度均值,输出同样为(None,3)
    # x = tf.reduce_mean(x, axis=1)
    
    # 全连接层输出二分类结果,形状为(None,1),与标签匹配
    outputs = layers.Dense(1, activation='sigmoid')(x)
    print('outputs shape:', outputs.shape)  # 现在输出形状为(None,1)

    return tf.keras.Model(inputs, outputs)

其他注意事项

  1. 调用build_model时,需移除原有的pred_len和target_slice参数,因为分类任务不需要这两个预测相关的参数。
  2. 保留原有的残差块和转置逻辑即可,这些是TSMixer的核心结构,不需要修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:09:52