You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenAI Gym复杂Dict观测空间扁平化及DQN实现问题咨询

关于DQN实现中Dict观测空间的问题

问题1:扁平化Dict观测空间的差异原因

你手动计算的513维是把每个Discrete空间当成单个离散值,但gym.spaces.utils.flatten_space默认会对Discrete类型做one-hot编码,而非直接保留离散数值,这是两者差异的核心:

  • elem_1是Discrete(64):扁平化后是64维的one-hot数组(每个离散值对应数组中唯一的1,其余为0)
  • elem_2中的每个子Dict:
    • prop_1(Discrete(100))→100维one-hot
    • prop_2(Discrete(10))→10维one-hot
    • prop_3到prop_8共6个Discrete(4)→每个4维,总计24维
      单个子Dict扁平化长度为100+10+24=134
  • 64个子Dict总长度为64×134=8576,加上elem_1的64,总长度为8640,和你看到的8801接近(可能是Tuple包装的微小差异或近似计算)

如果要得到你预期的513维数组(用离散值本身而非one-hot),需要手动遍历观测字典提取数值并拼接,不要用gym自带的flatten工具。

问题2:观测数组形式与replay函数错误

观测的numpy数组形式

原始观测是嵌套字典+元组结构:elem_1为整数,elem_2是64个字典的元组,每个字典包含8个整数。转换成数组有两种方式:

  1. 用gym的flatten函数:得到one-hot编码的高维数组(长度约8640)
  2. 手动提取离散值:拼接成1+64×8=513维的一维数值数组

replay函数错误原因及解决

你直接将嵌套字典形式的states转成numpy数组,得到的是object类型数组(每个元素是字典),而非数值型数组,这会导致reshape操作完全不匹配,出现“期望3D输入,得到(1,1)数组”的错误。

解决步骤:

  1. 统一预处理观测:在将观测存入replay buffer前,先转换成数值数组:

    def preprocess_observation(obs):
        # 提取elem_1的数值
        elem1 = np.array([obs["elem_1"]])
        # 提取elem_2中所有子字典的属性值
        elem2 = []
        for sub_dict in obs["elem_2"]:
            elem2.extend([
                sub_dict["prop_1"], sub_dict["prop_2"],
                sub_dict["prop_3"], sub_dict["prop_4"],
                sub_dict["prop_5"], sub_dict["prop_6"],
                sub_dict["prop_7"], sub_dict["prop_8"]
            ])
        elem2 = np.array(elem2)
        # 拼接成一维数组
        return np.concatenate([elem1, elem2])
    

    每次从环境获取obs后,调用preprocess_observation(obs)得到513维数组,再存入replay buffer。

  2. 修正replay函数:

    def replay(self, replay_buffer, batch_size, model, target_model):
        if len(replay_buffer) < batch_size:
            return
    
        samples = random.sample(replay_buffer, batch_size) 
        zipped_samples = list(zip(*samples))  
        states, actions, rewards, new_states, dones = zipped_samples  
    
        # 此时states已是(batch_size, 513)的数值数组
        states = np.array(states)
        # 若模型期望3D输入(如(batch_size, 1, 513)),执行reshape
        states = states.reshape((batch_size, 1, 513))
        targets = target_model.predict(states, verbose=0)
    
        new_states = np.array(new_states)
        new_states = new_states.reshape((batch_size, 1, 513))
        q_values = model.predict(new_states, verbose=0)
    
  3. 匹配模型输入:确保你的Sequential模型输入层形状与预处理后的数组一致——如果输入层定义为Input(shape=(1,513)),则reshape正确;如果是Input(shape=(513,)),则无需reshape成3D。

内容的提问来源于stack exchange,提问作者Ai_Nebula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:57:00