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

双分支融合神经网络梯度全零、输出恒为1问题求助

问题诊断与解决方案

咱们先揪出导致输出恒为1且梯度消失的核心问题,再一步步修复:

1. 致命错误:最后一层激活函数误用

你的融合网络最后一层用了softmax激活,但你做的是单输出的二分类任务(输出单个值):

z_2 = tf.keras.layers.Dense(1, activation="softmax")(z_1)

Softmax的特性是所有输出节点的概率和为1,当只有1个输出节点时,它的输出永远是1.0——这直接导致模型输出恒为1,同时因为输出没有变化,梯度自然会归零(没有可优化的空间)。

修复方案:把最后一层的激活换成sigmoid,它专门用于单输出的二分类任务,输出值在0-1之间,表示样本属于某一类的概率:

z_2 = tf.keras.layers.Dense(1, activation="sigmoid")(z_1)

2. 其他潜在问题排查

(1)分支模型的可训练状态

虽然你说单独测试分支时梯度正常,但融合时要确保两个分支模型没有被意外冻结。可以在创建融合模型前确认:

model.trainable = True  # CNN分支保持可训练
feat_model.trainable = True  # 全连接分支保持可训练

(2)全连接网络代码的笔误

你的全连接网络代码最后一行写的是model.summary(),但应该是feat_model.summary()——这只是打印错误,不影响模型功能,但建议修正避免混淆。

修正后的完整融合网络代码

def create_combined(model_1, model_2):
    # 确保分支模型处于可训练状态
    model_1.trainable = True
    model_2.trainable = True
    
    # 拼接两个分支的输出
    combined = tf.keras.layers.concatenate([model_1.output, model_2.output])
    
    # 后续全连接层
    z_0 = tf.keras.layers.Dense(24, activation="relu")(combined)
    z_1 = tf.keras.layers.Dense(12, activation = "relu")(z_0)
    # 替换为适合二分类的sigmoid激活
    z_2 = tf.keras.layers.Dense(1, activation="sigmoid")(z_1)
    
    # 创建融合模型
    combined_model = tf.keras.Model(inputs=[model_1.input, model_2.input], outputs=z_2)
    combined_model.compile(loss='binary_crossentropy', optimizer='adam')
    return combined_model

额外优化建议

如果修复后梯度仍然有问题,可以尝试:

  • 降低Dropout比例:当前所有Dropout都是0.5,比例过高可能导致梯度传播困难,先降到0.2或0.3试试;
  • 标准化输入数据:图像建议归一化到[0,1]或[-1,1],数值特征用StandardScaler做标准化,输入分布异常也会干扰梯度更新;
  • 添加验证集监控:训练时加入validation_data,观察损失变化,确认模型是否在有效学习。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:18:44