Flux.jl模型添加Sigmoid激活函数后输出恒为1.0问题排查咨询
Flux.jl模型添加Sigmoid后输出全为1.0的问题排查与解决
常见原因
- 最后一层Sigmoid出现输入饱和:Sigmoid函数在输入值大于5时,输出会无限逼近1.0。你的模型中间两层全连接层没有添加激活函数,仅做线性变换,很容易将前序ResNet输出的特征值放大数倍,导致输入到Sigmoid的预激活值过大,直接进入饱和区间。
- 权重初始化不合理:最后一层全连接层的权重初始值过大、或者偏置初始化为较大的正数,也会直接导致预激活值偏高,触发Sigmoid饱和。
- 激活函数与任务不匹配:你当前是2分类任务,输出2个神经元搭配Sigmoid的话,两个输出值不会满足概率和为1的要求,若后续损失函数搭配错误,也会在训练过程中让模型输出快速走向饱和。
修复方案
- 先验证预激活值大小:暂时移除最后一层的Sigmoid激活,打印推理阶段最后一层的输出数值,若数值普遍大于5即可确认是饱和问题。
- 给中间层添加激活与归一化:给中间两层全连接层添加ReLU激活和层归一化,限制特征值的范围,避免数值无限制放大,参考修改后的代码:
σ = sigmoid model = Chain( resnet[1:end-2], Dense(2048, 1000, relu), LayerNorm(1000), Dense(1000, 256, relu), LayerNorm(256), Dense(256, 2, σ), );
- 调整激活函数与损失的搭配:如果需要输出两个类别的概率分布,建议将最后一层激活替换为Softmax,搭配交叉熵损失;如果坚持使用Sigmoid做二分类,可将最后一层改为输出1个神经元,搭配BCELoss使用。
- 调整最后一层权重初始化:将最后一层全连接层的权重初始化改为更小的范围,偏置初始化为0,避免初始状态就出现饱和。
内容的提问来源于stack exchange,提问作者logankilpatrick
相关产品推荐
相关产品推荐

