Keras中自定义生成器包裹TimeSeriesGenerator后LSTM训练异常
问题根源:自定义生成器重复创建TimeseriesGenerator实例
你的自定义生成器写法有个关键问题——在while True循环内部每次都重新实例化TimeseriesGenerator,这会导致模型每次训练的批次数据都在重复从头开始,根本无法遍历完整的数据集进行有效学习。
具体分析
原来的TimeseriesGenerator是Keras的Sequence子类,它会按滑动窗口的顺序生成批次数据,比如你的示例中,第一个批次是[0,1,2,3]→4,第二个是[1,2,3,4]→5,以此类推。但你的自定义生成器每次进入while True循环都会重新创建一个新的TimeseriesGenerator实例,然后从第0个批次开始遍历。当你设置steps_per_epoch=32时,每个epoch模型都在反复训练相同的前32个批次(窗口0-3到窗口31-34),完全接触不到后续的序列数据。这种重复训练小部分样本的情况,会导致模型学习不稳定,损失自然会大幅波动,甚至无法收敛到正确的规律。
修正后的自定义生成器
把TimeseriesGenerator的实例化移到while True循环外面,这样生成器会持续遍历同一个实例的所有批次,不会每次都从头开始:
def get_generator(data, targets, window_length = 5, batch_size = 32): # 只实例化一次TimeseriesGenerator data_gen = TimeseriesGenerator(data, targets, length=window_length, sampling_rate=1, batch_size=batch_size) while True: for i in range(len(data_gen)): x, y = data_gen[i] # 在这里添加你的数据处理逻辑(比如归一化、特征工程等) yield x, y
额外注意事项
- 如果你需要在每个epoch后打乱数据,可以在
while True循环内每次遍历完所有批次后,对原始数据进行同步打乱(输入和目标要对应),然后重新创建TimeseriesGenerator——但这只适用于非强时序依赖的场景,你的升序序列示例不需要打乱。 - 建议将
steps_per_epoch的值设置为len(data_gen),这样每个epoch能遍历完整的数据集,避免遗漏或重复训练部分样本。
内容的提问来源于stack exchange,提问作者JunShern Chan
相关产品推荐
相关产品推荐

