经过大量的阅读和图表,我想我已经提出了一个模型,我可以用它作为更多测试我需要调整哪些参数和功能的基础.但是,我对如何实现以下测试用例感到困惑(所有数字都比最终模型小几个数量级,但我想从小开始):
这是我提出的,编译的.但是,看看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'])
Run Code Online (Sandbox Code Playgroud)
由于您的问题有点困惑,我将采取以下假设.
(1, 5000, 1)
(slidingWindowSteps, 3, 1000, 1)
(1,3,10)
.(你的图像是1x10,但你的文字说10x1,我假设图像是正确的).(1,3,10)
准备滑动窗框:
在滑动窗口的情况下,重复数据是不可避免的.您需要先输入您的输入.
以初始时间序列为例(1,5000,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)
Run Code Online (Sandbox Code Playgroud)
创建模型:
关于您第一次添加的图层的一些评论:
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)
Run Code Online (Sandbox Code Playgroud)
此时,您已经消除了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)
Run Code Online (Sandbox Code Playgroud)
如果您要丢弃边框,可以添加此图层:
out = Lambda(lambda x: x[:,1,:])(out) #model.add(Lambda(lambda x: x[:,1,:]))
Run Code Online (Sandbox Code Playgroud)
完成模型:
model = Model(inputTensor,out)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
Run Code Online (Sandbox Code Playgroud)
以下是尺寸如何流经此模型.我放在这里的第一个维度(totalSamples
)显示None
在model.summary()
.
(totalSamples,groupsInWindow,windowStride,features)
groupsInWindow
.这个维度将被保留. return_sequences=False
将消除windowStride
并更改特征(windowStride
,第二个最后一个维度,位于此LSTM的时间步长位置):(totalSamples, groupsInWindow, intermadiateFeatures)
groupsInWindow
(倒数第二个)将是"时间步长".但return_sequences=True
不会像第一个LSTM那样消除时间步骤.结果:(totalSamples, groupsInWindow, arbitraryLSTMUnits)
Dense
一层,因为它正在接收3D输入,将把第二个维度解释为它是一个TimeDistributed并保持不变,仅将自身应用于要素维度.结果:(totalSamples, groupsInWindow, n_classes)
归档时间: |
|
查看次数: |
2670 次 |
最近记录: |