Keras二分类训练报logits与labels形状不匹配问题咨询
故障背景
我已检索过同类问题,但相关问题下的已采纳解决方案均无法解决我遇到的故障。
以下是编写二分类器的完整代码:
from google.colab import drive drive.mount('/content/drive') df = pd.read_csv('/content/drive/My Drive/dielectron.csv') df = df.drop('Run', axis=1); df = df.drop('M', axis=1) df.info() df.head() scaler = MinMaxScaler() index = df.index.to_list() columns = df.columns.tolist() scaler = MinMaxScaler() df_scaled = scaler.fit_transform(df) Df = pd.DataFrame(df_scaled , index=index , columns=columns) Df.info() Df= Df.drop('Event', axis=1) x = Df.drop('Q2', axis=1).to_numpy() y = Df['Q2'] y = np.asarray(y).astype('float32').reshape((-1,1)) model = tf.keras.Sequential([ tf.keras.layers.Dense(16, activation='relu'), tf.keras.layers.Dense(16, activation='relu'), tf.keras.layers.Dense(16, activation='sigmoid') ]) epochs = 20 es = tf.keras.callbacks.EarlyStopping(monitor='val loss', patience = 3, mode = 'min', restore_best_weights=True) model.compile(loss= tf.keras.losses.BinaryCrossentropy(), optimizer= tf.optimizers.Adam(), metrics= [tf.keras.metrics.BinaryAccuracy()] ) history = model.fit(x, y, epochs=epochs, validation_split=0.3, callbacks=[es])
传入model.fit()的张量形状查询结果:
x.shape:(100000, 15) y.shape:(100000, 1)
运行代码触发的报错核心信息:
ValueError: `logits` and `labels` must have the same shape, received ((None, 16) vs (None, 1)).
注:本人接触机器学习、深度学习与TensorFlow Keras时间较短,不排除代码存在低级错误。本次使用的为CERN电子碰撞公开数据集,同时需要明确logit的准确定义,此前查阅的资料解释存在冲突。
故障原因
- 核心错误:二分类任务的输出层维度设置错误。标签y是单维度(每个样本对应一个0/1分类值),但模型最后一层设置了16个神经元,输出形状为
(None,16),和标签的(None,1)形状不匹配,计算二元交叉熵损失时无法对齐维度直接报错。 - 次要错误:早停回调的监控参数名书写错误,Keras中验证集损失的参数名为
val_loss,代码中写的val loss带空格,会导致早停机制无法找到对应监控值。 - 隐含错误:代码缺少必要的依赖导入,直接运行会触发
NameError。
修复方法
按以下步骤修改代码即可正常运行:
- 在代码最开头补充缺失的依赖导入:
import pandas as pd import numpy as np import tensorflow as tf from sklearn.preprocessing import MinMaxScaler - 修改模型最后一层的神经元数量为1,匹配二分类单输出的要求:
model = tf.keras.Sequential([ tf.keras.layers.Dense(16, activation='relu'), tf.keras.layers.Dense(16, activation='relu'), tf.keras.layers.Dense(1, activation='sigmoid') # 原代码此处为16,改为1 ]) - 修正早停回调的监控参数名,补全下划线:
es = tf.keras.callbacks.EarlyStopping(monitor='val_loss', # 原代码此处为val loss,补上下划线 patience = 3, mode = 'min', restore_best_weights=True)
logit 定义说明
logit是神经网络输出层未经过激活函数转换的原始输出值,值域为全体实数,没有被映射到概率区间。
以二分类场景为例:
- 如果最后一层写
Dense(1)(不指定激活函数),这一层直接输出的原始值就是logit; - 如果写
Dense(1, activation='sigmoid'),框架会先输出1维logit,再经过sigmoid函数把值压缩到0~1区间,输出最终的分类概率。
本次报错信息中提到的logits,就是模型最后一层输出的原始计算结果,因为最后一层设了16个神经元,所以输出16维logit,和1维的标签形状无法匹配,才触发了维度错误。
内容的提问来源于stack exchange,提问作者python newbie
相关产品推荐
相关产品推荐

