如何让Sigmoid函数在张量上正常工作?自定义实现函数处理张量输出全1的问题排查
问题分析与解决办法
嘿,这问题我之前也碰到过!核心原因就是你的输入特征数值太大了,直接触发了sigmoid函数的饱和特性。
咱们来具体拆解:你看张量里的第二个特征,比如5.6e+04(也就是56000),当计算np.exp(-56000)时,这个值会无限趋近于0——毕竟指数函数在负的超大值下会快速衰减到接近0。代入sigmoid公式1/(1 + 0),结果自然就是1了。而且sigmoid函数有个特性:只要输入绝对值超过20左右,输出就会趋近于1或者0,完全失去区分度。
那怎么解决呢?必须先对特征做缩放处理,把数值拉到sigmoid能正常反应的范围里,这里推荐用标准化(Z-Score归一化),步骤如下:
- 先实现一个标准化函数,把每个特征转化为均值为0、标准差为1的分布:
import numpy as np def standardize_features(X): mean = np.mean(X, axis=0) # 按列计算每个特征的均值 std = np.std(X, axis=0) # 按列计算每个特征的标准差 # 处理标准差为0的特殊情况,避免除以0报错 return (X - mean) / np.where(std == 0, 1, std)
- 对原始张量做标准化后,再传入你的sigmoid函数:
def sigmoid(z): return 1/(1 + np.exp(-z)) # 你的原始输入张量 X = np.array([[2.9e+01, 5.6e+04], [6.4e+01, 8.9e+04], [3.3e+01, 1.7e+04], [4.5e+01, 9.4e+04], [2.4e+01, 2.6e+04], [5.5e+01, 2.4e+04], [3.5e+01, 5.2e+04], [5.7e+01, 6.5e+04], [4.5e+01, 3.2e+04], [5.2e+01, 7.5e+04], [6.2e+01, 3.1e+04]]) # 标准化特征 X_scaled = standardize_features(X) # 计算sigmoid输出 output = sigmoid(X_scaled) print(output)
这样处理后,输出就会是0到1之间的合理数值,不会全是1了。
另外补充一点:除了标准化,你也可以用最小-最大归一化把特征压缩到[0,1]区间,但对于logistic回归来说,标准化更适配后续的模型训练,能避免梯度消失的问题——毕竟超大输入不仅会让sigmoid输出饱和,还会让反向传播时的梯度趋近于0,导致模型学不到东西。
内容的提问来源于stack exchange,提问作者Larry Abecid
相关产品推荐
相关产品推荐

