QNetwork构建输出形状异常:(50,50,7500)而非(7500,)求助
DQN QNetwork输出形状异常问题解决方案
问题根源
你的输入观测张量形状为(50,50,7500),而Dense层默认仅对输入的最后一个维度进行线性变换,不会改变前面的空间维度(此处为50,50)。因此经过多层Dense后,输出依然保留(50,50)的空间维度,最后一维被转换为7500,导致最终输出形状为(50,50,7500),而非预期的(7500,)。
解决方案
核心思路是先消除输入中的空间维度,将3维张量转换为1维特征向量,再通过全连接层输出对应7500个动作的Q值。以下两种方法任选其一:
方法1:使用Flatten层展平所有维度
直接将(50,50,7500)展平为一维向量(50*50*7500,),再接入后续全连接层:
def _build_q_network(self): # 添加展平层,消除空间维度 flatten_layer = tf.keras.layers.Flatten() dense_layers = [flatten_layer] + [self.dense_layer(num_units) for num_units in [64,64]] q_values_layer = tf.keras.layers.Dense( 7500, activation=None, kernel_initializer=tf.keras.initializers.RandomUniform( minval=-0.03, maxval=0.03), bias_initializer=tf.keras.initializers.Constant(-0.2)) q_net = sequential.Sequential(dense_layers + [q_values_layer]) return q_net
方法2:使用全局池化层压缩空间维度(适合带空间结构的输入)
如果50x50是具有实际空间意义的维度(如图像类输入),可以用全局池化层对每个通道的空间特征取平均,得到(7500,)的特征向量:
def _build_q_network(self): # 全局平均池化,压缩50x50空间维度为1 pooling_layer = tf.keras.layers.GlobalAveragePooling2D() dense_layers = [pooling_layer] + [self.dense_layer(num_units) for num_units in [64,64]] q_values_layer = tf.keras.layers.Dense( 7500, activation=None, kernel_initializer=tf.keras.initializers.RandomUniform( minval=-0.03, maxval=0.03), bias_initializer=tf.keras.initializers.Constant(-0.2)) q_net = sequential.Sequential(dense_layers + [q_values_layer]) return q_net
验证效果
修改后重新运行compute_output_signature,输出形状将变为TensorSpec(shape=(7500,), dtype=tf.float32, name=None),符合DQN对单状态对应多动作Q值的输出要求。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

