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

为何我的神经网络始终输出相同预测结果?技术求助

解决你的多标签分类模型总是输出固定值的问题

我来帮你梳理下可能的问题点和解决办法,你遇到的这种“模型只输出平均情况”的问题在多标签分类任务里挺常见的,咱们一步步排查改进:

1. 先修正网络结构里的激活函数错误

你代码里犯了一个小但关键的错误:在Dense层指定了activation='relu'之后,又叠加了LeakyReLU层。这相当于让数据先经过ReLU把所有负数变成0,再经过LeakyReLU——而LeakyReLU对0的处理还是0,等于完全浪费了LeakyReLU解决“神经元死亡”的作用,反而让模型更容易陷入梯度消失。

修正后的网络结构应该是去掉Dense层里的activation参数,只保留LeakyReLU:

model = Sequential()
model.add(Dense(150, input_dim=9600))  # 去掉activation='relu'
model.add(LeakyReLU(alpha=.01))
model.add(Dense(50))  # 同样去掉activation='relu'
model.add(LeakyReLU(alpha=.01))
model.add(Dense(12, activation='sigmoid'))

2. 更换适合多标签分类的损失函数和评估指标

你现在用的mean_squared_error是回归任务的损失函数,而你的任务是12个非互斥的二分类任务(每个输出对应一个“是否满足阈值”的判断),MSE会让模型趋向于输出训练数据的均值(也就是你看到的固定值),因为平方损失会惩罚偏离均值的预测,而不平衡的数据会让均值偏向多数类。

正确的选择是binary_crossentropy,这是专门针对多标签二分类的损失函数。同时评估指标别用普通的accuracy,改用binary_accuracy(每个标签单独计算准确率,更适合多标签场景):

from tensorflow.keras.optimizers import Adam

metrics_to_output = ['binary_accuracy']
model.compile(loss='binary_crossentropy', optimizer=Adam(), metrics=metrics_to_output)

3. 解决数据极度不平衡的问题

从你描述的输出结果(固定0 1 1 0 0 0 0 0 0 0 0 0)来看,训练数据里第2、3位的正样本(值为1)占比极高,其他标签的正样本极少。模型为了最小化损失,自然会一直预测最常见的组合。

解决办法可以用类别权重,给少数类的错误预测更高的惩罚:

import numpy as np

# 计算每个标签的类别权重:负样本数/正样本数
class_weights = {}
for label_idx in range(12):
    positive_count = np.sum(output[:, label_idx] == 1)
    negative_count = len(output) - positive_count
    # 避免除以0的情况
    class_weights[label_idx] = negative_count / positive_count if positive_count != 0 else 1.0

然后在训练时传入这个权重:

model.fit(x=input, y=output, batch_size=32, epochs=20, class_weight=class_weights)

4. 必须对输入数据做归一化

你的输入是9600维的高维数据,如果没有做归一化,不同维度的数值范围差异会极大干扰模型的梯度更新,导致模型无法学习到有效特征,只能输出平均情况。

用标准化把输入数据调整到均值为0、方差为1的分布:

from sklearn.preprocessing import StandardScaler

# 注意:只在训练数据上拟合scaler,再用它转换训练和测试数据
scaler = StandardScaler()
input_normalized = scaler.fit_transform(input)

# 训练时用归一化后的输入
model.fit(x=input_normalized, y=output, batch_size=32, epochs=20, class_weight=class_weights)

5. 调整训练策略

  • 增加训练轮数:你现在只训练了1个epoch,模型根本没机会学习到有效特征,至少训练20-50个epoch,同时观察训练损失和验证损失的变化,避免过拟合。
  • 加入验证集:用validation_split=0.1留出10%的数据做验证,看模型在 unseen 数据上的表现,判断是否过拟合或欠拟合。
  • 调整学习率:如果训练时损失下降很慢,可以试试把Adam的学习率调小(比如optimizer=Adam(learning_rate=0.0001)),避免梯度震荡。

关于你提到的softsign替换sigmoid

其实sigmoid本身是多标签分类的标准激活函数,问题不在激活函数上,而是前面的损失函数、数据处理和网络结构问题。如果你想尝试softsign也可以,但记得同步调整损失函数和目标值的范围(softsign输出是[-1,1],所以目标值也要对应调整),不过优先解决上面的几个核心问题会更有效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:29:37