【问题标题】:Averaging over the batch dimension in Keras在 Keras 中对批次维度进行平均
【发布时间】:2019-08-10 07:24:49
【问题描述】:

我遇到了一个问题,我想用多个时间序列预测一个时间序列。我的输入是(batch_size, time_steps, features),我的输出应该是(1, time_steps, features)

我不知道如何平均 N。

这是一个虚拟示例。首先,输出是200个时间序列的线性函数的虚拟数据:

import numpy as np
time = 100
N = 2000

dat = np.zeros((N, time))
for i in range(time):
    dat[i,:] = np.sin(list(range(time)))*np.random.normal(size =1) + np.random.normal(size = 1)

y = dat.T @ np.random.normal(size = N)

现在我将定义一个时间序列模型(使用一维卷积网络):

from keras.models import Model
from keras.layers import Input, Conv1D, Dense, Lambda
from keras.optimizers import Adam
from keras import backend as K

n_filters = 2
filter_width = 3
dilation_rates = [2**i for i in range(5)] 
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.predict(dat.reshape(N, time, 1)).shape

Out[43]: (2000, 100, 1)

输出的形状错误!接下来,我尝试使用平均层,但出现了这个奇怪的错误:

def av_over_batches(x):
    x = K.mean(x, axis = 0)
    return(x)

x = Lambda(av_over_batches)(x)

model = Model(inputs = inp, outputs = x)
model.compile(optimizer = Adam(), loss='mean_squared_error')
model.predict(dat.reshape(N, time, 1)).shape

Traceback (most recent call last):

  File "<ipython-input-3-d43ccd8afa69>", line 4, in <module>
    model.predict(dat.reshape(N, time, 1)).shape

  File "/home/me/.local/lib/python3.6/site-packages/keras/engine/training.py", line 1169, in predict
    steps=steps)

  File "/home/me/.local/lib/python3.6/site-packages/keras/engine/training_arrays.py", line 302, in predict_loop
    outs[i][batch_start:batch_end] = batch_out

ValueError: could not broadcast input array from shape (100,1) into shape (32,1)

32 来自哪里? (顺便说一句,我在真实数据中得到了相同的数字,而不仅仅是在 MWE 中)。

但主要问题是:如何构建一个在输入批次维度上取平均值的网络?

【问题讨论】:

    标签: python tensorflow machine-learning keras time-series


    【解决方案1】:

    我会以不同的方式解决问题

    问题:您想从一组时间序列中预测一个时间序列。所以假设你有 3 个时间序列值TS1, TS2, TS3,每个 100 个时间步长你想预测一个时间序列y1, y2, y3

    我解决这个问题的方法如下

    即将每个时间步的时间序列组合在一起并将其提供给 LSTM。如果某些时间步长比其他时间步短,您可以填充它们。同样,如果某些集合的时间序列较少,则再次填充它们。

    示例:

    import numpy as np
    np.random.seed(33)
    
    time = 100
    N = 5000
    k = 5
    
    magic = np.random.normal(size = k)
    
    x = list()
    y = list()
    for i in range(N):
        dat = np.zeros((k, time))
        for i in range(k):
            dat[i,:] = np.sin(list(range(time)))*np.random.normal(size =1) + np.random.normal(size = 1)
        x.append(dat)
        y.append(dat.T @ magic)
    

    所以我想从一组 3 次步长中预测 100 步的时间序列。我们要对模型进行学习magic

    from keras.models import Model
    from keras.layers import Input, Conv1D, Dense, Lambda, LSTM
    from keras.optimizers import Adam
    from keras import backend as K
    import matplotlib.pyplot as plt
    
    input = Input(shape=(time, k))
    lstm = LSTM(32, return_sequences=True)(input)
    output = Dense(1,activation='sigmoid')(lstm)
    
    model = Model(inputs = input, outputs = output)
    model.compile(optimizer = Adam(), loss='mean_squared_error')
    
    data_x = np.zeros((N,100,5))
    data_y = np.zeros((N,100,1))
    
    for i in range(N):
        data_x[i] = x[i].T.reshape(100,5)
        data_y[i] = y[i].reshape(100,1)
    
    from sklearn.preprocessing import StandardScaler
    
    ss_x = StandardScaler()
    ss_y = StandardScaler()
    
    data_x = ss_x.fit_transform(data_x.reshape(N,-1)).reshape(N,100,5)
    data_y = ss_y.fit_transform(data_y.reshape(N,-1)).reshape(N,100,1)
    
    # Lets leave the last one sample for testing rest split into train and validation
    model.fit(data_x[:-1],data_y[:-1], batch_size=64, nb_epoch=100, validation_split=.25)
    

    val loss 仍在下降,但我阻止了它。让我们看看我们的预测有多好

    y_hat = model.predict(data_x[-1].reshape(-1,100,5))
    plt.plot(data_y[-1], label='y')
    plt.plot(y_hat.reshape(100), label='y_hat')
    plt.legend(loc='upper left')
    

    结果很有希望。运行它更多的时期和超参数调整应该进一步让我们关闭magic。也可以尝试堆叠 LSTM 和双向 LSTM。

    我觉得 RNN 比 CNN 更适合时间序列数据

    数据格式: 假设时间步长 = 3 时间序列 1 = [1,2,3]

    时间序列 2 = [4,5,6]

    时间序列 3 = [7,8,9]

    时间序列 3 = [10,11,12]

    Y = [100,200,300]

    对于 1 的批量大小

    [[1,4,7,10],[2,5,8,11],[3,6,9,12]] -&gt; LSTM -&gt; [100,200,300]

    【讨论】:

    • 这是一个有趣的答案,但我不知道如何学习magic 参数(您的参数化与我的没有什么不同——每个变量都有一个参数,而不是每个时间序列一个参数),或单个聚合函数。
    • 我在上面尝试做的是训练一个模型来学习将一堆数据点(对应于不同的时间序列)转换为单个数据点的函数(在本例中为magic) (产生一个时间序列)
    • 嗯。抱歉,如果我很密集,但是您的方法如何从 (N, time, 1) 时间序列的输入中产生 (1, time, 1) 时间序列?
    • @generic_user 是的,您对尺寸的看法是正确的,除了我们必须进行整形以匹配 LSTMS 获取输入的方式
    • 正确的是什么?
    猜你喜欢
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    相关资源
    最近更新 更多