Python 时间序列神经网络与前馈神经网络的连接

Python 时间序列神经网络与前馈神经网络的连接,python,tensorflow,keras,neural-network,deep-learning,Python,Tensorflow,Keras,Neural Network,Deep Learning,考虑以下示例问题: # dummy data for a SO question import numpy as np import matplotlib.pyplot as plt plt.style.use('seaborn-whitegrid') from keras.models import Model from keras.layers import Input, Conv1D, Dense from keras.optimizers import Adam, SGD time =

考虑以下示例问题:

# dummy data for a SO question
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
from keras.models import Model
from keras.layers import Input, Conv1D, Dense
from keras.optimizers import Adam, SGD

time = np.array(range(100))
brk = np.array((time>40) & (time < 60)).reshape(100,1)
B = np.array([5, -5]).reshape(1,2)
np.dot(brk, B)
y = np.c_[np.sin(time), np.sin(time)] + np.random.normal(scale = .2, size=(100,2))+ np.dot(brk, B)



plt.clf()
plt.plot(time, y[:,0])
plt.plot(time, y[:,1])

另一方面,具有N个输出的基本线性回归(此处以Keras实现)非常适合特殊成分:

# time series model
n_filters = 10
filter_width = 3
dilation_rates = [2**i for i in range(7)] 
inp = Input(shape=(None, 1))
x = inp
for dilation_rate in dilation_rates:
    x = Conv1D(filters=n_filters,
               kernel_size=filter_width, 
               padding='causal',
               activation = "relu",
               dilation_rate=dilation_rate)(x)
x = Dense(1)(x)
model = Model(inputs = inp, outputs = x)
model.compile(optimizer = Adam(), loss='mean_squared_error')
model.summary()

X_train = np.transpose(np.c_[time, time]).reshape(2,100,1)
y_train = np.transpose(y).reshape(2,100,1)

history = model.fit(X_train, y_train,
                batch_size=2,
                epochs=1000,
                verbose = 0)
yhat = model.predict(X_train)
plt.clf()
plt.plot(time, y[:,0])
plt.plot(time, y[:,1])

plt.plot(time, yhat[0,:,:])
plt.plot(time, yhat[1,:,:])
inp1 = Input((1,))
x1 = inp1
x1 = Dense(2)(x1)
model1 = Model(inputs = inp1, outputs = x1)
model1.compile(optimizer = Adam(), loss='mean_squared_error')
model1.summary()

brk_train = brk
y_train = y
history = model1.fit(brk_train, y_train,
                batch_size=100,
                epochs=6000, verbose = 0)
yhat1 = model1.predict(brk_train)
plt.clf()
plt.plot(time, y[:,0])
plt.plot(time, y[:,1])
plt.plot(time, yhat1[:,0])
plt.plot(time, yhat1[:,1])

我想使用keras来联合估计时间序列分量和特质分量。主要问题是前馈网络(线性回归是其特例)形成
batch\u size x dims
,而时间序列网络采用维度
batch\u size x time\u steps x dims

因为我想联合估计模型的特殊部分(线性回归部分)和时间序列部分,所以我只会对整个时间序列进行批量采样。这就是为什么我为型号1指定了
batch\u size=time\u steps

但在静态模型中,我真正要做的是将数据建模为
时间步长x dims

我曾尝试将前馈模型重新转换为时间序列模型,但没有成功。以下是非工作方法:

inp3 = Input(shape = (None, 1))
x3 = inp3
x3 = Dense(2)(x3)
model3 = Model(inputs = inp3, outputs = x3)
model3.compile(optimizer = Adam(), loss='mean_squared_error')
model3.summary()
brk_train = brk.reshape(1, 100, 1)
y_train = np.transpose(y).reshape(2,100,1)
history = model3.fit(brk_train, y_train,
                batch_size=1,
                epochs=1000, verbose = 1)

ValueError: Error when checking target: expected dense_40 to have shape (None, 2) but got array with shape (100, 1)
我试图拟合与model1相同的模型,但形状不同,因此它与TCN模型兼容——重要的是,它将具有相同的批处理结构

在本例中,输出的最终形状应为
(2100,1)
。基本上,我希望模型执行以下算法:

  • 摄取形状
    (N,时间步长,dims)的
    X
  • 失去第一个维度,因为每个系列的设计矩阵都是相同的,产生形状
    (时间步长,dims)
    X1
  • 正向步长:
    np.dot(X1,W)
    ,其中
    W
    为尺寸
    (dims,N)
    ,产生尺寸
    X2
    (时间步长,N)
  • X2
    重塑为
    (N,时间步长,1)
    。然后我可以将它添加到模型的其他部分的输出中
  • 后退:由于这只是一个线性模型,
    W
    相对于输出的梯度就是
    X1
我如何实现这一点?我需要自定义图层吗

如果你对这一切背后的动机感到好奇的话,我会建立一些想法


编辑:发布后,我注意到我只使用了时间变量,而不是时间序列本身。与滞后序列的TCN拟合正好适合序列的特殊部分(无论如何,在样本中)。但我的基本问题仍然存在——我想合并这两种类型的网络。

因此,我解决了自己的问题。答案是创建虚拟交互(因此是一个真正稀疏的设计矩阵),然后重塑数据

###########################
# interaction model
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
from keras.models import Model
from keras.layers import Input, Conv1D, Dense
from keras.optimizers import Adam, SGD
from patsy import dmatrix


def shift5(arr, num, fill_value=np.nan):
    result = np.empty_like(arr)
    if num > 0:
        result[:num] = fill_value
        result[num:] = arr[:-num]
    elif num < 0:
        result[num:] = fill_value
        result[:num] = arr[-num:]
    else:
        result = arr
    return result


time = np.array(range(100))
brk = np.array((time>40) & (time < 60)).reshape(100,1)
B = np.array([5, -5]).reshape(1,2)
np.dot(brk, B)
y = np.c_[np.sin(time), np.sin(time)] + np.random.normal(scale = .2, size=(100,2))+ np.dot(brk, B)

plt.clf()
plt.plot(time, y[:,0])
plt.plot(time, y[:,1])

# define interaction model
inp = Input(shape=(None, 2))
x = inp
x = Dense(1)(x)
model = Model(inputs = inp, outputs = x)
model.compile(optimizer = Adam(), loss='mean_squared_error')
model.summary()

from patsy import dmatrix
df = pd.DataFrame(data = {"fips": np.concatenate((np.zeros(100), np.ones(100))),
                          "brk": np.concatenate((brk.reshape(100), brk.squeeze()))})
df.brk = df.brk.astype(int)
tm = np.asarray(dmatrix("brk:C(fips)-1", data = df))

brkint = np.concatenate(( \
                tm[:100,:].reshape(1,100,2),
                tm[100:200,:].reshape(1,100,2)
                ), axis = 0)

y_train = np.transpose(y).reshape(2,100,1)

history = model.fit(brkint, y_train,
                batch_size=2,
                epochs=1000,
                verbose = 1)

yhat = model.predict(brkint)
plt.clf()
plt.plot(time, y[:,0])
plt.plot(time, y[:,1])

plt.plot(time, yhat[0,:,:])
plt.plot(time, yhat[1,:,:])
###########################
#交互模型
将numpy作为np导入
将matplotlib.pyplot作为plt导入
plt.style.use('seaborn-whitegrid'))
从keras.models导入模型
从keras.layers导入输入,Conv1D,稠密
从keras.optimizers导入Adam,新加坡元
从patsy导入数据矩阵
def移位5(arr、num、fill_值=np.nan):
结果=np.空类(arr)
如果num>0:
结果[:num]=填充值
结果[num:]=arr[:-num]
elif num<0:
结果[num:]=填充值
结果[:num]=arr[-num:]
其他:
结果=arr
返回结果
时间=np.数组(范围(100))
brk=np.数组((时间>40)和(时间<60)).重塑(100,1)
B=np.数组([5,-5])。重塑(1,2)
np.dot(brk,B)
y=np.c_uu[np.sin(时间),np.sin(时间)]+np.random.normal(标度=0.2,大小=(100,2))+np.dot(brk,B)
plt.clf()
plt.plot(时间,y[:,0])
plt.plot(时间,y[:,1])
#定义交互模型
inp=输入(形状=(无,2))
x=inp
x=密度(1)(x)
模型=模型(输入=输入,输出=x)
compile(优化器=Adam(),loss='mean_squared_error')
model.summary()
从patsy导入数据矩阵
df=pd.DataFrame(data={“fips”:np.concatenate((np.zero(100),np.one(100)),
“brk”:np.concatenate((brk.reformate(100),brk.squence()))
df.brk=df.brk.astype(int)
tm=np.asarray(dmatrix(“brk:C(fips)-1”,数据=df))
brkint=np.连接((\
tm[:100,:]重塑(1100,2),
tm[100:200,:]重塑(1100,2)
),轴=0)
y_序列=np.转置(y).重塑(2100,1)
历史=模型拟合(brkint,y_列车,
批次大小=2,
纪元=1000,
详细=1)
yhat=模型预测(brkint)
plt.clf()
plt.plot(时间,y[:,0])
plt.plot(时间,y[:,1])
plt.plot(时间,yhat[0,:,:])
plt.plot(时间,yhat[1,:,:])

输出形状与TCN相同,可以简单地按元素添加