python - 如何在 Keras 中为有状态 LSTM 准备数据?

标签 python keras lstm

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

这是我的数据的样子。我有很多录音,例如 N。每个记录包含 22 个长度为 M_i(i=1,...N) 的时间序列。我想在 Keras 中使用有状态模型,但我不知道如何 reshape 我的数据,尤其是我应该如何定义我的 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 是目标矢量。

那么,我的问题是,根据上面解释的数据,如何为有状态模型 reshape 数据并考虑批处理概念?是否需要采取预防措施?

我想做的是能够将每个记录的每个 time_step 分类为癫痫发作/非癫痫发作。

编辑:我想到的另一个问题是:我的录音包含不同长度的序列。我的有状态模型可以了解每个记录的长期依赖性,因此这意味着 batch_size 从一个记录到另一个记录不同......如何处理?在完全不同的序列(test_set)上测试会不会导致泛化问题?

谢谢

最佳答案

我认为您不需要有状态层来实现您的目的。

如果您想长期学习,就不要创建这些滑动窗口。将您的数据塑造为:

(number_of_independent_sequences, length_or_steps_of_a_sequence, variables_or_features_per_step)

我不确定我是否正确理解了您问题中的措辞。如果“录音”类似于“电影”或“歌曲”、“语音剪辑”或类似的东西,则:

  • 序列数 = 记录数

按照“录音”的想法,时间步长将是“视频中的帧”,或音频文件中的“样本”(时间 x 1 个 channel 的样本率)。 (注意,keras 中的“样本”是“序列/录音”,而音频处理中的“样本”是 keras 中的“步骤”)。

  • time_steps = 帧数或音频样本数

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

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

将您的数据塑造成这样将适用于 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()

可能只有优化器的更新方式发生了变化。

对于您的情况,如果您可以创建上述形状的输入数据并且您不打算递归地预测 future ,我认为没有理由使用 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

然后您可以:

  • 单独加载每个脑电图:

    • 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 并使用:

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

关于python - 如何在 Keras 中为有状态 LSTM 准备数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52071751/

相关文章:

python - 为什么我的 Django 管理员没有加载 css?

python-3.x - Keras One Hot 编码内存管理 - 最好的出路

python - PyTorch:第二次尝试向后遍历图形,但缓冲区已被释放

deep-learning - 为什么用于预测的 Keras LSTM 批量大小必须与拟合批量大小相同?

python - 如何使 BeautifulSoup 'replace_with' 属性与 'unicode' 对象一起使用?

python - Jupyter Notebook - 在函数内部绘图 - 图未绘制

python - 如何在 Selenium 中保留登录状态

python - Numpy 数组作为图像、图像 channel

python - 发生此错误。 "TypeError: Expected int64, got 1e-07 of type ' float' instead."。我该怎么办?

optimization - 神经网络的高变异性损失