有没有详细的说明如何使用TimeDistributed、stateful和return_sequences?在这两种情况下,我是否需要将shuffle设置为False?它适用于窗口(1-11、2-12、3-13等)还是应该分批处理(1-11、12-22、13-33等)。
我特别关注LSTM层。
这不影响层的工作方式。其目的是增加一个额外的“时间”维度(它可能不仅仅是时间)。封装后的层将分别应用于考虑此时间维度的输入张量的每个切片。
例如,如果一个层期望具有三个维度的输入形状,比如 (batch, length, features)
,使用TimeDistributed
封装器将使其期望四个维度:(batch, timeDimension, length, features)
然后,该层将被“复制”并等同地应用于时间维度中的每个元素。
对于LSTM层,它的工作方式相同。虽然LSTM层已经期望其输入形状中存在时间维度:(batch, timeSteps, features)
,但您可以使用TimeDistributed
添加另一个“时间”维度(它可能意味着任何内容,而不仅仅是时间),并使得该LSTM
层可用于该新时间维度中的每个元素。
LSTM
- 期望输入为 (batch, timeSteps, features)
TimeDistributed(LSTM())
- 期望输入为 (batch, superSteps, timeSteps, features)
在任何情况下,LSTM仅在timeSteps
维度中执行其递归计算。其他时间维度只是复制此层多次。
TimeDistributed + Dense:
Dense
层(以及可能还有其他一些层)已经支持3D输入,尽管标准是2D: (batch, inputFeatures)
。
使用TimeDistributed与Dense层是可选的,并且结果是相同的:如果您的数据是3D,则Dense层将针对第二个维度重复。
这在文档中已经很好地解释了。
使用循环层,Keras将使用timeSteps
维度执行其循环步骤。对于每个步骤,它自然会有一个输出。
你可以选择获取所有步骤的输出(return_sequences=True
),或仅获取最后一个输出(return_sequences=False
)。
考虑像(batch, timeSteps, inputFeatures)
这样的输入形状和一个带有outputFeatures
个单元的层:
return_sequences=True
时,输出形状为(batch, timeSteps, outputFeatures)
return_sequences=False
时,输出形状为(batch, outputFeatures)
无论如何,如果你使用一个TimeDistributed
包装器,superSteps
维度将保持不变,既出现在输入中,也出现在输出中。
通常情况下,如果你可以将所有序列及其步骤放入一个输入数组中,那就没问题了,你不需要使用stateful=True
层。
Keras为批次中的每个序列创建一个"state"。批次维度等于序列数。当Keras完成处理批次时,它会自动重置状态,这意味着:我们到达了序列的结束(最后一个时间步),从第一步开始带入新的序列。
使用stateful=True
时,这些状态将不会被重置。这意味着,将另一个批次发送到模型将不会被解释为新的序列集,而是已处理过的序列的附加步骤。你必须手动调用model.reset_states()
告诉模型,你已经达到序列的最后一步,或者你将开始新序列。
唯一需要使用shuffle=False
的情况是此stateful=True
的情况。因为对于每个批次,都输入了许多序列。在每个批次中,这些序列必须保持相同的顺序,以便每个序列的状态不会混淆。
状态层适用于:
到目前为止,我能够处理窗口的唯一方法是复制数据。
输入数组应按窗口组织。每个窗口步骤一个序列。如果您想将所有窗口步骤作为单个批次条目保留,则可以选择利用TimeDistributed
包装器。但您也可以将所有步骤作为单独的序列。
stateful=True
层不能与窗口一起使用,因为存在状态。如果您在一个批次中输入从1到12的步骤,则下一个批次将期望步骤13作为第一个步骤以保持连接。