我有一个数据集X,其中包含 N = 4000个样本,每个样本包含 d = 2个特征(连续值),跨越 t = 10时间步骤即可。在时间步骤11,我还有每个样本的相应“标签”,它们也是连续值。
目前我的数据集的形状为X:[4000,20],Y:[4000]。
我想使用TensorFlow训练LSTM来预测Y(回归)的值,给出之前10个d特征的输入,但是我很难在TensorFlow中实现它。
目前我遇到的主要问题是了解TensorFlow期望输入格式化的方式。我已经看到了各种例子,例如this,但是这些例子涉及一大串连续时间序列数据。我的数据是不同的样本,每个样本都是一个独立的时间序列。
答案 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)
outputs
和state
形状中的数字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]]])
¡希望这会有所帮助!