python - 带有 TimeSeriesGenerator 的 Keras LSTM 自定义数据生成器
问题描述
所以我正在尝试使用 Keras 的fit_generator和自定义数据生成器来输入 LSTM 网络。
什么有效
为了说明这个问题,我创建了一个玩具示例,试图以简单的升序预测下一个数字,并使用Keras TimeseriesGenerator创建一个 Sequence 实例:
WINDOW_LENGTH = 4
data = np.arange(0,100).reshape(-1,1)
data_gen = TimeseriesGenerator(data, data, length=WINDOW_LENGTH,
sampling_rate=1, batch_size=1)
我使用一个简单的 LSTM 网络:
data_dim = 1
input1 = Input(shape=(WINDOW_LENGTH, data_dim))
lstm1 = LSTM(100)(input1)
hidden = Dense(20, activation='relu')(lstm1)
output = Dense(data_dim, activation='linear')(hidden)
model = Model(inputs=input1, outputs=output)
model.compile(loss='mse', optimizer='rmsprop', metrics=['accuracy'])
并使用以下fit_generator
功能对其进行训练:
model.fit_generator(generator=data_gen,
steps_per_epoch=32,
epochs=10)
这可以完美地训练,并且模型会按预期进行预测。
问题
现在的问题是,在我的非玩具情况下,我想在将数据输入fit_generator
. 作为实现这一目标的一步,我创建了一个生成器函数,它只包装了之前使用的 TimeseriesGenerator。
def get_generator(data, targets, window_length = 5, batch_size = 32):
while True:
data_gen = TimeseriesGenerator(data, targets, length=window_length,
sampling_rate=1, batch_size=batch_size)
for i in range(len(data_gen)):
x, y = data_gen[i]
yield x, y
data_gen_custom = get_generator(data, data,
window_length=WINDOW_LENGTH, batch_size=1)
但现在奇怪的是,当我像以前一样训练模型,但是使用这个生成器作为输入时,
model.fit_generator(generator=data_gen_custom,
steps_per_epoch=32,
epochs=10)
没有错误,但训练错误到处都是(上下跳跃而不是像其他方法那样持续下降),并且模型没有学会做出良好的预测。
任何想法我的自定义生成器方法做错了什么?
解决方案
这可能是因为对象类型从Sequence
aTimeseriesGenerator
变成了泛型生成器。该fit_generator
函数以不同的方式处理这些。一个更干净的解决方案是继承类并覆盖处理位:
class CustomGen(TimeseriesGenerator):
def __getitem__(self, idx):
x, y = super()[idx]
# do processing here
return x, y
并且像以前一样使用这个类,因为其余的内部逻辑将保持不变。
推荐阅读
- java - 在android studio中更改按钮文本并执行相应的onClick功能
- c - 复杂铸造
- javascript - Google 日历 - 接受/拒绝选项
- google-app-engine - NDB 查询挂起一组条件
- html - 为什么我的段落元素显示在背景色后面
- html - 表格中水平和垂直边框之间的空间被忽略
- git - 在 GitHub 组织内创建一个文件夹
- swift - Swift Alamofire 发布“通话中的额外参数”
- firebase - 在 LiveData-returning 函数中删除 Firestore 快照侦听器
- spring - 如何使用来自另一个对象的数据创建休眠查询?