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

问题描述 投票:-1回答:1

我想开发一种二元分类的时间序列方法,在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)上测试时,它不会导致泛化问题吗?

谢谢

python keras lstm
1个回答
3
投票

我不认为你需要一个有状态的层来达到你的目的。

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

(number_of_independent_sequences, length_or_steps_of_a_sequence, variables_or_features_per_step)

我不确定我在你的问题中正确理解了措辞。如果“录音”类似于“电影”或“歌曲”,“语音片段”或类似的东西,那么:

  • 序列数=录音数量

遵循“录制”的想法,时间步长将是“视频中的帧”,或音频文件中的“样本”(时间x sample_rate,用于1个频道)。 (注意,keras中的“样本”是“序列/记录”,而音频处理中的“样本”是keras中的“步骤”)。

  • time_steps =帧数或音频样本数

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

  • features =每个步骤中测量的变量数

使您的数据形状像这样将适用于stateful = 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)的目标,每步一个类。

简而言之,您需要:

  • LSTM层与return_sequences=True
  • 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)分别训练每个脑电图。 您需要手动管理纪元,并使用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,...)训练
© www.soinside.com 2019 - 2024. All rights reserved.