Python 如何在Keras中为有状态LSTM准备数据?
我想为二进制分类开发一种时间序列方法,在Keras中使用有状态LSTM 下面是我的数据的外观。我得到了很多录音,比如说Python 如何在Keras中为有状态LSTM准备数据?,python,keras,lstm,Python,Keras,Lstm,我想为二进制分类开发一种时间序列方法,在Keras中使用有状态LSTM 下面是我的数据的外观。我得到了很多录音,比如说N。每个记录由22个长度为M_i(i=1,…N)的时间序列组成。我想在Keras中使用有状态模型,但我不知道如何重塑数据,特别是如何定义我的批处理大小 下面是我如何处理无状态LSTM的。我为所有录音创建了长度序列look\u back,这样我就有了大小数据(N*(M\u I-look\u back),look\u back,22=N\u特征) 以下是我用于此目的的函数: def
N
。每个记录由22个长度为M_i(i=1,…N)的时间序列组成。我想在Keras中使用有状态模型,但我不知道如何重塑数据,特别是如何定义我的批处理大小
下面是我如何处理无状态
LSTM的。我为所有录音创建了长度序列look\u back
,这样我就有了大小数据(N*(M\u I-look\u back),look\u back,22=N\u特征)
以下是我用于此目的的函数:
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个样本,n个特征)
(每个记录)的二维数据数组,targ
是目标向量
因此,我的问题是,基于上面解释的数据,如何为一个有状态的模型重塑数据,并考虑批处理的概念?有预防措施吗
我想做的是能够将每个录音的每一个时间步分类为“发作/未发作”
编辑:我想的另一个问题是:我有包含不同长度序列的录音。我的状态模型可以了解每个记录的长期依赖性,这意味着不同记录的批量大小不同。。。如何处理?当在完全不同的序列(测试集)上测试时,它不会导致泛化问题吗
谢谢我认为您不需要一个有状态的层
如果你想长期学习,就不要创建这些滑动窗口。将您的数据塑造为:
(number_of_independent_sequences, length_or_steps_of_a_sequence, variables_or_features_per_step)
我不确定我是否正确理解了你问题中的措辞。如果“录音”类似于“电影”或“歌曲”、“语音剪辑”或类似内容,则:
- 序列数量=录制数量
按照“录制”的想法,时间步长将是“视频中的帧”,或音频文件中的“采样”(1个通道的时间x采样率)。(请注意,keras中的“样本”是“序列/录音”,而音频处理中的“样本”是keras中的“步骤”)
- 时间步长=帧数或音频采样数
最后,功能/变量的数量。在电影中,它就像RGB频道(3个功能),在音频中,也是频道数(立体声中为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()
可能只有优化器的更新方式会发生变化
对于您的情况,如果您可以创建上述形状的输入数据,并且不打算递归地预测未来,那么我看不出使用stateful=True
的理由
分类每一步
要对每个步骤进行分类,不需要创建滑动窗口,也不需要使用stateful=True
通过设置return\u sequences=True
,重复层可以选择输出所有时间步长
如果您有一个带有shape(批处理、步骤、特征)
的输入,则需要带有shape(批处理、步骤1)
的目标,即每个步骤一个类
简而言之,您需要:
- 具有
return\u sequences=True的LSTM层
X\u列车
带形状(文件,总长度,22)
Y\u序列
带形状(文件,总长度,1)
提示:由于LSTM从不很好地对开始进行分类,您可以尝试使用双向(LSTM(..)
层
不同长度的输入
要使用不同长度的输入,需要设置input\u shape=(无,特征)
。考虑到我们在聊天中的讨论,features=22
然后你可以:
- 分别加载每个EEG:
X\u列车
as(1,eeg\u长度,22)
Y\u序列
as(1,eeg\u长度,1)
- 使用
模型分别训练每个脑电图。批量训练(阵列、目标)
- 您需要手动管理历元,并对验证数据使用
test\u on\u batch
- 用零或另一个虚拟值填充较短的脑电图,直到它们都达到
max_eeg_length
并使用:
- 模型开头的
掩蔽
层,用于丢弃带有虚拟值的步骤
X\u列车
as(脑电图,最大脑电图长度,22)
Y\u序列
as(脑电图,最大脑电图长度,1)
- 您可以使用常规的
型号进行训练。fit(X\U系列,Y\U系列,…)
使用stateful有什么特殊原因吗?(它在计算上与常规层没有什么不同,也不适用于回望窗口。)astateful=False
学习的东西与astateful=True
学习的东西完全相同。没有区别。唯一的区别是:stateful=False
认为“这一批输入独立于前一批输入”,而stateful=True
则认为“这一批输入与上一批输入序列相同,我假设没有中断”。我认为“stateful”这个名称选择得非常糟糕。“无状态”一词表示没有内存状态,但事实并非如此。它应该被称为类似于keep_states=True
(因为不要在每个批处理后重置状态)。这种冗余(滑动窗口)是不必要的,我不知道他们为什么要教它。这完全违背了LSTM可以学到的“长期依赖性”。我必须更好地理解您的数据才能回答。见下面我的答案。你不知道