Keras:我应该如何准备RNN的输入数据?

21

我在为Keras的RNN准备输入数据时遇到了问题。

当前,我的训练数据的维度是:(6752, 600, 13)

  • 6752:训练数据的数量
  • 600:时间步数的数量
  • 13:特征向量的大小(该向量为浮点型)

X_trainY_train都是这个维度。

我想要准备这些数据以供Keras中的SimpleRNN使用。

假设我们正在按时间步骤进行,从步骤#0到步骤#599。 假设我想要使用input_length = 5,这意味着我想要使用最近的5个输入。(例如,在第14步使用第10步、第11步、第12步、第13步和第14步的输入)。

我应该如何重塑X_train

它应该是(6752, 5, 600, 13)还是(6752, 600, 5, 13)

Y_train应该是什么形状?

它应该是(6752, 600, 13)还是(6752, 1, 600, 13)还是(6752, 600, 1, 13)

2个回答

22

如果您只想使用最近的5个输入来预测输出,那么无需提供任何训练样本的完整600个时间步长。我的建议是以以下方式传递训练数据:

             t=0  t=1  t=2  t=3  t=4  t=5  ...  t=598  t=599
sample0      |---------------------|
sample0           |---------------------|
sample0                |-----------------
...
sample0                                         ----|
sample0                                         ----------|
sample1      |---------------------|
sample1           |---------------------|
sample1                |-----------------
....
....
sample6751                                      ----|
sample6751                                      ----------|

培训序列的总数将合计为

(600 - 4) * 6752 = 4024192    # (nb_timesteps - discarded_tailing_timesteps) * nb_samples

每个训练序列由5个时间步骤组成。在每个序列的每个时间步骤中,您都会传递13个特征向量元素。因此,训练数据的形状将为(4024192, 5, 13)。
这个循环可以重新塑造您的数据:
input = np.random.rand(6752,600,13)
nb_timesteps = 5

flag = 0

for sample in range(input.shape[0]):
    tmp = np.array([input[sample,i:i+nb_timesteps,:] for i in range(input.shape[1] - nb_timesteps + 1)])

    if flag==0:
        new_input = tmp
        flag = 1

    else:
        new_input = np.concatenate((new_input,tmp))

7
这是一种快速的程序,可创建LSTN/RNN的3D数据,无需循环,并涉及此简单函数。
def create_windows(data, window_shape, step = 1, start_id = None, end_id = None):
    
    data = np.asarray(data)
    data = data.reshape(-1,1) if np.prod(data.shape) == max(data.shape) else data
        
    start_id = 0 if start_id is None else start_id
    end_id = data.shape[0] if end_id is None else end_id
    
    data = data[int(start_id):int(end_id),:]
    window_shape = (int(window_shape), data.shape[-1])
    step = (int(step),) * data.ndim
    slices = tuple(slice(None, None, st) for st in step)
    indexing_strides = data[slices].strides
    win_indices_shape = ((np.array(data.shape) - window_shape) // step) + 1
    
    new_shape = tuple(list(win_indices_shape) + list(window_shape))
    strides = tuple(list(indexing_strides) + list(data.strides))
    
    window_data = np.lib.stride_tricks.as_strided(data, shape=new_shape, strides=strides)
    
    return np.squeeze(window_data, 1)

从这个样本数据开始:

n_sample = 2000
n_feat_inp = 6
n_feat_out = 1

X = np.asarray([np.arange(n_sample)]*n_feat_inp).T # (n_sample, n_feat_inp)
y = np.asarray([np.arange(n_sample)]*n_feat_out).T # (n_sample, n_feat_out)

如果我们想要提前一步进行预测

look_back = 5
look_ahead = 1

X_seq = create_windows(X, window_shape = look_back, end_id = -look_ahead)
# X_seq.shape --> (n_sample - look_back, look_back, n_feat_inp)
y_seq = create_windows(y, window_shape = look_ahead, start_id = look_back)
# y_seq.shape --> (n_sample - look_back, look_ahead, n_feat_out)

生成数据的示例:

X_seq[0]: [[0, 0, 0, 0, 0, 0],
           [1, 1, 1, 1, 1, 1],
           [2, 2, 2, 2, 2, 2],
           [3, 3, 3, 3, 3, 3],
           [4, 4, 4, 4, 4, 4]]

y_seq[0]: [[5]]

如果我们想进行多步预测

look_back = 5
look_ahead = 3

X_seq = create_windows(X, window_shape = look_back, end_id = -look_ahead)
# X_seq.shape --> (n_sample - look_back - look_ahead + 1, look_back, n_feat_inp)
y_seq = create_windows(y, window_shape = look_ahead, start_id = look_back)
# y_seq.shape --> (n_sample - look_back - look_ahead + 1, look_ahead, n_feat_out)

生成数据的例子:

X_seq[0]: [[0, 0, 0, 0, 0, 0],
           [1, 1, 1, 1, 1, 1],
           [2, 2, 2, 2, 2, 2],
           [3, 3, 3, 3, 3, 3],
           [4, 4, 4, 4, 4, 4]]

y_seq[0]: [[5],
           [6],
           [7]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接