使用Keras训练避障虚拟小车时遭遇张量维度不匹配错误
首先,先把你遇到的问题和代码整理出来:
错误信息:两个形状的第1维度必须相等,但当前为128和164,形状分别为[8,128]和[8,164]。
你的相关代码:
from flat_game import carmunk import numpy as np from nn import neural_net NUM_SENSORS = 8 def play(model): car_distance = 0 game_state = carmunk.GameState(display_hidden=False) # Do nothing to get initial. _, state = game_state.frame_step((2)) # Move. while True: car_distance += 1 # Choose action. action = (np.argmax(model.predict(state, batch_size=1))) # Take action. _, state = game_state.frame_step(action) # 原代码此处截断
问题根源分析
这个错误本质是数据维度和模型的输入/输出维度不匹配。从错误里的形状[8,128]和[8,164]来看:
- 第一个
8是批量大小(batch size),第二个数字是特征/输出的维度数 - 你的模型期望处理的维度是128,但实际传入的数据维度是164,或者反过来,导致计算时无法对齐。结合你代码里
model.predict(state)的调用,大概率是输入的state特征数和模型输入层的定义不一致。
具体修复步骤
检查模型输入层的定义
打开nn.py里的neural_net函数,确认输入层的形状是否和你定义的NUM_SENSORS=8一致?比如如果输入层写的是Input(shape=(128,)),但实际state是8维或者164维,就会触发这个错误。务必让输入层的形状和state的特征数完全匹配。确认
state的实际维度
在代码里加一行打印,看看frame_step返回的state到底是几维:_, state = game_state.frame_step((2)) print("初始state形状:", state.shape) # 添加这行调试运行后如果输出是
(8,),那模型输入层应该设为(8,);如果是(164,),你要么修改模型输入层为164,要么调整carmunk.GameState里生成state的逻辑,让它返回8维特征(对应你设定的NUM_SENSORS)。处理批量维度的问题
Keras的predict方法默认需要批量输入(形状为(batch_size, features))。如果你的state是一维数组(比如(8,)),需要先扩展维度变成(1,8),这样模型才能正确识别:# 修改predict的调用方式 action = np.argmax(model.predict(np.expand_dims(state, axis=0), batch_size=1))验证输出层与动作空间匹配
另外要确保模型输出层的神经元数量和你的小车动作数量一致。比如如果小车有3种动作(前进、左转、右转),输出层应该是Dense(3, activation='softmax'),这样np.argmax才能正确拿到对应的动作索引。
内容的提问来源于stack exchange,提问作者Kevin Tieu

