You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras多输出人脸属性预测模型输出负概率、概率和不为1问题求助

问题原因
  • 你编译模型时设置了SparseCategoricalCrossentropy(from_logits=True),这个参数表示模型输出层不需要加softmax激活,直接输出未归一化的logits值,所以predict得到的结果本身就不是概率,自然不满足总和为1、非负的要求。
  • 模型结构不匹配输入数据:输入是48*48的二维人脸图像,你使用了一维卷积Conv1D做特征提取,完全无法正确提取图像的二维空间特征,导致模型训练效果极差、每次重新初始化参数后结果波动很大。
  • 卷积层输出没有做拉平处理就直接接全连接层,存在维度不匹配问题,进一步干扰模型训练。
修正方案

方案1:直接转换现有输出为概率

如果你不需要修改已训练的模型,只需对输出的logits做softmax转换,即可得到符合要求的归一化概率:

import tensorflow as tf
# 转换性别输出为概率
gender_prob = tf.nn.softmax(predictions[0]).numpy()
# 转换族裔输出为概率
ethnicity_prob = tf.nn.softmax(predictions[1]).numpy()

转换后两类输出的概率和均为1,取值范围在0-1之间。

方案2:修正模型结构,直接输出概率

如果要从模型结构层面解决问题,同时提升训练稳定性,修改代码如下:

# 输入层增加灰度图通道维度,适配二维卷积要求
input_layer = keras.Input(shape=(48,48,1),name='img')
# 替换为二维卷积提取图像特征
x = keras.layers.Conv2D(128, kernel_size=3, activation='relu')(input_layer)
x = keras.layers.MaxPooling2D(pool_size=2)(x)
# 拉平卷积输出为一维张量适配全连接层
x = keras.layers.Flatten()(x)
# 性别输出分支添加softmax激活,直接输出概率
y1_output = keras.layers.Dense(units=2, activation='softmax', name='genderoutput')(x)
# 族裔输出分支
x_eth = keras.layers.Dense(units=64, activation='relu')(x)
y2_output = keras.layers.Dense(units=5, activation='softmax', name='ethnicityoutput')(x_eth)

model = keras.Model(inputs=input_layer, outputs=[y1_output, y2_output])
# 输出层已加softmax,所以from_logits设置为False
model.compile(optimizer='adam',
              loss={
                  'genderoutput': tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
                  'ethnicityoutput': tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
              },
              metrics=['accuracy'])

调整后model.predict()直接输出的就是符合要求的分类概率,同时特征提取层适配图像结构,训练稳定性会大幅提升,重复初始化的结果波动问题也会得到解决。

内容的提问来源于stack exchange,提问作者dabo1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:24:05