iTransformer:时间序列预测的最新突破

IMG_256

预测领域在基础模型领域开展了大量活动,自 2024 年初以来就提出了Lag-LLaMATime-LLMChronos和 Moirai 等模型。

然而,它们的性能有点令人印象深刻(对于可重复的基准,请参见此处),并且我相信特定于数据的模型仍然是目前的最佳解决方案。

为此,Transformer 架构已以多种形式应用于时间序列预测,其中PatchTST实现了长期预测的最先进性能。

具有挑战性的 PatchTST 是iTransformer模型,该模型于 2024 年 3 月在论文iTransformer:Inverted Transformers Are effective for Time Series Forecasting中提出。

在本文中,我们发现 iTransformer 背后极其简单的概念并探索其架构。然后,我们将该模型应用到一个小型实验中,并将其性能与TSMixerN-HiTS和 PatchTST 进行比较。

欲了解更多详细信息,请务必阅读原始论文

让我们开始吧!

探索 iTransformer

iTransformer 背后的想法来自于对普通 Transformer 模型使用时间_标记_的认识。

这意味着该模型会在单个时间步长中查看所有特征。因此,模型在一次查看一个时间步骤时学习时间依赖性是一项挑战。

该问题的解决方案是修补,这是通过 PatchTST 模型提出的。通过修补,我们只需将时间点分组在一起,然后再对其进行标记和嵌入,如下所示。

IMG_257

可视化修补。在这里,我们有一个包含 15 个时间步长的序列,补丁长度为 5,步幅也为 5,从而产生三个补丁。图片由作者提供。

在 iTransformer 中,我们通过简单地将模型应用到反转维度上,将修补推向了极致。

IMG_258

iTransformer应用在系列的倒立形状上。这样,跨时间的整个功能就被标记化和嵌入了。图片由 Y. Liu、T. Hu、H. Zhang、H. Wu、S. Wang、L. Ma、M. Long 提供,来自iTransformer:反向变压器对于时间序列预测非常有效

在上图中,我们可以看到 iTransformer 与普通 Transformer 的不同之处。它不是在一个时间步长中查看所有特征,而是在多个时间步长中查看一个特征。这只需通过反转输入的形状即可完成。

这样,注意力层可以学习多元相关性,前馈网络对整个输入序列的表示进行编码。

现在我们已经掌握了 iTransformer 背后的总体思路,让我们更详细地了解一下它的架构。

iTransformer的架构

iTransformer 采用带有嵌入、投影和 Transformer 块的普通编码器-解码器架构,最初是在 2017 年的开创性论文《Attention Is All You Need》中提出的。

IMG_259

iTransformer 的架构。图片由 Y. Liu、T. Hu、H. Zhang、H. Wu、S. Wang、L. Ma、M. Long 提供,来自iTransformer:反向变压器对于时间序列预测非常有效

从上图中我们可以看出,构建块是相同的,但功能却完全不同。让我们仔细看看。

嵌入层

首先,输入序列作为标记独立嵌入。同样,这就像修补的极端情况,模型不是对输入的子序列进行标记,而是对整个输入序列进行标记。

多变量注意力

然后,嵌入被发送到注意力层,在那里它将学习多元相关图。

这是可能的,因为倒置模型将每个特征视为一个独立的过程。因此,注意力机制可以学习特征对之间的相关性,使 iTransformer 特别适合多元预测任务。

层归一化

注意力层的输出被发送到归一化层。

在传统的 Transformer 架构中,所有特征都在固定的时间戳上完成归一化。这可能会引入交互噪声,这意味着模型正在学习无用的关系。另外,它可能会导致信号过于平滑。

相比之下,由于 iTransformer 反转了维度,因此标准化是跨时间戳完成的。这有助于模型处理非平稳序列,并减少序列中的噪声。

前馈网络

最后,前馈网络(FFN)学习传入令牌的深度表示。

同样,由于形状是倒置的,多层感知器 (MLP) 可以学习不同的时间属性,例如周期性和幅度。这模仿了基于 MLP 的模型的功能,例如N-BEATS、N-HiTS 和 TSMixer。

投影

从这里开始,只需堆叠许多由以下组成的块即可:

  • 注意力层
  • 层归一化
  • 前馈网络
  • 层归一化

每个块学习输入序列的不同表示。然后,通过线性投影步骤发送块堆栈的输出以获得最终预测。

综上所述,iTransformer 并不是一个新的架构;它并没有重新发明变压器。它只是将其应用于输入的反转维度,这使得模型能够学习多元相关性并捕获时间属性。

现在我们对 iTransformer 模型有了深入的了解,让我们将其应用到一个小型的预测实验中。

使用 iTransformer 进行预测

对于这个小实验,我们在 Creative Commons 许可下发布的Electricity Transformer 数据集上应用了 iTransformer 模型。

这是一个流行的基准数据集,用于跟踪中国一个省两个地区的电力变压器的油温。对于这两个区域,我们每小时和每 15 分钟采样一个数据集,总共四个数据集。

虽然 iTransformer 本质上是一个多变量模型,但我们在 96 个时间步长的范围内测试其单变量预测能力。

此实验的代码可在GitHub上找到。

让我们开始吧!

初始设置

_在这个实验中,我们使用了Neuralforecast_库,因为我相信它提供了深度学习方法最快、最直观的即用型实现。

1
2
3
4
5
6
import pandas as pd  
import numpy as np
import matplotlib.pyplot as plt
from datasetsforecast.long_horizon import LongHorizon
from neuralforecast.core import NeuralForecast
from neuralforecast.models import NHITS, PatchTST, iTransformer, TSMixer

请注意,在撰写本文时,iTransformer 尚未在Neuralforecast_的_公开版本中提供。要立即访问模型,您可以运行:

pip install git+https://github.com/Nixtla/neuralforecast.git

现在,让我们编写一个函数来加载 ETT 数据集及其验证大小、测试大小和频率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def load_data(name):
if name == "ettm1":
Y_df, *_ = LongHorizon.load(directory='./', group='ETTm1')
Y_df = Y_df[Y_df['unique_id'] == 'OT']
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
val_size = 11520
test_size = 11520
freq = '15T'
elif name == "ettm2":
Y_df, *_ = LongHorizon.load(directory='./', group='ETTm2')
Y_df = Y_df[Y_df['unique_id'] == 'OT']
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
val_size = 11520
test_size = 11520
freq = '15T'
elif name == 'etth1':
Y_df, *_ = LongHorizon.load(directory='./', group='ETTh1')
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
val_size = 2880
test_size = 2880
freq = 'H'
elif name == "etth2":
Y_df, *_ = LongHorizon.load(directory='./', group='ETTh2')
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
val_size = 2880
test_size = 2880
freq = 'H'

return Y_df, val_size, test_size, freq

_上面的函数可以方便地以Neuroforecast_期望的格式加载数据,其中我们有一个unique_id用于标记唯一时间序列的列,一个ds用于时间戳的列,以及一个y包含我们的序列值的列。

另请注意,验证和测试规模与科学界在发表论文时使用的一致。

我们现在准备好训练模型了。

训练和预测

要训​​练 iTransformer 模型,我们只需指定:

  • 预测范围
  • 输入尺寸
  • 系列数

请记住,iTransformer 本质上是一个多元模型,这就是为什么我们在拟合模型时需要指定系列数。

由于我们处于单变量场景,n_series=1.

1
2
3
4
5
iTransformer(h=horizon, 
input_size=3*horizon,
n_series=1,
max_steps=1000,
early_stop_patience_steps=3)

在上面的代码块中,我们还指定了最大训练步骤数,并将提前停止设置为三次迭代以避免过度拟合。

然后我们对其他模型执行相同的操作,并将它们放入列表中。

1
2
3
4
5
6
7
8
horizon = 96

models = [
iTransformer(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
TSMixer(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
NHITS(h=horizon, input_size=3*horizon, max_steps=1000, early_stop_patience_steps=3),
PatchTST(h=horizon, input_size=3*horizon, max_steps=1000, early_stop_patience_steps=3)
]

伟大的!现在,我们只需初始化该NeuralForecast对象即可访问训练、交叉验证和预测的方法。

1
2
nf = NeuralForecast(models=models, freq=freq)
nf_preds = nf.cross_validation(df=Y_df, val_size=val_size, test_size=test_size, n_windows=None)

最后,我们使用该库评估每个模型的性能utilsforecast。

1
2
3
4
5
from utilsforecast.losses import mae, mse
from utilsforecast.evaluation import evaluate

ettm1_evaluation = evaluate(df=nf_preds, metrics=[mae, mse], models=['iTransformer', 'TSMixer', 'NHITS', 'PatchTST'])
ettm1_evaluation.to_csv('ettm1_results.csv', index=False, header=True)

然后对所有数据集重复这些步骤。运行该实验的完整函数如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from utilsforecast.losses import mae, mse
from utilsforecast.evaluation import evaluate

datasets = ['ettm1', 'ettm2', 'etth1', 'etth2']

for dataset in datasets:

Y_df, val_size, test_size, freq = load_data(dataset)

horizon = 96

models = [
iTransformer(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
TSMixer(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
NHITS(h=horizon, input_size=3*horizon, max_steps=1000, early_stop_patience_steps=3),
PatchTST(h=horizon, input_size=3*horizon, max_steps=1000, early_stop_patience_steps=3)
]

nf = NeuralForecast(models=models, freq=freq)
nf_preds = nf.cross_validation(df=Y_df, val_size=val_size, test_size=test_size, n_windows=None)
nf_preds = nf_preds.reset_index()

evaluation = evaluate(df=nf_preds, metrics=[mae, mse], models=['iTransformer', 'TSMixer', 'NHITS', 'PatchTST'])
evaluation.to_csv(f'{dataset}_results.csv', index=False, header=True)

一旦运行完成,我们就可以从所有数据集上的所有模型中获得预测。然后我们可以继续进行评估。

绩效评估

_由于我们将所有性能指标保存在 CSV 文件中,因此我们可以使用pandas_读取它们并绘制每个数据集的每个模型的性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
files = ['etth1_results.csv', 'etth2_results.csv', 'ettm1_results.csv', 'ettm2_results.csv']
datasets = ['etth1', 'etth2', 'ettm1', 'ettm2']

dataframes = []

for file, dataset in zip(files, datasets):
df = pd.read_csv(file)
df['dataset'] = dataset

dataframes.append(df)

full_df = pd.concat(dataframes, ignore_index=True)
full_df = full_df.drop(['unique_id'], axis=1)

然后,绘制指标:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import matplotlib.pyplot as plt
import numpy as np

dataset_names = full_df['dataset'].unique()
model_names = ['iTransformer', 'TSMixer', 'NHITS', 'PatchTST']

fig, axs = plt.subplots(2, 2, figsize=(15, 15))
bar_width = 0.35

axs = axs.flatten()

for i, dataset_name in enumerate(dataset_names):
df_subset = full_df[(full_df['dataset'] == dataset_name) & (full_df['metric'] == 'mae')]
mae_vals = df_subset[model_names].values.flatten()
df_subset = full_df[(full_df['dataset'] == dataset_name) & (full_df['metric'] == 'mse')]
mse_vals = df_subset[model_names].values.flatten()

indices = np.arange(len(model_names))

bars_mae = axs[i].bar(indices - bar_width / 2, mae_vals, bar_width, color='skyblue', label='MAE')
bars_mse = axs[i].bar(indices + bar_width / 2, mse_vals, bar_width, color='orange', label='MSE')

for bars in [bars_mae, bars_mse]:
for bar in bars:
height = bar.get_height()
axs[i].annotate(f'{height:.2f}',
xy=(bar.get_x() + bar.get_width() / 2, height),
xytext=(0, 3),
textcoords="offset points",
ha='center', va='bottom')

axs[i].set_xticks(indices)
axs[i].set_xticklabels(model_names, rotation=45)
axs[i].set_title(dataset_name)
axs[i].legend(loc='best')

plt.tight_layout()

IMG_260

来自 ETT 数据集上所有模型的 MAE 和 MSE,范围为 96 个时间步长。图片由作者提供。

从上图可以看出,iTransformer 在所有数据集上的表现都相当不错,但 TSMixer 整体略好于 iTransformer,PatchTST 是本次实验中整体冠军模型。

当然,请记住,我们没有利用 iTransformer 的多变量功能,并且我们仅在单个预测范围内进行测试。因此,它并不是对 iTransformer 性能的完整评估。

尽管如此,有趣的是看到该模型的表现与 PatchTST 非常接近,这进一步支持了这样的想法:在使用 Transformer 进行时间序列预测时,在标记化之前将时间步分组在一起可以解锁新的性能高度。

结论

iTransformer 采用普通 Transformer 架构,并将其简单地应用于输入序列的反转形状。

这样,整个系列就被标记化了,这模仿了 PatchTST 中提出的修补的极端情况。

这使得模型能够使用其注意力机制来学习多元相关性,而前馈网络则学习序列的时间属性。

尽管在我们有限的实验中,PatchTST 的整体表现最好,但 iTransformer 在许多基准数据集上的长期预测中表现出了最先进的性能。

我坚信每个问题都需要其独特的解决方案,现在您可以将 iTransformer 添加到您的工具箱并将其应用到您的项目中。

谢谢阅读!我希望您喜欢它并学到新东西!

© 2024 Omer Wu bar All Rights Reserved. 本站访客数人次 本站总访问量