Keras 困惑于如何实现时间分布式LSTM+;LSTM 经过大量的阅读和图解,我想我已经提出了一个模型,我可以用它作为更多测试的基础,我需要调整哪些参数和特征。然而,我对如何实现以下测试用例感到困惑(所有数字都比最终模型小几个数量级,但我想从小的角度开始): 输入数据:5000x1时间序列向量,分为1000x1的5个时代 对于每个时间步,将通过双向LSTM层的3个时间分布副本输入3个时代的数据,每个副本将输出10x1的向量(提取10个特征),然后将其作为第二个双向LSTM层的输入 对于每个时间步,第一个和最后一个标签将被忽略,但中心标签是所需的
这是我想到的,它可以编译。但是,看看model.summary,我想我忽略了一个事实,即我希望第一个LSTM在每个输出时间步的3个输入序列上运行。我做错了什么Keras 困惑于如何实现时间分布式LSTM+;LSTM 经过大量的阅读和图解,我想我已经提出了一个模型,我可以用它作为更多测试的基础,我需要调整哪些参数和特征。然而,我对如何实现以下测试用例感到困惑(所有数字都比最终模型小几个数量级,但我想从小的角度开始): 输入数据:5000x1时间序列向量,分为1000x1的5个时代 对于每个时间步,将通过双向LSTM层的3个时间分布副本输入3个时代的数据,每个副本将输出10x1的向量(提取10个特征),然后将其作为第二个双向LSTM层的输入 对于每个时间步,第一个和最后一个标签将被忽略,但中心标签是所需的,keras,lstm,Keras,Lstm,这是我想到的,它可以编译。但是,看看model.summary,我想我忽略了一个事实,即我希望第一个LSTM在每个输出时间步的3个输入序列上运行。我做错了什么 model = Sequential() model.add(TimeDistributed(Bidirectional(LSTM(11, return_sequences=True, recurrent_dropout=0.1, unit_forget_bias=True), input_shape=(3, 3, epoch_len),
model = Sequential()
model.add(TimeDistributed(Bidirectional(LSTM(11, return_sequences=True, recurrent_dropout=0.1, unit_forget_bias=True), input_shape=(3, 3, epoch_len), merge_mode='sum'), input_shape=(n_epochs, 3, epoch_len)))
model.add(TimeDistributed(Dense(7)))
model.add(TimeDistributed(Flatten()))
model.add(Bidirectional(LSTM(12, return_sequences=True, recurrent_dropout=0.1, unit_forget_bias=True), merge_mode='sum'))
model.add(TimeDistributed(Dense(n_classes, activation='softmax')))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
由于你的问题有点混乱,我将采取以下假设
- 您有一个5000个时间步骤的时间序列,每个步骤都有一个功能。形状
(1,5000,1)
- 问题答案的主要部分:您想运行一个“滑动窗口”案例,窗口大小等于3000,窗口跨距为1000李>
- 您希望将窗口大小划分为3个内部时间序列,每个序列包含1000个步骤,每个步骤仅包含一个功能。这些系列中的每一个都与独立系列输入相同的LSTM(相当于有3个LSTM副本)-形状
(slidingWindowSteps,3,1000,1)
- 重要提示:从这3个系列中,您需要3个不带长度且具有10个功能的输出。形状
。(您的图像显示为1x10,但您的文本显示为10x1,我假设图像是正确的)李>(1,3,10)
- 您希望将这3个输出合并为一个由3个步骤组成的单一序列,shape
(1,3,10)
- 您希望处理此3步序列的LSTM也返回3步序列
(15000,1)
为例,我们需要先将其拆分为包含3组1000个样本的批次。这里我只为X做这个,你必须对Y做类似的事情
numberOfOriginalSequences = 1
totalSteps = 5000
features = 1
#example of original input with 5000 steps
originalSeries = np.array(
range(numberOfOriginalSequences*totalSteps*features)
).reshape((numberOfOriginalSequences,
totalSteps,
features))
windowSize = 3000
windowStride = 1000
totalWindowSteps = ((totalSteps - windowSize)//windowStride) + 1
#at first, let's keep these dimensions for better understanding
processedSequences = np.empty((numberOfOriginalSequences,
totalWindowSteps,
windowSize,
features))
for seq in range(numberOfOriginalSequences):
for winStep in range(totalWindowSteps):
start = winStep * windowStride
end = start + windowSize
processedSequences[seq,winStep,:,:] = originalSeries[seq,start:end,:]
#now we reshape the array to transform each window step in independent sequences:
totalSamples = numberOfOriginalSequences*totalWindowSteps
groupsInWindow = windowSize // windowStride
processedSequences = processedSequences.reshape((totalSamples,
groupsInWindow,
windowStride,
features))
print(originalSeries)
print(processedSequences)
创建模型:
关于第一个添加的图层的一些评论:
- 该模型只考虑一个
。这个形状是输入形状
。它应该位于最外部的包装器中:TimeDistributed李>(groupsInWindow、windowStride、features)
- 您不想保留1000个时间步,只需要10个结果特性:
。(如果需要更多层,可以在第一阶段使用多个LSTM。在这种情况下,第一个LSTM可以保留步骤,只有最后一个需要使用return\u sequences=False
)return\u sequences=False
- 您需要10个功能,因此
units=10
from keras.models import Model
intermediateFeatures = 10
inputTensor = Input((groupsInWindow,windowStride,features))
out = TimeDistributed(
Bidirectional(
LSTM(intermediateFeatures,
return_sequences=False,
recurrent_dropout=0.1,
unit_forget_bias=True),
merge_mode='sum'))(inputTensor)
此时,您已经消除了1000个时间步。因为我们使用了return\u sequences=False
,所以不需要展平或类似的东西。数据已经以(示例、组窗口、中间功能)
的形式成形。密集的
层也是不必要的。但如果你想按你的方式做,只要最终的形状是一样的,就不会“错”
arbitraryLSTMUnits = 12
n_classes = 17
out = Bidirectional(
LSTM(arbitraryLSTMUnits,
return_sequences=True,
recurrent_dropout=0.1,
unit_forget_bias=True),
merge_mode='sum')(out)
out = TimeDistributed(Dense(n_classes, activation='softmax'))(out)
如果要放弃边界,可以添加此层:
out = Lambda(lambda x: x[:,1,:])(out) #model.add(Lambda(lambda x: x[:,1,:]))
完成模型:
model = Model(inputTensor,out)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
以下是维度如何通过此模型流动。 我放在这里的第一个维度(
totalSamples
)在model.summary()中显示为None
- 输入:
(totalSamples、groupsInWindow、windowStride、features)
- 时间分布LSTM的工作原理如下:
- TimeDistributed允许第四维,即
groupsInWindow
。
将保留此维度李>
- 带有
return\u sequences=False
的LSTM将消除windowStride
并更改功能(windowStride
,最后第二个维度,位于此LSTM的时间步长位置):
- 结果:
(总样本、组窗口、绝热特性)
- 另一个LSTM没有时间分布,将不会有第四维度。这样,
groupsInWindow
(倒数第二个)将成为“时间步长”。但是return\u sequences=True
不会像第一个LSTM那样消除时间步长。结果:(totalSamples、groupsInWindow、arbitraryLSTMUnits)
- 最后的
Dense
层,因为它正在接收一个3D输入,将解释第二个维度,就像它是一个时间分布的一样,并保持不变,只将其自身应用于特征维度。结果:(totalSamples,groupsInWindow,n_类)
感谢您的详细回复,我将从今天开始尝试。在我发布这篇文章几小时后,我发现了重复数据。不过,谢谢你纠正了我问题中的一些错误和误解。很抱歉,我花了比计划更长的时间才回到这个问题上来。我以前没有接触过函数式API模型,但现在我意识到这正是我所需要的。我可以编译您的代码,甚至测试fit函数是否可以与model.fit(processedSequences,labels)
一起使用。但是,这仅在标签是(3,3,n_类)数组时有效