经过大量的阅读和图解,我想我已经提出了一个模型,我可以用它作为更多测试我需要调整哪些参数和功能的基础。但是,我对如何实现以下测试用例感到困惑(所有数字都比最终模型小,但我想从小开始):
这是我提出的,编译的。但是,看看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), 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'])
答案 0 :(得分:5)
由于你的问题有点困惑,我会采取以下假设。
(1, 5000, 1)
(slidingWindowSteps, 3, 1000, 1)
(1,3,10)
。 (你的图像是1x10,但你的文字说10x1,我假设图像是正确的)。 (1,3,10)
准备滑动窗口案例
在滑动窗口的情况下,重复数据是不可避免的。您需要先输入您的输入。
采用初始时间序列(1,5000,1)
,我们需要在包含3组1000的样本的批处理中将其拆分。这里我只为X做这个,你必须对Y做类似的事情/ p>
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)
创建模型:
关于您首次添加的图层的一些评论:
input_shape
。这个形状是(groupsInWindow,windowStride,features)
。它应该在最外部的包装器中:TimeDistributed。 return_sequences = False
。 (如果你想要更多图层,你可以在第一阶段使用许多LSTM。在这种情况下,第一阶段可以保留步骤,只有最后一部分需要使用return_sequences=False
)units=10
我将使用功能API来查看摘要中的输入形状,这有助于理解事物。
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_sequences=False
,因此不需要展平或类似的东西。数据已经以(samples, groupsInWindow,intermediateFeatures)
的形式进行了整形。 Dense
图层也不是必需的。但只要最终形状相同,如果你想按照你的方式去做就不会“错”。
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
)在None
中显示为model.summary()
。
(totalSamples,groupsInWindow,windowStride,features)
groupsInWindow
。
这个维度将被保留。 return_sequences=False
的LSTM将消除windowStride
并更改功能(windowStride
,第二个最后一个维度位于此LSTM的时间步长位置):(totalSamples, groupsInWindow, intermadiateFeatures)
groupsInWindow
(倒数第二个)将成为“时间步长”。但return_sequences=True
不会像第一个LSTM那样消除时间步长。结果:(totalSamples, groupsInWindow, arbitraryLSTMUnits)
Dense
图层,因为它正在接收3D输入,会将第二个维度解释为时间分布并保持不变,仅将自身应用于要素维度。结果:(totalSamples, groupsInWindow, n_classes)