Keras-rl DQN报模型多输出不支持错误的解决方法咨询
结论
你的判断完全准确。原生keras-rl的DQN组件从设计层面仅支持单输出模型,默认要求模型输出一维张量对应所有离散动作的Q值,没有内置多输出分支的Q值聚合、动作选择逻辑,传入多输出模型必然触发对应报错。另外你代码里nb_actions=np.array([15,15])的写法本身也不符合参数要求,该参数需要传入整数类型的动作空间总大小,不支持传入维度数组。
可落地的绕过方案
不需要大规模修改框架源码,推荐优先选第一个方案,改动最小、兼容性最好:
- 方案1:追加无参数逻辑层适配单输出要求,保留双分支轻量化结构
你现有的卷积、Dropout、两个15维Dense层的结构完全不需要改动,只需要在两个Dense输出层后追加简单的张量运算,把双分支结果转换成单输出即可,有两种可选的实现逻辑:- 外积映射为全点位Q值(零额外参数、无需改后续逻辑)
两个Dense层分别输出x、y维度的15维Q值后,通过矩阵外积计算每个15×15网格点位的联合Q值,再展平为225维的单输出,和225个独立点位输出的接口完全一致,不需要修改DQN策略、环境交互的任何逻辑,参数量和你原本的双输出模型完全一致。
核心实现代码参考:
调整后初始化DQN时直接设置import tensorflow as tf # 假设dense_x、dense_y是你原本两个15维的输出层 x_expand = tf.expand_dims(dense_x, axis=-1) # 维度调整为(None, 15, 1) y_expand = tf.expand_dims(dense_y, axis=1) # 维度调整为(None, 1, 15) joint_q = tf.matmul(x_expand, y_expand) # 外积得到(None,15,15)的网格Q值图 model_output = tf.keras.layers.Flatten()(joint_q) # 展平为(None,225)单输出nb_actions=225即可正常训练。
2. 拼接输出+自定义动作解析(适合需要独立优化x、y分支损失的场景)
把两个15维输出直接拼接为30维的单输出,设置nb_actions=30,同时重写Boltzmann策略的动作选择逻辑、环境的交互逻辑:拿到30维输出后切分前15维作为x坐标的Q值、后15维作为y坐标的Q值,分别采样得到x、y坐标后组合为最终的网格点位传入环境。 - 外积映射为全点位Q值(零额外参数、无需改后续逻辑)
- 方案2:本地修改keras-rl DQN源码适配多输出
找到本地keras-rl安装路径下的dqn.py文件,重写其中的compute_q_values、forward等涉及输出张量解析的方法,让其支持接收双输出Q值、分别计算动作后再组合。该方案需要改动框架源码,换环境部署时需要重复修改,维护成本高,非特殊需求不推荐使用。
内容的提问来源于stack exchange,提问作者Mercury
相关产品推荐
相关产品推荐

