我想开发一种用于二元分类的时间序列方法,在 Keras 中使用有状态的 LSTM
这是我的数据的外观。我有很多,比如说N
,录音。每个记录由 22 个长度M_i(i=1,...N)
的时间序列组成。我想在 Keras 中使用有状态模型,但我不知道如何重塑我的数据,尤其是关于我应该如何定义我的batch_size
。
以下是我为 LSTMstateless
的进行方式。我为所有记录创建了长度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
是目标向量。
所以,我的问题是,根据上面解释的数据,如何重塑有状态模型的数据并考虑批处理概念?有没有预防措施?
我想做的是能够将每个录音的每个time_step分类为癫痫发作/不癫痫发作。
编辑:我想到的另一个问题是:我的录音包含不同长度的序列。我的有状态模型可以学习每个记录long_term依赖关系,这意味着batch_size从一个记录到另一个记录不同......如何处理?在完全不同的序列上测试时,它不会引起泛化问题吗(test_set(?
谢谢
我认为你不需要有状态的层来实现你的目的。
如果你想要长期学习,就不要创建这些滑动窗口。将数据形状设置为:
(number_of_independent_sequences, length_or_steps_of_a_sequence, variables_or_features_per_step)
我不确定我是否正确理解了您问题中的措辞。如果"录音"像"电影"或"歌曲","语音剪辑"或类似的东西,那么:
- 序列数 = 记录数
遵循"录制"的想法,时间步长将是音频文件中的"视频中的帧"或"样本"(1 个通道的时间 x sample_rate(。(请注意,keras 中的"样本"是"序列/录音",而音频处理中的"样本"是 keras 中的"步骤"(。
- time_steps = 帧数或音频样本数
最后,特征/变量的数量。在电影中,它就像 RGB 通道(3 个功能(,在音频中,也像通道的数量(2 个立体声(。在其他类型的数据中,它们可能是温度、压力等。
- 特征 = 每个步骤中测量的变量数
将数据形状设置为这样将适用于有状态 = 真和假。
这两种训练方法是等效的:
#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 图层 - 带形状
(files, total_eeg_length, 22)
X_train
- 带形状
(files, total_eeg_length, 1)
Y_train
提示:由于 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)
分别训练每个脑电图。 - 您将需要手动管理纪元,并将
test_on_batch
用于验证数据。
用零或其他虚拟值填充较短的脑电图,直到它们都达到
max_eeg_length
并使用:- 模型开头的
Masking
层,用于丢弃具有虚拟值的步骤。 X_train
饰(eegs, max_eeg_length, 22)
Y_train
饰(eegs, max_eeg_length, 1)
- 您可以定期训练
model.fit(X_train, Y_train,...)
- 模型开头的