如何为Keras中的有状态LSTM准备数据?

时间:2018-08-29 07:24:52

标签: python keras lstm

我想使用Keras中的有状态LSTM开发用于二进制分类的时间序列方法

这是我的数据的外观。 N我有很多录音。每个记录包含22个时间序列,长度为M_i(i=1,...N)。我想在Keras中使用有状态模型,但是我不知道如何重塑数据,尤其是关于如何定义batch_size的问题。

这是我进行stateless LSTM的方法。我为所有录音创建了长度为look_back的序列,这样我得到了大小为(N*(M_i-look_back), look_back, 22=n_features)

的数据

这是我用于此目的的功能:

def create_dataset(feat,targ, look_back=1):
    dataX, dataY = [], []
#     print (len(targ)-look_back-1)
    for i in range(len(targ)-look_back):
        a = feat[i:(i+look_back), :]
        dataX.append(a)
        dataY.append(targ[i + look_back-1])
    return np.array(dataX), np.array(dataY)

其中feat是大小为(n_samples, n_features)的二维数据数组(对于每个记录),targ是目标向量。

因此,我的问题是,根据上述数据,如何为有状态模型重塑数据并考虑批处理概念?有预防措施吗?

我想要做的是能够将每个记录的每个时间步分为癫痫发作/非癫痫发作。

编辑:我想到的另一个问题是:我的录音包含不同长度的序列。我的状态模型可以学习每个记录的长期依赖关系,因此这意味着batch_size在一个记录与另一个记录之间是不同的...如何处理?在完全不同的序列(test_set)上进行测试时,会不会引起泛化麻烦?

谢谢

1 个答案:

答案 0 :(得分:2)

我认为您不需要出于目的的有状态层。

如果您想长期学习,请不要创建这些滑动窗口。数据的形状为:

(number_of_independent_sequences, length_or_steps_of_a_sequence, variables_or_features_per_step)

我不确定您的问题中的措词是否正确。如果“录音”就像是“电影”或“歌曲”,“语音剪辑”或类似的东西,则:

  • 序列数=记录数

按照“录制”的想法,时间步长是音频文件中的“视频中的帧”或“采样”(时间x 1个通道的sample_rate)。 (请注意,喀拉拉语中的“样本”是“序列/记录”,而音频处理中的“样本”是喀拉斯语中的“步骤”)。

  • time_steps =帧数或音频样本

最后,特征/变量的数量。在电影中,就好像是RGB通道(3个功能),音频一样,还是通道数(2个立体声)。在其他类型的数据中,它们可能是温度,压力等。

  • 功能=每个步骤中测得的变量数量

具有这种形状的数据将对有状态的= True和False都适用。

这两种训练方法是等效的:

#with stateful=False
model.fit(X, Y, batch_size=batch_size)

#with stateful=True
for start in range(0, len(X), batch_size):
    model.train_on_batch(X[start:start+batch_size], Y[start:start+batch_size])
    model.reset_states()

仅在更新优化器的方式上可能会有更改。

对于您来说,如果您可以创建上述形状的输入数据,并且不打算递归地预测未来,那么我认为没有理由使用stateful=True

对每个步骤进行分类

要对每个步骤进行分类,您无需创建滑动窗口,也不必使用stateful=True

循环图层可以通过设置return_sequences=True来输出所有时间步长。

如果您使用形状为(batch, steps, features)的输入,则将需要形状为(batch, steps, 1)的目标,即每步一个类

简而言之,您需要:

  • return_sequences=True的LSTM层
  • X_train,形状为(files, total_eeg_length, 22)
  • Y_train,形状为(files, total_eeg_length, 1)

提示:由于LSTM从未很好地对开始进行分类,因此您可以尝试使用Bidirectional(LSTM(....))层。

长度不同的输入

要使用不同长度的输入,您需要设置input_shape=(None, features)。考虑我们在聊天室features = 22中的讨论。

然后,您可以:

  • 分别加载每个EEG:

    • X_train(1, eeg_length, 22)
    • Y_train(1, eeg_length, 1)
    • 分别用model.train_on_batch(array, targets)训练每个EEG。
    • 您将需要手动管理纪元,并将test_on_batch用于验证数据。
  • 用零或另一个虚拟值填充较短的EEG,直到它们全部达到max_eeg_length并使用:

    • 模型开始处的Masking层,以丢弃具有虚拟值的步骤。
    • X_train(eegs, max_eeg_length, 22)
    • Y_train(eegs, max_eeg_length, 1)
    • 您可以使用常规的model.fit(X_train, Y_train,...)
    • 进行训练