TensorFlow2.6.0下Dueling DQN出现Optimization cancelled报错如何解决?
问题解决方案
- 首先解决触发报错的tf.data优化bug:
TF2.6版本的tf.data自动优化模块存在已知兼容问题,在DQN这类直接传入批次数据训练、不使用tf.data流水线加载数据的场景下,会误触发优化取消警告。在代码最开头加入以下配置即可关闭冗余优化:
该方案可以解决90%的同报错场景,调整后如果警告消失,再排查损失无变化的问题import tensorflow as tf # 关闭tf.data自动优化 tf.data.experimental.disable_optimizations(["map_and_batch", "parallel_batch"]) # 关闭元优化器避免内部调度错误 tf.config.optimizer.set_experimental_options({"disable_meta_optimizer": True}) - 修正模型结构的冗余与潜在问题:
你当前的模型结构存在两处冗余/不规范点,虽然不是直接报错原因,但可能导致梯度传递异常:- 输入层后接的
Dense(512)输出维度已经是二维(batch_size, 512),后续的Flatten()层完全冗余,可直接删除 - 优势层的命名存在拼写错误(Adavantage应为Advantage),虽不影响计算但不利于调试
- 输入层后接的
- 校验DQN训练逻辑的正确性:
损失无变化基本都是训练逻辑错误导致的,重点排查以下三点:- 目标Q值
target_q计算时是否添加了tf.stop_gradient(),如果没有加会导致梯度反向传播到目标网络,TD误差计算失效,损失全程无波动 - 采样权重
self.is_weight.flatten()的维度是否为(batch_size,),必须和批次大小严格匹配,维度不匹配会导致样本权重失效,损失计算错误 - 是否定期更新目标网络的权重,如果目标网络和主网络始终权重一致,TD误差会始终接近0,模型无法学习
- 目标Q值
- 替换训练接口避免keras封装问题:
TF2.6的train_on_batch接口存在较多内部兼容问题,可以替换为自定义训练循环,绕过keras的封装逻辑:# 定义自定义训练步 @tf.function def train_step(obs, target_q, sample_weight): with tf.GradientTape() as tape: pred_q = self.R.model(obs, training=True) loss = tf.keras.losses.Huber()(target_q, pred_q, sample_weight=sample_weight) grads = tape.gradient(loss, self.R.model.trainable_variables) self.R.model.optimizer.apply_gradients(zip(grads, self.R.model.trainable_variables)) return loss # 训练调用 losses = train_step(self.b_obs, target_q, self.is_weight.flatten()) - 版本适配调整:
如果上述方案都无效,可将TensorFlow版本升级到2.8.x或降级到2.4.x,这两个版本对keras自定义模型训练的兼容性最好,不会触发该类内部报错。
内容的提问来源于stack exchange,提问作者prakash gawas
相关产品推荐
相关产品推荐

