了解Tensorflow LSTM输入形状

Ren*_*tha 18 python regression lstm tensorflow

我有一个数据集X,其中包含N = 4000个样本,每个样本由d = 2个特征(连续值)组成,跨越t = 10个时间步长.在时间步骤11,我还具有每个样本的相应"标签",它们也是连续值.

目前,我的数据集的形状为X:[4000,20],Y:[4000].

考虑到d特征的10个先前输入,我想使用TensorFlow训练LSTM来预测Y(回归)的值,但是我很难在TensorFlow中实现它.

我目前面临的主要问题是了解TensorFlow如何期望输入格式化.我见过各种各样的例子,如,但这些例子处理连续时间序列数据的一个大的字符串.我的数据是不同的样本,每个都是独立的时间序列.

fwa*_*lch 11

各州的文件tf.nn.dynamic_rnn:

inputs:RNN输入.如果time_major == False(默认),则必须是形状的Tensor:[batch_size, max_time, ...]或这些元素的嵌套元组.

在您的情况下,这意味着输入应具有的形状[batch_size, 10, 2].不是一次训练所有4000个序列,而是batch_size在每次训练迭代中只使用其中的许多序列.类似下面的东西应该工作(为了清晰起见,添加了重塑):

batch_size = 32
# batch_size sequences of length 10 with 2 values for each timestep
input = get_batch(X, batch_size).reshape([batch_size, 10, 2])
# Create LSTM cell with state size 256. Could also use GRUCell, ...
# Note: state_is_tuple=False is deprecated;
# the option might be completely removed in the future
cell = tf.nn.rnn_cell.LSTMCell(256, state_is_tuple=True)
outputs, state = tf.nn.dynamic_rnn(cell,
                                   input,
                                   sequence_length=[10]*batch_size,
                                   dtype=tf.float32)
Run Code Online (Sandbox Code Playgroud)

文档中,outputs将是形状[batch_size, 10, 256],即每个时间步长一个256输出.state将是一个形状元组[batch_size, 256].您可以预测您的最终值,每个序列一个,来自:

predictions = tf.contrib.layers.fully_connected(state.h,
                                                num_outputs=1,
                                                activation_fn=None)
loss = get_loss(get_batch(Y).reshape([batch_size, 1]), predictions)
Run Code Online (Sandbox Code Playgroud)

在的形状的数量256 outputsstate由下式确定cell.output_sizeRESP.cell.state_size.在创建LSTMCell上述内容时,这些是相同的.另请参阅LSTMCell文档.


Eza*_*e11 5

(这个答案“解决”了当直接 np.reshape() 没有按照我们想要的那样组织最终数组时的问题。如果我们想直接重塑为 3D np.reshape 会这样做,但要注意最后的组织输入)。

在我个人尝试最终解决为 RNN 提供输入形状的问题并且不再混淆时,我将对此给出我的“个人”解释。

在我的情况下(我认为许多其他人可能在他们的特征矩阵中有这种组织方案),外面的大多数博客“无济于事”。让我们尝试一下如何将 2D 特征矩阵转换为用于 RNN 的 3D 形状。

假设我们的特征矩阵中有这种组织类型:我们有5 个观察值(即行 - 我认为这是最合乎逻辑的术语),并且在每一行中,每个时间步都有2 个特征(我们有 2时间步长),像这样:

(这df是为了更好地从视觉上理解我的话)

In [1]: import numpy as np                                                           

In [2]: arr = np.random.randint(0,10,20).reshape((5,4))                              

In [3]: arr                                                                          
Out[3]: 
array([[3, 7, 4, 4],
       [7, 0, 6, 0],
       [2, 0, 2, 4],
       [3, 9, 3, 4],
       [1, 2, 3, 0]])

In [4]: import pandas as pd                                                          

In [5]: df = pd.DataFrame(arr, columns=['f1_t1', 'f2_t1', 'f1_t2', 'f2_t2'])         

In [6]: df                                                                           
Out[6]: 
   f1_t1  f2_t1  f1_t2  f2_t2
0      3      7      4      4
1      7      0      6      0
2      2      0      2      4
3      3      9      3      4
4      1      2      3      0
Run Code Online (Sandbox Code Playgroud)

我们现在将使用这些值来处理它们。这里的问题是RNN 将“时间步长”维度纳入其输入,因为它们的架构性质。我们可以将这个维度想象为按照我们拥有的时间步数将二维数组一个接一个地堆叠起来。在这种情况下,我们有两个时间步;所以我们将堆叠两个二维数组:一个用于 timestep1,一个用于 timestep2。

实际上,在我们需要进行的 3D 输入中,我们仍然有 5 个观察值。问题是我们需要以不同的方式排列它们:RNN 将取第一个数组(即 timestep1)的第一行(或指定的批次 - 但我们在这里保持简单)和第二个堆叠数组的第一行(即时间步长2)。然后是第二行……直到最后一行(在我们的示例中是第 5 行)。所以,在每个时间步的每一行中,我们需要有两个特征,当然,分开在不同的数组中,每一个对应于它的时间步。让我们用数字来看看。

我将制作两个数组以便于理解。请记住,由于我们在 df 中的组织方案,您可能已经注意到我们需要将前两列(即时间步长 1 的特征 1 和 2)作为我们的第一个堆栈数组,最后两列,即,第三个和第四个,作为我们堆栈的第二个数组,所以一切最终都有意义。

In [7]: arrStack1 = arr[:,0:2]                                                       

In [8]: arrStack1                                                                    
Out[8]: 
array([[3, 7],
       [7, 0],
       [2, 0],
       [3, 9],
       [1, 2]])

In [9]: arrStack2 = arr[:,2:4]                                                       

In [10]: arrStack2                                                                   
Out[10]: 
array([[4, 4],
       [6, 0],
       [2, 4],
       [3, 4],
       [3, 0]])
Run Code Online (Sandbox Code Playgroud)

最后,我们唯一需要做的就是堆叠两个数组(“一个在另一个之后”),就好像它们是同一个最终结构的一部分:

In [11]: arrfinal3D = np.stack([arrStack1, arrStack2])                               

In [12]: arrfinal3D                                                                  
Out[12]: 
array([[[3, 7],
        [7, 0],
        [2, 0],
        [3, 9],
        [1, 2]],

       [[4, 4],
        [6, 0],
        [2, 4],
        [3, 4],
        [3, 0]]])

In [13]: arrfinal3D.shape                                                            
Out[13]: (2, 5, 2)
Run Code Online (Sandbox Code Playgroud)

就是这样:考虑到我们对 2D 特征矩阵的组织,我们已经准备好将特征矩阵输入到 RNN 单元中。

(对于关于所有这些的单衬,您可以使用:

In [14]: arrfinal3D_1 = np.stack([arr[:,0:2], arr[:,2:4]])                           

In [15]: arrfinal3D_1                                                                
Out[15]: 
array([[[3, 7],
        [7, 0],
        [2, 0],
        [3, 9],
        [1, 2]],

       [[4, 4],
        [6, 0],
        [2, 4],
        [3, 4],
        [3, 0]]])
Run Code Online (Sandbox Code Playgroud)