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

使用Keras Functional API训练OpenAI LunarLander-v2模型时遭遇输入形状不兼容ValueError

解决LunarLander-v2中Functional模型的张量形状不兼容问题

看起来你遇到的核心问题是数据在记忆存储和提取环节出现了错位,再加上一些小的代码错误,导致输入模型的张量形状完全不符合预期。我们一步步来拆解修复:

1. 最致命的错误:记忆存储时混入了多余的self

看你的addToMemory方法:

def addToMemory(self, state, action, reward, next_state, done):
    self.memory.append((self, state, action, reward, next_state, done))

你把self(Agent实例)作为元组的第一个元素加入了记忆队列!这直接导致后面extractFromSample的时候:

  • states = np.array([i[0] for i in sample]) 实际取到的是一堆Agent对象,而不是环境状态
  • 真正的state被存在了i[1],next_state在i[4],done在i[5],完全错位了

修正这个方法,去掉多余的self:

def addToMemory(self, state, action, reward, next_state, done):
    self.memory.append((state, action, reward, next_state, done))

2. 记忆采样函数的错误

你的sampleFromMemory用了np.random.sample,这个函数是用来生成[0,1)之间的随机浮点数,不是从序列里采样样本。应该用random.sample(Python标准库)来抽取记忆样本:

def sampleFromMemory(self):
    # 使用random.sample从记忆中抽取指定数量的样本
    sample = random.sample(self.memory, self.config.batch_size)
    return sample

记得在文件顶部导入import random。

3. 修正样本提取的索引与形状处理

因为上面修正了addToMemory的元组顺序,现在extractFromSample的索引需要对应正确的位置,同时注意squeeze的使用场景:

def extractFromSample(self, sample):
    states = np.array([i[0] for i in sample])
    actions = np.array([i[1] for i in sample])
    rewards = np.array([i[2] for i in sample])
    next_states = np.array([i[3] for i in sample])
    done_list = np.array([i[4] for i in sample])
    
    # 只有当state本身是(1,8)形状时才需要squeeze,如果是(8,)则不需要
    # 堆叠后的states默认是(batch_size,8),正好匹配模型输入要求
    # states = np.squeeze(states)
    # next_states = np.squeeze(next_states)
    return states, actions, rewards, next_states, done_list

4. 策略动作生成时的输入形状处理

在policyAct方法中,环境返回的state通常是一维数组((8,)),而Keras模型期望输入是批量数据(形状为(batch_size, 8)),所以需要给state增加一个维度:

def policyAct(self, state):
    # 给state增加batch维度,从(8,)变成(1,8)
    state = np.expand_dims(state, axis=0)
    predicted_actions = self.model.predict(state, verbose=0)
    return np.argmax(predicted_actions[0])

加上verbose=0可以避免每次predict都打印日志,训练过程更清爽。

5. 验证模型输入输出形状

你的Functional模型定义是正确的,输入(None,8)对应批量的8维状态,输出(None,4)对应每个状态的4个动作值(LunarLander-v2的动作空间是4)。修正上面的问题后,输入模型的states和next_states应该都是(batch_size,8),和模型期望的形状完全匹配。

把这些修正点全部应用后,你的Functional模型应该就能和Sequential模型一样正常运行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:07:46