
在 tensorflow 中实现 q-learning 时,若在训练循环中反复构建或保存模型却未清理计算图状态,会导致内存泄漏与计算图持续膨胀,从而引发逐轮显著变慢;调用 `tf.keras.backend.clear_session()` 可有效释放全局状态、重置默认图并防止性能退化。
在基于 TensorFlow 的深度 Q 网络(DQN)或简化 Q-learning 实现中,一个常见但容易被忽视的性能陷阱是:在多 episode 循环中频繁创建、训练和保存 Keras 模型,却未主动清理 TensorFlow 的全局会话状态。虽然你的代码中没有显式重复构建模型(self.model = self.build_model() 仅在 __init__ 中执行),但每次调用 model.save(...)(尤其是 HDF5 格式 .h5)会隐式依赖当前计算图上下文;若训练循环长期运行且涉及环境重置、模型保存、甚至潜在的梯度计算复用,Keras 默认会不断累积图节点、变量作用域和回调状态——尤其在较旧版本 TensorFlow(如 2.8 之前)或混合使用 Eager / Graph 模式时更为明显。
根本原因在于 tf.keras.backend 维护了一个全局的计算图与资源管理器(如 default_graph、_GRAPH_LEAK_WARNING_THRESHOLD 监控对象等)。当连续多轮训练不重启会话时,这些未释放的中间张量、临时变量、优化器状态残留,将导致:
- 内存占用线性增长;
- model.train_step() 或 tf.GradientTape 执行延迟升高;
- model.save() 耗时随 episode 增加而显著上升(尤其 .h5 格式需序列化完整图结构)。
✅ 推荐修复方案:在每轮 episode 结束、模型保存后,立即调用
import tensorflow as tf
# ... 在 episode 循环内,save_model 之后添加:
env.left_ball.q_agent.save_model("left_trained_agent.h5")
tf.keras.backend.clear_session() # ← 关键修复行⚠️ 注意事项:
- clear_session() 会销毁当前默认图、释放所有模型权重内存,并重置全局随机种子状态。因此它必须在模型已成功保存之后调用,否则后续训练将因图丢失而报错;
- 若你在单个 episode 中多次调用 build_model()(例如动态调整网络结构),更应确保每次 clear_session() 后重建模型;
- 对于 TensorFlow 2.10+ 用户,若启用 tf.function 编译训练步骤,建议同时检查是否误将 @tf.function 装饰器置于循环内部(导致函数反复追踪生成新图),此时 clear_session() 仍有效,但更优解是将 @tf.function 移至方法级并复用;
- 替代方案(进阶):使用 tf.saved_model.save() 替代 .h5 保存,配合 tf.keras.models.load_model() 按需加载,可减少图序列化开销;但 clear_session() 仍是轻量级训练循环中最直接可靠的兜底措施。
? 总结:Q-learning 训练缓慢往往并非算法或超参问题,而是框架层面的状态管理疏漏。一句 tf.keras.backend.clear_session() 即可切断历史图依赖、重置内存足迹,让每一轮 episode 回归“干净起点”——这是 TensorFlow 强化学习实践中值得写入模板的黄金习惯。










