Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PaddleTS增加NLinear时序预测模型的提案 #354

Closed
2Bear opened this issue Jan 13, 2023 · 8 comments
Closed

PaddleTS增加NLinear时序预测模型的提案 #354

2Bear opened this issue Jan 13, 2023 · 8 comments

Comments

@2Bear
Copy link
Contributor

2Bear commented Jan 13, 2023

综述

本提案旨在建议将NLinear时序预测模型加入PaddleTS模型库。

👉NLinear原作论文
👉基于PaddleTS的NLinear实现

本实现立足于原作设计,亦做出了以下改进:

⭐支持已知协变量与观测协变量。
⭐Linear结构可以按需增加隐层。

本提案将NLinear与结构类似的MLP以及主流的NBEATS进行了效果比较(见有效性验证一节)。
实验证明NLinear能以极低的模型复杂度实现较优异的效果。本实现做出的改进则进一步提升了NLinear的效果和泛用性。

NLinear模型介绍

NLinear是一个非常简单的线性模型,仅将历史输入通过一个线性层,就得到预测输出。

linear

为了解决时序数据的分布漂移问题,NLinear又对输入输出做了一次非常简单的Normalization。以历史输入的最后一个数作为尾数。历史输入先减去尾数,然后通过线性层,得到的输出再加回尾数,作为模型的预测输出。

本实现做出的改进

支持已知协变量与观测协变量

原作设计虽然简单高效,但是并不能利用TSDataset中包含的协变量信息,对于协变量至关重要的任务并不适用,为了解决这个问题,本实现做了相应改进。在构建输入张量时,将PAST_TARGETKNOWN_COVOBSERVED_COV一维展平,然后横向拼接作为输入,得到一维输出后,再重新折叠成所需要的张量形状。

# concat backcast, known_cov, observed_cov if any
feature = [backcast.reshape((batch_size, 1, -1))]
if known_cov is not None:
    feature.append(known_cov.reshape((batch_size, 1, -1)))
if observed_cov is not None:
    feature.append(observed_cov.reshape((batch_size, 1, -1)))
out = paddle.concat(x=feature, axis=2)

# forward
out = self._nn(out)
out = out.reshape([batch_size, -1, self._target_dim])

Linear结构可以按需增加隐层

协变量增加了输入张量的复杂性,单线性层可能无法充分学习特征,导致欠拟合。为了解决这个问题,本实现也做了相应改进。增加了与MLP类似的hidden_config属性,允许开发者按需增加隐层。

# Unlike MLP, `hidden_config` is empty by default, so there can be no hidden layer.
layers = []
dims = [in_chunk_len_multi] + hidden_config + [out_chunk_len_multi]
for i in range(len(dims) - 2):
    layers.append(paddle.nn.Linear(dims[i], dims[i + 1]))
    if use_bn:
        layers.append(paddle.nn.BatchNorm1D(1))
    layers.append(paddle.nn.ReLU())
layers.append(paddle.nn.Linear(dims[-2], dims[-1]))
self._nn = paddle.nn.Sequential(*layers)

有效性验证

以下是NLinear与其它模型在主流数据集的实验结果,考虑到MLP并不支持协变量,且数据集中协变量不一定对预测有正向作用,所以每个数据集都做了有协变量与无协变量两遍测试。

result

隐层的有效性

从实验结果可知,虽然单线性层的NLinear效果不错,但是有隐层的NLinear更优,尤其当协变量多导致输入复杂时,效果尤为明显。因此可以认为本实现的可增加隐层改进是有效的。

Normalization的有效性

有隐层的NLinear换种角度看,可以被认为是一种增加了Normalization的MLP。从实验结果可知,当输入相同(都没有协变量),且网络结构一致(都有一个相同的隐层)时,NLinear均优于MLP。因此可以认为原作的Normalization特性是一个有效的特性。

协变量的有效性

并不是所有数据集的协变量都对预测有正向作用。通过与同样支持协变量的NBEATS对比可知,当协变量有助益时,NLinear模型可以从协变量中学习有效特征,实现比无协变量时更好的效果。因此可以认为本实现的支持协变量改进是有效的。(而MLP完全不支持协变量,对此类任务无适用性。)

结论

总的来说,NLinear简单好用,而本实现的NLinear模型在原作设计的基础上,进一步提升了效果和泛用性。NLinear的模型复杂程度并不比MLP高,却能实现比某些复杂模型更好的效果。模型调参简单,训练快,可以迅速地得出结论,适合作为各种任务的入手模型。

另外从PaddleTS自身发展的角度来看,NLinear无疑是对现有模型库的有益补充。考虑到开源社区内已有顶流时序建模库(5K+⭐)支持了该模型,PaddleTS吸纳NLinear亦有利于提高自身竞争力。

所以,建议PaddleTS加入NLinear时序预测模型。

@yangs16
Copy link
Collaborator

yangs16 commented Jan 13, 2023

太赞了!希望早日合入代码,让更多开发者用起来。

@LinWencong
Copy link
Collaborator

LinWencong commented Jan 13, 2023

对于您的实现,想请教下,对于协变量的normalization的实现问题;您是否根据协变量自身的尾数作为 normalization?
若不是的话,我认为,协变量本身不一定会有分布漂移情况(很多业务的情况下,例如日期,温度、湿度等等类似的);如果依据 Nlinear 的实现,使用 target 的尾数来进行normalization,会造成协变量自身的分布漂移;~ 可以考虑增加一个控制开关;
若是的话,个人感觉应该是合理的~

@2Bear
Copy link
Contributor Author

2Bear commented Jan 13, 2023

对于您的实现,想请教下,对于协变量的normalization的实现问题;您是否根据协变量自身的尾数作为 normalization? 若不是的话,我认为,协变量本身不一定会有分布漂移情况(很多业务的情况下,例如日期,温度、湿度等等类似的);如果依据 Nlinear 的实现,使用 target 的尾数来进行normalization,会造成协变量自身的分布漂移;~ 可以考虑增加一个控制开关; 若是的话,个人感觉应该是合理的~

在目前的实现中,并未对协变量做Normalization,协变量是原样拼接在输入中的。

@2Bear
Copy link
Contributor Author

2Bear commented Jan 13, 2023

对于您的实现,想请教下,对于协变量的normalization的实现问题;您是否根据协变量自身的尾数作为 normalization? 若不是的话,我认为,协变量本身不一定会有分布漂移情况(很多业务的情况下,例如日期,温度、湿度等等类似的);如果依据 Nlinear 的实现,使用 target 的尾数来进行normalization,会造成协变量自身的分布漂移;~ 可以考虑增加一个控制开关; 若是的话,个人感觉应该是合理的~

因为协变量不存在“尾数加回”这一步,只是单纯减自己的尾数,可能没有太多意义,并不能起到Normalization的作用。

@2Bear
Copy link
Contributor Author

2Bear commented Jan 13, 2023

对于您的实现,想请教下,对于协变量的normalization的实现问题;您是否根据协变量自身的尾数作为 normalization? 若不是的话,我认为,协变量本身不一定会有分布漂移情况(很多业务的情况下,例如日期,温度、湿度等等类似的);如果依据 Nlinear 的实现,使用 target 的尾数来进行normalization,会造成协变量自身的分布漂移;~ 可以考虑增加一个控制开关; 若是的话,个人感觉应该是合理的~

对于像“星期几”等这种周期循环协变量,如果减去尾数,反而会彻底失掉原有的信息。

@bianchuanxin
Copy link
Collaborator

1、Nlinear对协变量的支持对MLP起到了很好的补充作用;
2、多层linear的改进使得模型更为广义,并通过实际数据验证了有效性;
3、代码实现很工整

很棒的工作,支持合入~

@QGN123
Copy link
Collaborator

QGN123 commented Jan 13, 2023

首先,您的工作非常棒!关于协变量的支持有一个问题,某顶流时序建模库(5K+⭐)的实现方案是target与cov分别过线性层最后相加, 您的实现方案是全部一起打平过线性层。 请问您有分别验证过这两种实现的效果吗,您选择全部打平的原因是?

@2Bear
Copy link
Contributor Author

2Bear commented Jan 13, 2023

首先,您的工作非常棒!关于协变量的支持有一个问题,某顶流时序建模库(5K+⭐)的实现方案是target与cov分别过线性层最后相加, 您的实现方案是全部一起打平过线性层。 请问您有分别验证过这两种实现的效果吗,您选择全部打平的原因是?

我没有测试过二者效果的区别,所以下面的讨论只是讨论,也可能我完全错了。

首先,如果没有隐层,二者其实是等价的。而5K顶流库的NLinear模型不支持隐层,所以它用哪种并没有区别。
但是这里的实现是有隐层的,为了充分学习历史与协变量和未来三者之间的关系(不只是它们分别与未来的关系),我决定将它们输入到同一个深度网络中。我们不妨换种说法理解这种处理。这里的实现,在第一层就是把历史与协变量分别通过一个线性层,然后相加,输入到一个MLP中。而另一种处理是它们分别通过一个MLP,在最后一层才相加。

如果有测试结果表面我的想法错了,我乐意修改~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants