NARX延时动态神经网络、BP神经网络,可做预测分析

最近在研究时间序列预测的时候,发现NARX神经网络这玩意儿挺有意思。和传统BP神经网络相比,它的延时反馈结构简直就是处理动态系统的作弊器。先放个对比图感受下(假装这里有手绘结构图):BP网络像直男一根筋往前传,NARX却偷偷记住了前几天的故事。

搞预测总得有个数据,咱们先造点带噪声的正弦波当玩具数据:

import numpy as np
t = np.linspace(0, 10, 500)
data = np.sin(t*2) * 0.8 + np.random.normal(0, 0.2, 500)

现在要给NARX准备延时输入。假设用前3个时刻的数据预测当前值,这代码比想象中简单:

def create_time_delay(data, delay=3):
    X, y = [], []
    for i in range(len(data)-delay-1):
        X.append(data[i:i+delay])
        y.append(data[i+delay])
    return np.array(X), np.array(y)

拿到数据后,搭建NARX模型就像搭乐高。注意这个External Input的骚操作——它允许额外输入天气数据、股票指标啥的:

from keras.layers import Dense, Input, Concatenate
from keras.models import Model

input_layer = Input(shape=(3,))
feedback = Input(shape=(1,))
merged = Concatenate()([input_layer, feedback])
hidden = Dense(8, activation='tanh')(merged)
output = Dense(1)(hidden)

model = Model(inputs=[input_layer, feedback], outputs=output)
model.compile(optimizer='adam', loss='mse')

训练时要玩点花样,把前一时刻的输出作为当前反馈输入。这种动态特性让模型自己和自己对话,效果堪比递归神经网络:

for epoch in range(100):
    preds = []
    for i in range(len(X_train)):
        pred = model.predict([X_train[i:i+1], last_feedback])
        preds.append(pred[0,0])
        last_feedback = pred
    # 用完整序列更新权重...

至于BP神经网络,老熟人就不客气了。但要注意,处理时序数据时得把时间维度压平,像煎饼果子一样摊开:

model_bp = Sequential([
    Dense(12, input_shape=(3,), activation='relu'),
    Dense(1)
])

实际跑下来,NARX在长期预测中更稳,BP容易放飞自我。不过当数据量小时,BP反而可能不翻车——毕竟参数少啊。有个骚操作是把NARX的延时输出接到BP的隐藏层,效果堪比咖啡配油条。

最后说个坑:做多步预测时,NARX容易误差累积。这时候可以祭出Teacher Forcing大法——训练时随机混入真实值,像驾校教练时不时帮你把方向盘。代码实现就是在训练循环里加个随机替换:

if np.random.rand() < 0.3:  # 30%概率用真实值
    last_feedback = y_train[i]
else:
    last_feedback = pred

预测这玩意儿就像算命,模型结构越符合物理规律,算得越准。下次试试在NARX里加入股票的交易量作为外部输入,说不定能薅到市场的羊毛呢(手动狗头)。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐