8、TensorFlow 中的激活函数

来源:互联网 发布:制作html5的软件 编辑:程序博客网 时间:2024/06/07 23:02

一、深层神经网络为什么需要激活函数?

  • 非线性激活函数的主要作用

    • 提供网络的非线性建模能力,增强模型的表达能力,双隐层神经网络能够解决任意复杂的分类问题
    • 将原始特征从低维空间映射到高维空间(从多项式角度看——它隐含的找到了所需的高次特征项(更好的特征),从而简化了繁重的计算)
  • 线性函数不能用作激活函数的原因

    • 线性函数的线性组合仍然是线性函数
    • 不能解决线性不可分问题

二、激活函数的分类、演化及优缺点

1、激活函数的分类

  • Traditional: sigmoid(logistic)、tanh
  • RELU Family: RELU、Leaky RELU、PRELU、RRELU
  • Exponential Family: ELU、SELU

这里写图片描述


2、激活函数的演化及优缺点

  • Sigmoid 的优缺点

    • 优点:
      • 可以把输入映射到(0, 1)区间,可以用来表示概率(eg:logistic regression)
      • 在物理意义上最为接近生物神经元
    • 缺点:
      • 梯度消失问题
        • 首先明确一点:误差反向传播时,梯度包含了f(zl)和上一层的误差项(又包含了f(zl+1):z 为权重加权和)两个乘法因子,具体反向传播推导见此链接
        • 一个原因是:由于 sigmoid 的导数f(zl)区间为(0, 0.25],所以其极易落入饱和区,导致梯度非常小,权重接近不变,无法正常更新
        • 另一个原因是:误差不断向底层传递的过程中,f(zl)会呈指数倍增加,而其值域为(0, 0.25],所以梯度越往后传递值越小,最终导致权重无法正常更新
      • Sigmoid outputs are not zero-centered(待补充?还不是很清楚为什么?)
  • Tanh 的优缺点

    • 优点:
      • Tanh outputs are zero-centered,把输入映射到(-1, 1)区间
    • 缺点:
      • 虽然 tanh 的导数f(zl)区间为(0, 1],但仍然会导致梯度消失问题!
    • 在 RNN 中的应用:
      • RNN 中为什么要采用 tanh 而不是 RELU 作为激活函数?

    这里写图片描述

  • RELU 的优缺点

    • 优点:
      • 比 sigmoid/tanh 收敛的更快(6x),creating sparse representations with true zeros( more likely to be linearly separable)
      • 其导数在其权重和(z) 大于 0 的时候为 1,从而误差可以很好的传播,权重可以正常更新
    • 缺点:
      • 其导数在其权重和(z) 小于 0 的时候为 0,会导致梯度值为0,从而权重无法正常更新
      • 输出具有偏移现象,即输出均值恒大于零
        这里写图片描述
  • RELU 的变种
    这里写图片描述

  • ELU

    • 右侧线性部分使得 ELU 能够缓解梯度消失,而左侧软饱能够让 ELU 对输入变化或噪声更鲁棒
      这里写图片描述
  • SELU(出自 Self-Normalizing Neural Networks )
    • 激活函数有一个不动点,网络深了以后每一层的输出都是均值为 0 方差为 1
    • 可以防止梯度消失和梯度爆炸
    • 代码实现如下:
def selu(x):    with ops.name_scope('elu') as scope:        alpha = 1.6732632423543772848170429916717        scale = 1.0507009873554804934193349852946        return scale*tf.where(x>=0.0, x, alpha*tf.nn.elu(x))

三、激活函数实战建议

  • Use ReLU with a samll learning rate
  • Try out ELU / Leaky RELU / SELU
  • Try out tanh but don not expect much and never use sigmoid
  • Output layer should use softmax for classification or liner for regression

四、激活函数在 TensorFow 中的实现

# All activation ops apply componentwise, and produce # a tensor of the same shape as the input tensortf.sigmoid(x, name = None) == tf.nn.sigmoid(x, name = None)# y = 1 / (1 + exp(-x))tf.tanh(x, name = None)  == tf.nn.tanh(x, name = None)# y = (exp(x) - exp(-x)) / (exp(x) + exp(-x))tf.nn.relu(features, name=None)# y = max(features, 0)tf.nn.elu(features, name=None)# exp(features) - 1 if < 0, features otherwisetf.nn.relu6(features, name=None)# y = min(max(features, 0), 6)tf.nn.crelu(features, name=None)# concat 后的结果为:[relu(features), -relu(features)],一个是relu,一个是relu关于y轴对称的形状tf.nn.softplus(features, name=None)# y = log(exp(features) + 1)tf.nn.softsign(features, name=None)# y = features / (abs(features) + 1)

五、参考资料

1、深度学习中的激活函数导引
2、Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)
3、https://cs231n.github.io/neural-networks-1/

原创粉丝点击