Keras模型训练报错:dense层输入维度不兼容求助
问题描述
尝试用Keras和TensorFlow拟合概率分布时出现维度不兼容错误,相关代码及报错信息如下:
模型构建代码
def build_env_model(learning_rate): InputLayer = Input(shape=(5,)) Layer_1 = Dense(16,activation='tanh')(InputLayer) Layer_2 = Dense(16,activation='tanh')(Layer_1) position_mean = Dense(1, activation="linear")(Layer_2) position_sigma = Dense(1, activation=lambda x: tf.nn.elu(x) + 1)(Layer_2) velocity_mean = Dense(1, activation="linear")(Layer_2) velocity_sigma = Dense(1, activation=lambda x: tf.nn.elu(x) + 1)(Layer_2) angle_mean = Dense(1, activation="linear")(Layer_2) angle_sigma = Dense(1, activation=lambda x: tf.nn.elu(x) + 1)(Layer_2) angular_velocity_mean = Dense(1, activation="linear")(Layer_2) angular_velocity_sigma = Dense(1, activation=lambda x: tf.nn.elu(x) + 1)(Layer_2) reward_mean = Dense(1, activation=lambda x: tf.nn.elu(x) + 1)(Layer_2) reward_sigma = Dense(1, activation=lambda x: tf.nn.elu(x) + 1)(Layer_2) y_real = Input(shape=(5,)) lossF = cost(position_mean,position_sigma,velocity_mean,velocity_sigma,angle_mean,angle_sigma,angular_velocity_mean,angular_velocity_sigma,reward_mean,reward_sigma,y_real) model = Model(inputs=[InputLayer,y_real],outputs=[position_mean,position_sigma,velocity_mean,velocity_sigma,angle_mean, angle_sigma,angular_velocity_mean,angular_velocity_sigma,reward_mean,reward_sigma]) model.add_loss(lossF) adamOptimizer = adam_v2.Adam(learning_rate=learning_rate) model.compile(optimizer=adamOptimizer,metrics=['mse']) return model
模型训练代码
def update_env_model(self,state,action,reward,next_state,done): state = state[0] next_state = next_state[0] position,velocity,angle,angular_velocity = state ns_position,ns_velocity,ns_angle,ns_angular_velocity = next_state inp1 = np.array([position,velocity,angle,angular_velocity,action]) inp2 = np.array([ns_position,ns_velocity,ns_angle,ns_angular_velocity,reward]) self.env_model.fit([inp1,inp2],verbose=0)
报错信息
ValueError: in user code: File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1051, in train_function * return step_function(self, iterator) File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1040, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1030, in run_step ** outputs = model.train_step(data) File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 889, in train_step y_pred = self(x, training=True) File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler raise e.with_traceback(filtered_tb) from None File "/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py", line 228, in assert_input_compatibility raise ValueError(f'Input {input_index} of layer "{layer_name}" ' ValueError: Exception encountered when calling layer "model_1" (type Functional). Input 0 of layer "dense_16" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (None,) Call arguments received by layer "model_1" (type Functional): • inputs=('tf.Tensor(shape=(None,), dtype=float32)', 'tf.Tensor(shape=(None,), dtype=float32)') • training=True • mask=None
解决方案
报错核心是模型要求输入为2维(批量维度+特征维度),但训练时传入的是1维数组。Keras的Dense层需要输入至少是2维(形如(batch_size, feature_size)),而当前inp1和inp2是1维的(5,),传入后会被识别为(None,),不满足层的输入要求。
修改训练代码,给输入增加批量维度,有两种实现方式:
方式1:用np.expand_dims追加维度
def update_env_model(self,state,action,reward,next_state,done): state = state[0] next_state = next_state[0] position,velocity,angle,angular_velocity = state ns_position,ns_velocity,ns_angle,ns_angular_velocity = next_state inp1 = np.array([position,velocity,angle,angular_velocity,action]) inp2 = np.array([ns_position,ns_velocity,ns_angle,ns_angular_velocity,reward]) # 增加批量维度,将形状从(5,)变为(1,5) inp1 = np.expand_dims(inp1, axis=0) inp2 = np.expand_dims(inp2, axis=0) self.env_model.fit([inp1,inp2],verbose=0)
方式2:直接创建2维数组
def update_env_model(self,state,action,reward,next_state,done): state = state[0] next_state = next_state[0] position,velocity,angle,angular_velocity = state ns_position,ns_velocity,ns_angle,ns_angular_velocity = next_state # 用双层列表直接生成(1,5)的2维数组 inp1 = np.array([[position,velocity,angle,angular_velocity,action]]) inp2 = np.array([[ns_position,ns_velocity,ns_angle,ns_angular_velocity,reward]]) self.env_model.fit([inp1,inp2],verbose=0)
后续如果要处理批量数据,只需将多个样本堆叠成(batch_size,5)的形状传入即可,无需修改模型结构。
内容的提问来源于stack exchange,提问作者Tanmay Aeron
相关产品推荐
相关产品推荐

