联合回归与分类模型训练报错:TypeError: NoneType对象不可调用
问题排查与解决方案
核心错误原因
- Sequential模型不支持多输出任务:Sequential是线性层堆叠结构,仅能保留一个输出分支。你在最后添加两个Dense层(分类+回归),会导致模型输出结构混乱,触发底层调用错误。
- 分类损失函数不匹配:使用
categorical_crossentropy但标签是整数格式(0/1,shape为(2860,1)),该损失要求标签为one-hot编码,此处应改用sparse_categorical_crossentropy。 - Conv2D重复定义input_shape:Reshape层已处理输入维度,后续Conv2D无需再指定
input_shape,多余定义会干扰模型输入维度判断。
修正后的代码(改用Functional API)
import tensorflow as tf from tensorflow.keras import layers, Model data_shape = (75, 2) # 输入层 inputs = layers.Input(shape=data_shape) # Reshape为4D张量适配Conv2D x = layers.Reshape(data_shape + (1,))(inputs) # 卷积块 x = layers.Conv2D(16, kernel_size=(2, 1), activation='relu')(x) x = layers.BatchNormalization()(x) x = layers.Conv2D(32, kernel_size=(2, 1), activation='relu')(x) x = layers.BatchNormalization()(x) x = layers.Conv2D(64, kernel_size=(2, 1), activation='relu')(x) x = layers.BatchNormalization()(x) # 扁平化 x = layers.Flatten()(x) # 全连接块 x = layers.Dense(64, activation='relu')(x) x = layers.BatchNormalization()(x) x = layers.Dense(32, activation='relu')(x) x = layers.BatchNormalization()(x) # 两个输出分支 output_cls = layers.Dense(2, activation='softmax', name='classification')(x) output_reg = layers.Dense(1, activation='linear', name='regression')(x) # 构建多输出模型 model = Model(inputs=inputs, outputs=[output_cls, output_reg]) # 编译:指定每个输出对应的损失和指标 model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss={ 'classification': 'sparse_categorical_crossentropy', 'regression': 'mean_squared_error' }, metrics={ 'classification': 'accuracy', 'regression': 'mae' } ) # 训练:支持列表或字典传递标签 model.fit( x=train_x, y=[train_y_cls, train_y_reg], validation_data=(val_in, [val_out_cls, val_out_reg]), batch_size=32, epochs=30 )
额外优化建议
- 数据类型转换:TensorFlow对float32支持更高效,可将数值型数据转为float32(分类标签保留int32即可):
train_x = train_x.astype('float32') val_in = val_in.astype('float32') train_y_reg = train_y_reg.astype('float32') val_out_reg = val_out_reg.astype('float32') - 输出分支命名:给输出层命名后,用字典传递损失/标签可避免顺序错误,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Pradyumna TK
相关产品推荐
相关产品推荐

