TensorFlow三分类模型持续输出相同预测值的问题求助
问题诊断与修复方案
你的模型无法完成三分类任务的核心问题是从标签定义到模型架构都按二分类逻辑设计,再加上预处理和预测环节的错误,导致输出异常。以下是具体问题和修复步骤:
1. 标签定义错误:三分类被改成二分类
你给正常胸部X光片和病毒性肺炎都标记了0,仅给COVID样本标记1,这直接把三类任务合并成了「COVID vs 非COVID」的二分类任务,模型根本没有学习三分类的目标。
修正:
给三类分配唯一标签:
# 加载数据时修改标签映射 covidImages, covidTargets = loadImages(covid_path, covidUrl, 0) # COVID肺炎 → 0 normalImages, normalTargets = loadImages(normal_path, normal_urls, 1) # 正常 →1 viralImages, viralTargets = loadImages(viral_path, viral_urls, 2) # 病毒性肺炎 →2
2. 模型输出层与激活函数不匹配三分类需求
当前输出层是Dense(1, activation='sigmoid'),这是二分类的标准配置。三分类需要输出3个神经元,搭配softmax激活函数来输出各类别的概率分布:
修正模型架构:
model = Sequential([ Conv2D(32, 3, input_shape=(100,100,3), activation='relu'), MaxPooling2D(), Conv2D(16, 3, activation='relu'), MaxPooling2D(), Conv2D(16, 3, activation='relu'), MaxPooling2D(), Flatten(), Dense(512, activation='relu'), Dense(256, activation='relu'), Dense(3, activation='softmax') # 三分类改为3个神经元+softmax激活 ])
3. 损失函数选择错误
BinaryCrossentropy是二分类专用损失,三分类需要使用SparseCategoricalCrossentropy(适配整数形式的标签,无需做one-hot编码):
修正编译代码:
model.compile( optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=['accuracy'] )
4. 预测环节的两个关键错误
(1)输入图像未做归一化
训练时你对图像执行了img = img / 255.0的归一化,但预测时加载的图像直接传入模型,没有同步预处理,导致输入数据分布不一致。
(2)错误叠加tf.nn.softmax
当前模型输出已经是softmax的概率结果,不需要再额外调用tf.nn.softmax处理。
修正预测代码:
img = tf.keras.utils.load_img(testimage, target_size=(100, 100)) img_array = tf.keras.utils.img_to_array(img) img_array = img_array / 255.0 # 同步训练时的归一化操作 img_array = tf.expand_dims(img_array, 0) predictions = model.predict(img_array) # 获取概率最高的类别索引 predicted_class = np.argmax(predictions[0]) # 定义类别名称映射 class_names = ['COVID肺炎', '正常', '病毒性肺炎'] print(f"预测类别:{class_names[predicted_class]}") print(f"各类别概率:{predictions[0]}")
5. 可选优化:处理数据不均衡问题
先检查三类样本的数量差异:
print(f"COVID样本数:{len(covidUrl)}") print(f"正常样本数:{len(normal_urls)}") print(f"病毒性肺炎样本数:{len(viral_urls)}")
如果样本数量差距较大,会导致模型偏向样本多的类别,可通过设置class_weight来平衡:
# 假设统计后各类别样本数为covid_count、normal_count、viral_count total = covid_count + normal_count + viral_count class_weight = { 0: total / covid_count, 1: total / normal_count, 2: total / viral_count } # 训练时传入class_weight model.fit(x_train, y_train, batch_size=32, epochs=15, validation_data=(x_test, y_test), class_weight=class_weight)
按照以上步骤修改后,模型就能正确执行三分类任务。
内容的提问来源于stack exchange,提问作者Alex Amir
相关产品推荐
相关产品推荐

