sigmoid激励函数是个很敏感的函数

1/(1+exp(-x))在x大于10的时候,计算结果就差不多是1了,此时sigmoid的导函数sigmoid(x)(1-sigmoid(x))几乎为0,如果开发的时候用的是C/C++,训练的时候由于double类型加减时数量级差距过大训练无效,如果是python这种能给出高精度浮点数的语言,训练的效果也几乎没有。

对于sigmoid的使用,在初始化权重,偏置时,结合输入数据,初步估算一下权重和偏置的大小范围,以免一开始初始化就过大,从而导致训练的时候导数几乎为0。sigmoid导数最大的时候x=0,根据以往经验来看x在-4到4之间,sigmoid的导数都是比较精确且比较大的。(然而并不能大于0.25)

如果训练的模型深度比较足,tanh,ReLU,Leaky_ReLU都是不错的激励函数,而sigmoid因为梯度消失就鲜有出现了,使用的激励函数类型还是要看具体情况而定。


Sigmoid激活函数,在数值较大或者较小的时候会难以训练,使用ReLU激活函数max(0,x)。


前面加 btach normalization?


可以考虑一下batch normalize,尤其是sigmoid激活函数,通过batchnorm把输入重新拉回到均值0方差1的正态分布上,避免梯度消失的问题。

不过有一点要注意一下,因为不一定都要标准正态,为了增强网路表达能力,经常在batchnorm之后再加两个调节参数,具体可以百度一下。


方法有很多,基本思路可以归为以下两类。

1. 自适应学习率。 learning rate 是动态调整,一般开始时候大,后面慢慢调小。

2. 采用其他损失/激活函数。如hinge损失函数。


一般这种行为是 公式写错,或者下标写错,请重新阅读BP1234条公式来源


推荐阅读:
相关文章