Keras-tuner二分类报错logits和labels形状不匹配((None,2)vs(None,1))
错误根因
- 直接触发报错的原因是输出层配置与标签形状、损失函数不匹配:当前二分类任务的标签
y_train/y_test形状为(None, 1)(单列表征0/1类别),但定义的输出层是Dense(2, activation='sigmoid'),输出形状为(None, 2),而binary_crossentropy损失要求预测输出和真实标签形状完全一致,因此触发形状不匹配错误。 - 代码还存在两个隐藏问题:
- 控制隐藏层堆叠数量的超参数被错误命名为
input_shape,语义完全不符,后续调参很容易出现配置混淆 - 堆叠的第一层Dense层没有指定输入特征维度,模型无法正确推断输入形状,修正当前形状错误后也大概率会触发输入形状相关报错。
- 控制隐藏层堆叠数量的超参数被错误命名为
修复方案
优先选择普通二分类的标准配置(适配当前(None,1)形状的标签,无需修改标签格式),修正后完整代码如下:
def build_model(hp): model = keras.Sequential() # 重命名层数超参数保证语义匹配,第一层显式指定输入特征维度 hidden_layer_count = hp.Int('hidden_layers_num', 2, 20) for i in range(hidden_layer_count): dense_config = { "units": hp.Int(f'units_{i}', min_value=32, max_value=512, step=32), "activation": 'relu' } # 第一层传入输入形状,填入训练集的特征数量 if i == 0: dense_config["input_shape"] = (X_train.shape[1],) model.add(layers.Dense(**dense_config)) # 输出层改为单神经元+sigmoid,输出形状(None,1)与标签匹配 model.add(layers.Dense(1, activation='sigmoid')) model.compile( optimizer=keras.optimizers.Adam( hp.Choice('learning_rate', [1e-2, 1e-3, 1e-4])), loss='binary_crossentropy', metrics=['accuracy']) return model tuner.search(X_train, y_train, epochs=5, validation_data=(X_test, y_test))
如果需要保留2个神经元的输出配置(普通二分类场景不推荐),需要同步修改对应配置:
- 将输出层激活函数改为
softmax,损失函数替换为sparse_categorical_crossentropy,可保持现有(None,1)形状的标签不变 - 如果坚持用
sigmoid激活+2神经元输出,属于多标签分类配置,需要将标签转换为(None,2)形状的one-hot编码,才能匹配binary_crossentropy的输入要求。
内容的提问来源于stack exchange,提问作者Sahil Bhatti
相关产品推荐
相关产品推荐

