了解Tensorflow LSTM输入形状

时间:2016-09-05 05:43:30

标签: python tensorflow regression lstm

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

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

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

目前我遇到的主要问题是了解TensorFlow期望输入格式化的方式。我已经看到了各种例子,例如this,但是这些例子涉及一大串连续时间序列数据。我的数据是不同的样本,每个样本都是一个独立的时间序列。

2 个答案:

答案 0 :(得分:10)

documentation of tf.nn.dynamic_rnn州:

  

inputs:RNN输入。如果time_major == False(默认值),则必须是形状张量:[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)

documentation开始,outputs的形状为[batch_size, 10, 256],即每个时间步长为256输出。 state将是tuple个形状[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)

outputsstate形状中的数字256由cell.output_size resp确定。 cell.state_size。在创建上面的LSTMCell时,这些是相同的。另请参阅LSTMCell documentation

答案 1 :(得分:1)

(当直接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

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

实际上,在我们需要进行的3D输入中,我们仍然有5个观测值。关键是我们需要以不同的方式排列它们:RNN将采用第一个数组(即timestep1)的第一行(或指定的批处理-但我们将在此处保持简单),并采用第二个堆叠数组的第一行(即, timestep2)。然后第二行...直到最后一行(在我们的示例中为第五行)。 S o,在每个时间步长的每一行中,我们都需要具有两个特征,当然,这两个特征应以不同的数组分开,每个数组对应于其时间步长。我们来看一下数字。

我将制作两个数组以便于理解。请记住,由于我们在df中的组织方案,您可能已经注意到我们需要将前两列(即timestep1的功能1和2)作为我们的第一层堆栈,而后两列,即第3和第4个,作为我们的堆栈第二阵列,因此最终一切都变得有意义。

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]])

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

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)

就是这样:考虑到我们二维特征矩阵的组织,我们已经准备好将特征矩阵输入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]]])

¡希望这会有所帮助!