乐趣区

关于算法:超全激活函数学习总结

前言

对于计算机视觉的学习教程临时告于段落,预计八月中旬当前我将会更新对于 CV 我的项目开发的学习笔记以及相干教程。当初的粉丝数曾经过百了,感激家人敌人给我的反对,以及机器学习爱好者们对我的必定,我将会持续保持我学习路线,分享给大家。接下来这节内容,选材来自昨天学习交换群中一位敌人,提出了无关激活函数的问题。我在收集了一下相干内容,在此整顿汇合比照激活函数的毛病和有余。

什么是激活函数

文章次要从激活函数概念,数学模式剖析,Python 代码模式展示,优缺点比照等方面进行学习。对于激活函数的定义 维基百科解释是:节点的激活函数定义了给定一个输出或一组输出的节点的输入。规范集成电路能够被视为激活函数的数字网络,依据输出能够是“ON”(1)或“OFF”(0)。此定义与逻辑回归的定义类似。
换句话说,激活函数是一种增加到神经网络中的函数,旨在帮忙网络学习数据中的简单模式。相似于人类大脑中基于神经元的模型,激活函数最终决定了要传送给下一个神经元的内容。在人工神经网络中,一个节点的激活函数定义了该节点在给定的输出或输出汇合下的输入。激活函数就是确定神经网络输入的数学方程。


当神经元接管到了其余神经元或外界传来的数字信号,神经元通过权重和偏置对输出信息进行线性变换,因为线性方程很简略解决简单问题的能力无限,因而退出激活函数对输出进行非线性变换使其可能学习和执行更简单的工作。此时激活函数的意义尤为重要,适合的激活函数也非常重要。

激活函数品种

常见的激活函数能够分为三类:岭函数,径向函数,以及利用在卷积神经网络中的折叠激活函数。

  • 岭函数:作用与输出变量的线性组合多元函数

    • 线性函数:

      $$
      {\displaystyle \phi (\mathbf {v} )=a+\mathbf {v} ‘\mathbf {b} }
      $$

    • ReLU 函数:

      $$
      {\displaystyle \phi (\mathbf {v} )=\max(0,a+\mathbf {v} ‘\mathbf {b} )}{\displaystyle \phi (\mathbf {v} )=\max(0,a+\mathbf {v} ‘\mathbf {b} )}
      $$

    • Heaviside 函数:

      $$
      {\displaystyle \phi (\mathbf {v} )=1_{a+\mathbf {v} ‘\mathbf {b} >0}}{\displaystyle \phi (\mathbf {v} )=1_{a+\mathbf {v} ‘\mathbf {b} >0}}
      $$

    • Logistic 函数:

$$
{\displaystyle \phi (\mathbf {v} )=(1+\exp(-a-\mathbf {v} ‘\mathbf {b} ))^{-1}}{\displaystyle \phi (\mathbf {v} )=(1+\exp(-a-\mathbf {v} ‘\mathbf {b} ))^{-1}}
$$

  • 径向激活函数:在欧几里得空间中求得点与点之间间隔,作为通用的函数迫近用具有很好的成果。

    • 高斯函数:

      $$
      {\displaystyle f(x)=a\cdot \exp \left(-{\frac {(v-c)^{2}}{2c^{2}}}\right)}
      $$

    • 多项式函数:

      $$
      {\displaystyle \,\phi (\mathbf {v} )={\sqrt {\|\mathbf {v} -\mathbf {c} \|^{2}+a^{2}}}}
      $$

​ 留神:c 为函数核心的向量和,a 为影响半径流传的参数

  • 折叠激活函数:宽泛应用池层在卷积神经网络中和多分类网络的输入层中。激活函数应用取均值,最小值或最大值。在多分类中,常常应用 software 激活

激活函数数学个性

每个激活函数都有着其个性,依据个性它可能实用在某一种模型中可能展示更好的成果。除了数学构造,激活函数还具备不同的数学个性:

  • 非线性:当激活函数为非线性,那么能够证实两层神经网络是一个通用函数迫近器。换句话说神经网络是由很多层神经元组成的,应用非线性激活函数能够把整个网络看作一个单层模型。使得神经网络能够任意迫近任何非线性函数,这个个性使神经网络应用到泛滥非线性模型中。
  • 范畴:激活函数的输入值的范畴能够是无限的也能够是有限的。当输入值是无限的时候,基于梯度的优化办法会更加稳固,因为特色的示意受无限权值的影响更加显著;当输入值有限时,模型的训练会更加高效。留神在这种状况,个别须要更小的学习率。
  • 间断可微:这个个性并不是必须的(ReLu 局部点不可微影响不大)这个个性保障了优化中梯度的可计算性。
  • 非饱和性:饱和指的是某些区间梯度靠近 0(梯度隐没),使得参数无奈持续更新。Sigmoid它的导数在靠近正无穷和负无穷时都会靠近 0。跃阶函数简直所有地位梯度都为 0,无奈作为激活函数。因而有一些学者提出了一些改良激活函数解决这类问题
  • 枯燥性:即导数符号不变,大部分激活函数都具备该特点。换句话说就是枯燥性使得激活函数的梯度方向不会常常扭转,使训练更容易收敛,成果更佳。
  • 靠近恒等变换:这个个性使得网络更加稳固,存在于大量激活函数中在 Tanh 中只有原点左近导数为 1,ReLu只在 x >0 时为线性。这一结构设计与 CNN 中的 ReNetRNN中的LSTM
  • 参数少:参数少能够缩小网络的大小
  • 归一化:次要思维是使样本分布主动归一化到零均值,单位方差的散布,从而稳固训练。

这些数学个性不会决定性的影响模型成果,也不存在惟一有用属性,通过这些属性能够不便咱们在构建模型时选出适合的激活函数。

激活函数比拟

接下来到了最要害的局部,激活函数的比照,咱们以及把握了激活函数的品种以及个性,那么都有哪些罕用的激活函数,以及他们的个性都有哪些呢。如下所示为多种常见激活函数的收集整理,外面蕴含内容有函数曲线,数学构造,范畴,可导区间,以及连续性。

常见激活函数全收集!

以及折叠函数的:

如何选取失当的激活函数

通过理解这些函数的,以及个性剖析,咱们能够总结一下如何抉择正确的激活函数;依据问题的性质,咱们能够为构建模型作出更佳抉择。联合一些文章提供的教训之说选取规定如下所示(仅供参考)

  • 首先思考常见的激活函数:SigmoidTanHReLULeaky ReLUELUSoftPlusBinary stepMaxout,以及Mish
  • 用于分类器时,Sigmoid函数及其组合通常成果更好
  • 对于防止梯度隐没问题,须要防止应用SigmoidTanH
  • 首先思考ReLU,速度最快,察看模型的体现,如果成果不好能够尝试Leaky ReLUMaxout
  • ReLU只能在暗藏层中应用
  • 当层数不多时的 CNN 中,激活函数影响不大。

代码实现

搞定了实践根底,接下来就该实战筹备造轮子环节了,倡议珍藏这些代码局部以备不时之需。

Sigmoid代码实现:实用于二分类,多分类,成果个别,留神梯度隐没问题

import numpy as np

def sigmoid(x):
    s = 1 / (1 + np.exp(-x))
    return s

# Tensorflow2.0 版
sigmoid_fc = tf.keras.activations.sigmoid(x)
# pytorch 版
sigmoid_fc = torch.nn.Sigmoid()
output = sigmoid_fc(x)

TanH代码实现:留神梯度隐没问题

import numpy as np

def tanh(x):
    s1 = np.exp(x) - np.exp(-x)
    s2 = np.exp(x) + np.exp(-x)
    s = s1 / s2
    return s

# Tensorflow2.0 版
tanh_fc = tf.keras.activations.tanh(x)
# pytorch 版
tanh_fc = torch.nn.Tanh()
output = tanh_fc(x)

ReLU代码实现:最罕用,只用于暗藏层

import numpy as np

def relu(x):
    s = np.where(x < 0, 0, x)
    return s

# Tensorflow2.0 版
relu_fc = tf.keras.activations.relu(x)
# pytorch 版
relu_fc = torch.nn.Relu()
output = relu_fc(x)

Leaky ReLU代码实现:利用于 当构建网络中存在大量未激活神经元时

import numpy as np

def lrelu(x):
    s = np.where(x >= 0, x, αx)
    return s

# Tensorflow2.0 版
lrelu_fc = tf.keras.activations.relu(x,alpha=0.01) # 须要指定 alpha 的大小 
# pytorch 版
lrelu_fc = torch.nn.LeakyReLU(0.01)
output = lrelu_fc(x)

ELU代码实现

import numpy as np

def elu(x):
    s = np.where(x >= 0, x, α(np.exp(x)-1)
    return s

# Tensorflow2.0 版
elu_fc = tf.keras.activations.elu(x,alpha=0.1) # 须要指定 alpha 的大小 
# pytorch 版
elu_fc = torch.nn.ELU(0.1)
output = elu_fc(x)

Softmax代码实现

def softmax(x):
    x_exp = np.exp(x)
    x_sum = np.sum(x_exp, axis=1, keepdims=True)
    s = x_exp / x_sum
    return s

# Tensorflow2.0 版
softmax_fc = tf.keras.activations.softmax(x)
# pytorch 版
softmax_fc = torch.nn.Softmax()
output = softmax_fc(x)

Binary step代码实现

def binaryStep(x):
    '''It returns'0'is the input is less then zero otherwise it returns one'''
    return np.heaviside(x,1)
x = np.linspace(-10, 10)
plt.plot(x, binaryStep(x))
plt.axis('tight')
plt.title('Activation Function :binaryStep')
plt.show()

Maxout代码实现:较量中应用

import tensorflow as tf

x = tf.random_normal([5,3])
m = 4
k = 3
d = 3

W = tf.Variable(tf.random_normal(shape=[d, m, k])) # 3*4*3
b = tf.Variable(tf.random_normal(shape = [m, k])) # 4*3
dot_z = tf.tensordot(x, W, axes=1) + b # 5 * 4 * 3
print(dot_z)
z = tf.reduce_max(dot_z, axis=2) # 5 * 4
print(z)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run([x,dot_z,z]))

Mish代码实现:较新的激活函数,体现优于 ReLUSwishTanHSoftplus 组合

原理如下:有趣味的能够看一看

import matplotlib.pyplot as plt
%matplotlib inline

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from keras.engine.base_layer import Layer
from keras.layers import Activation, Dense
from keras import backend as K
from sklearn.model_selection import train_test_split
from keras.datasets import mnist
from keras.optimizers import SGD
from keras.utils import np_utils
from __future__ import print_function
import keras
from keras.models import Sequential
from keras.layers.core import Flatten
from keras.layers import Dropout
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
import numpy as np

class Mish(Layer):
    '''
    Mish Activation Function.
    .. math::
        mish(x) = x * tanh(softplus(x)) = x * tanh(ln(1 + e^{x}))
    Shape:
        - Input: Arbitrary. Use the keyword argument `input_shape`
        (tuple of integers, does not include the samples axis)
        when using this layer as the first layer in a model.
        - Output: Same shape as the input.
    Examples:
        >>> X_input = Input(input_shape)
        >>> X = Mish()(X_input)
    '''

    def __init__(self, **kwargs):
        super(Mish, self).__init__(**kwargs)
        self.supports_masking = True

    def call(self, inputs):
        return inputs * K.tanh(K.softplus(inputs))

    def get_config(self):
        base_config = super(Mish, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

    def compute_output_shape(self, input_shape):
        return input_shape
      
      

def mish(x):
    return keras.layers.Lambda(lambda x: x*K.tanh(K.softplus(x)))(x)
 
 ###### Use in your model ##########
 
 model.add(Dense(128,activation= mish))

舞弊代码:小样本

def tanh(x):
    return (np.exp(x) - np.exp(-x))/(np.exp(x) + np.exp(-x))
 
def softplus(x):
    return np.log(1 + np.exp(x))
 
def misc(x):
    return x * tanh(softplus(x))

结语

通过盘点总结激活函数的意义,品种,数学个性,以及应用范畴等方面,咱们能够很好的意识了激活函数,并且在构建模型时如何抉择应用。我在学习交换群看到了有人问过这个问题,我在网上浏览很多文章,感觉这是一个值得总结,学习的问题。并且通过深刻理解原理意义,了解为什么选十分重要。不能只做代码的搬运工,应该有本人的思考见解,谋求境界高了,咱们眼界高了,能力有更多的倒退空间。不过这次文章的刻画应用了很多公式展现,让我的 Latex 编写能力有了大大的进步,我发现应用才有价值能力更快的成长。。。。

欢送小伙伴们交流学习!

参考文献:

1.Activation function https://en.wikipedia.org/wiki…

2. 非线性激活函数 https://zhuanlan.zhihu.com/p/…

3. 常见风行激活函数 https://cloud.tencent.com/dev…

4.Mish As Neural Networks Activation Function https://sefiks.com/2019/10/28…

5.Understand Maxout Activation Function in Deep Learning – Deep Learning Tutorial https://www.tutorialexample.c…

举荐浏览

  • 微分算子法
  • 应用 PyTorch 构建神经网络模型进行手写辨认
  • 应用 PyTorch 构建神经网络模型以及反向流传计算
  • 如何优化模型参数,集成模型
  • TORCHVISION 指标检测微调教程

退出移动版