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

如何用EinsumDense实现时序张量的维度压缩与扩展?

使用EinsumDense处理时序张量的Horizon与特征维度变换

你的核心问题在于当前的einsum公式没有正确实现Horizon维度的映射,且最终层引入了冗余维度导致模型难以学习,以下是针对性的修正方案和解释:

一、先明确符号定义(避免混淆)

统一符号方便理解:

  • s: Batch Size(你的场景中为1)
  • h_in: 输入的Horizon长度
  • h_out: 目标Horizon长度(即你说的H)
  • f_in: 输入特征数
  • f_out: 目标特征数(即你说的F)

二、FFN层:实现Horizon维度的变换(从(s, h_in, f_in)到(s, h_out, f_in))

你之前用的shf,h->shf公式没有改变Horizon维度——输入和输出的h是同一个维度,相当于只对每个时间步做了无意义的缩放,完全没实现Horizon长度的调整。

正确的公式应该是shf, hh' -> sh'f:

  • 输入张量:(s, h_in, f_in)对应shf
  • 权重张量:(h_in, h_out)对应hh'(负责把原时间步映射到目标时间步)
  • 输出张量:(s, h_out, f_in)对应sh'f

这个操作本质是对每个特征维度,做时间步的线性投影,把h_in个时间步映射到h_out个,真正实现Horizon长度的变换。

代码示例:

from tensorflow.keras.layers import EinsumDense

# FFN层:将输入Horizon转为目标H,保持特征数不变
ffn_layer = EinsumDense(
    equation='shf, hh_new -> sh_newf',
    output_shape=(H, f_in),  # H是目标Horizon长度,f_in是输入特征数
    bias_axes='h_new'  # 可选:给每个输出时间步添加偏置,提升拟合能力
)

三、最终输出层:实现特征维度的变换(从(s, h_out, f_in)到(s, h_out, f_out))

你之前用的shf,hfyz->syz公式引入了冗余的y、z维度,导致参数数量爆炸且模型无法聚焦于有效的特征映射,这是效果差的关键原因之一。

根据场景选择两种方案:

方案1:时间步共享特征变换(推荐,参数少、泛化性好)

大多数时序场景下,每个时间步的特征变换逻辑是一致的,用这个方案:
公式:shf, ff' -> shf'

  • 输入张量:(s, h_out, f_in)对应shf
  • 权重张量:(f_in, f_out)对应ff'(所有时间步共享这套特征映射权重)
  • 输出张量:(s, h_out, f_out)对应shf'

代码示例:

final_layer = EinsumDense(
    equation='shf, ff_new -> shf_new',
    output_shape=(H, F),  # H是目标Horizon,F是目标特征数
    bias_axes='f_new'
)

方案2:时间步独立特征变换(仅特殊场景使用)

如果你的时序数据中每个时间步的特征分布差异极大,需要独立的变换逻辑,可以用这个方案:
公式:shf, hff' -> shf'

  • 权重张量:(h_out, f_in, f_out)对应hff'(每个时间步有专属的特征映射权重)
  • 缺点是参数量会增加h_out倍,容易过拟合。

四、原有配置效果好的原因

你之前未修改Horizon的配置中,FFN的shf,h->shf(推测实际是shf,f->shf,即对每个时间步的特征做线性变换)和最终层的shf,hz->shz(实际是shf,fz->shz),都是在做稳定的特征维度变换,模型只需要学习特征映射逻辑即可;而错误的einsum公式既没实现Horizon的真正变换,又引入了冗余参数,导致模型学习目标混乱,自然效果差。

完整可运行示例

import tensorflow as tf
from tensorflow.keras.layers import EinsumDense, Input, TransformerEncoder

# 定义参数
batch_size = 1
input_horizon = 24
input_features = 16
target_H = 48
target_F = 8

# 构建输入
inputs = Input(shape=(input_horizon, input_features))

# Transformer编码器(示例结构)
encoder = TransformerEncoder(
    num_layers=2,
    d_model=input_features,
    num_heads=4,
    dim_feedforward=64
)
x = encoder(inputs)  # 输出形状:(batch_size, input_horizon, input_features)

# FFN层:变换Horizon到target_H
x = EinsumDense(
    equation='shf, hh_new -> sh_newf',
    output_shape=(target_H, input_features),
    bias_axes='h_new'
)(x)  # 现在形状:(batch_size, target_H, input_features)

# 最终输出层:变换特征到target_F
outputs = EinsumDense(
    equation='shf, ff_new -> shf_new',
    output_shape=(target_H, target_F),
    bias_axes='f_new'
)(x)  # 输出形状:(batch_size, target_H, target_F)

# 模型构建与查看
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model.summary()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:10:19