如何使用有状态LSTM和batch_size布局训练数据> 1

时间:2018-02-02 07:15:52

标签: tensorflow machine-learning keras theano lstm

背景

我想在Keras进行“有状态”LSTM的小批量培训。我的输入训练数据是一个大矩阵“X”,其尺寸为m x n,其中

m = number-of-subsequences
n = number-of-time-steps-per-sequence

X的每一行包含一个子序列,该序列在前一行的子序列离开的地方拾取。所以给定一长串数据,

Data = ( t01, t02, t03, ... )

其中“tK”表示原始数据中位置K处的标记,序列在X中排列如下:

X = [
  t01 t02 t03 t04
  t05 t06 t07 t08
  t09 t10 t11 t12
  t13 t14 t15 t16
  t17 t18 t19 t20
  t21 t22 t23 t24
]

问题

我的问题是当我对有状态LSTM以这种方式进行数据的小批量培训时会发生什么。具体而言,小批量训练通常一次训练“连续”的行组。因此,如果我使用2的小批量,那么X将被分成三个小批量X1,X2和X3,其中

X1 = [
  t01 t02 t03 t04
  t05 t06 t07 t08
]

X2 = [
  t09 t10 t11 t12
  t13 t14 t15 t16
]

X3 = [
  t17 t18 t19 t20
  t21 t22 t23 t25
]

请注意,此类迷你批处理与训练有状态 LSTM不一致,因为处理上一批次的最后一列所产生的隐藏状态不是与时间对应的隐藏状态 - 在后续批次的第一列之前的步骤。

要看到这一点,请注意迷你批次将像从左到右一样进行处理:

------ X1 ------+------- X2 ------+------- X3 -----
t01 t02 t03 t04 | t09 t10 t11 t12 | t17 t18 t19 t20
t05 t06 t07 t08 | t13 t14 t15 t16 | t21 t22 t23 t24

暗示

- Token t04 comes immediately before t09
- Token t08 comes immediately before t13
- Token t12 comes immediately before t17
- Token t16 comes immediately before t21

但我希望使用迷你批处理对行进行分组,以便我们在小批量中获得这种时间对齐:

------ X1 ------+------- X2 ------+------- X3 -----
t01 t02 t03 t04 | t05 t06 t07 t08 | t09 t10 t11 t12
t13 t14 t15 t16 | t17 t18 t19 t20 | t21 t22 t23 t24

在Keras训练LSTM时,实现这一目标的标准方法是什么?

感谢您提供任何指示。

2 个答案:

答案 0 :(得分:1)

感谢。似乎丹尼尔暗示如果我像这样重新组织X,我可以使用批量大小为2:

X = [
  t01 t02 t03 t04 
  t13 t14 t15 t16
  t05 t06 t07 t08
  t17 t18 t19 t20 
  t09 t10 t11 t12
  t21 t22 t23 t24
]

这是正确的解释吗?

答案 1 :(得分:0)

解决方案1 ​​ - 批量大小= 1

好吧,既然看起来你实际上只有一个序列(尽管它是分开的,它仍然是一个单一的序列,对吗?),你确实需要训练批量大小等于1.

如果您不想更改或重新组织数据,只需:

 X = X.reshape((-1,length,features))

     #where
         #length = 4 by your description    
         #features = 1 (if you have only one var over time, as it seems)

解决方案2 - 重新组合长度= 8

仍然使用批量大小为1 ,重新整形输入数据(在将其传递给模型之前),因此它具有双倍长度。

最终结果将与您所描述的尺寸为2的小型车进行培训完全相同。(但请确保在模型的输入形状中将批量大小设置为1,否则这会给您错误结果)。

X = X.reshape((-1, 2 * length, features)) 

这会给你:

X = [
  [t01 t02 t03 t04 t05 t06 t07 t08]
  [t09 t10 t11 t12 t13 t14 t15 t16]
  [t17 t18 t19 t20 t21 t22 t23 t24]
]

解决方案3 - 只有在您实际拥有两个不同的序列时才可能

根据您的描述,您似乎只有一个序列。如果您确实有两个不同/独立的序列,那么您可以制作一批大小为2.

如果将您的序列分成两部分(并且它们之间失去连接)不是问题,您可以重新排列数据:

X = X.reshape((2,-1,length, features))

然后:

X0 = X[:,0]
X1 = X[:,1]
...

您可以尝试将其分组到一个数组中:

X = X.reshape((2,-1,length, features))
X = np.swapaxes(X,0,1).reshape((-1,length,features))

然后:

X0 = X[0]
X1 = X[1]
...

只要您在模型的输入形状中明确将批量大小设置为2,您就可以尝试将完整的X传递给培训。