首先要明确激活函数的作用,就是用来给模型加入非线性因素,使得模型处处可微。
神经网络的一般形式是:
Y=∑inwixi+b
Y = \sum_i^n w_ix_i +b
Y=i∑nwixi+b
加入激活函数后,形式为:
Y=激活函数(∑inwixi+b)
Y = 激活函数(\sum_i^n w_ix_i +b)
Y=激活函数(i∑nwixi+b)
以下是几种常用激活函数介绍:
1.sigmoid函数
1.1 Sigmoid公式:反正记不住。
1.2 Sigmoid代码实现:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#生成需要的X数据集
x = np.linspace(-8,8,100)
x = x.round(decimals=2)
#占位符
X = tf.placeholder(tf.float32)
Y = tf.nn.sigmoid(X)
with tf.Session() as sess:
y = []
for i in x:
y.append(sess.run(Y,feed_dict = {X:i}))
y = np.array(y)
y = y.round(decimals=3)
#画出sigmoid
plt.plot(x, y, linewidth=1,label='Sigmoid')
plt.legend(loc = 'best')
plt.show()
1.Sigmoid函数能把输入值转换的 0~1 之间,都是正值没有负值,所以用在分类中比较好。
2.从图中可以看出,sigmoid在 -6~6之间效果较好,在这范围之外,效果基本没有,所以容易导致梯度消失。
3.基于Sigmoid的这些特性,当计算的特征中没有太大的区别时,就需要更为细微的分类判断,此时选择Sigmoid函数比较理想!即在二分类问题中Sigmoid更好!
4.Sigmoid运算量大!
2.Tanh函数
之前我们知道Sigmoid函数值在 0~1 之间,没有负值,所以当我们需要负值时,Tanh函数会非常不错。
Tanh函数实现:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#生成需要的X数据集
x = np.linspace(-8,8,100)
x = x.round(decimals=2)
#占位符
X = tf.placeholder(tf.float32)
Y = tf.nn.tanh(X)
with tf.Session() as sess:
y = []
for i in x:
y.append(sess.run(Y,feed_dict = {X:i}))
y = np.array(y)
y = y.round(decimals=3)
#画出sigmoid
plt.plot(x, y, linewidth=1,c='red',label='Tanh')
plt.legend(loc = 'best')
plt.show()
1.从图中可以看出Tanh的取值范围是 -1~1 之间,弥补了Sigmoid没有负值的缺陷。所以在计算具有较大特征差距时,用Tanh比较好。
2.但是,Tanh函数拥有和Sigmoid同样的缺点,在两端时会导致 梯度消失,计算量大 的问题!
3.ReLU和Leaky_ReLU函数
3.1ReLU函数:
(1)公式:f(x) = max(0,x)
这个公式很简单, 大于0取x,小于等于0取0 。
(2)代码实现:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#生成需要的X数据集
x = np.linspace(-8,8,50)
x = x.round(decimals=2)
#占位符
X = tf.placeholder(tf.float32)
Y = tf.nn.relu(X)
with tf.Session() as sess:
y = []
for i in x:
y.append(sess.run(Y,feed_dict = {X:i}))
y = np.array(y)
y = y.round(decimals=3)
#画出sigmoid
plt.plot(x, y, linewidth=1,c='c',label='ReLU',marker='.')
plt.legend(loc = 'best')
plt.show()
1.从ReLU特性图中可以看出,它的计算特别简单,这会大大的提高计算机的运算效率!
2.但是由于ReLU函数将所有小于0的值都取0,这就忽略了负值信号,同样也会造成 梯度消失 的问题!所以就有了Leaky_ReLU函数。
3.2 Leaky_ReLU
(1) 公式:f(x) = max(0.01*x,x)
公式同样很简单,在x>0时取x,在x<=0时取(0.01*x)
(2) 代码实现
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#定义Leaky_ReLU函数
leaky = 0.1
def Leaky_ReLU(input):
return(tf.maximum(input,leaky*input))
#生成需要的X数据集
x = np.linspace(-8,8,50)
x = x.round(decimals=2)
#占位符
X = tf.placeholder(tf.float32)
Y = Leaky_ReLU(X)
with tf.Session() as sess:
y = []
for i in x:
y.append(sess.run(Y,feed_dict = {X:i}))
y = np.array(y)
y = y.round(decimals=3)
#画出sigmoid
plt.plot(x, y, linewidth=1,c='c',label='Leaky_ReLU',marker='.')
plt.legend(loc = 'best')
plt.show()
leaky大小可以自己调整,0<leaky<1就行。
4.Swish函数
Swish函数的效果更优于Relu函数,其公式如下:
f(x)=x∗sigmoid(x∗β)
f(x) = x * sigmoid(x*\beta)
f(x)=x∗sigmoid(x∗β)
代码实现:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#生成需要的X数据集
x = np.linspace(-8,8,50)
x = x.round(decimals=2)
#占位符
X = tf.placeholder(tf.float32)
Y = tf.nn.swish(X)
with tf.Session() as sess:
y = []
for i in x:
y.append(sess.run(Y,feed_dict = {X:i}))
y = np.array(y)
y = y.round(decimals=3)
#画出sigmoid
plt.plot(x, y, linewidth=1,c='r',label='Swish')
plt.legend(loc = 'best')
plt.show()
从图中可以看出,Swish函数就是比ReLU函数有点变形,但他的效果却比ReLU函数要好!
5.Softmax函数
1.Softmax函数可以算是sigmoid函数的扩展,因为sigmoid函数通常用在二分类问题中,但Softmax函数用在多分类问题中!
2.公式:
Si=ei∑1ej
S_i=\frac{e_i}{\sum_1e_j}
Si=∑1ejei
3.公式看看就行了,但你要知道,Softmax函数就是将神经元的多个输入映射到(0,1)区间内,每个输入值对应一个映射值,且映射值的总和为1,即概率为100%。
4.
y1 + y2 + y3 =1
5.代码实现:
import tensorflow as tf
import numpy as np
x = [-8,-1,3,8,25]
X = tf.placeholder(tf.float32)
Y = tf.nn.softmax(X)
with tf.Session() as sess:
y = sess.run(Y,feed_dict = {X:x})
print(y)
print(sum(y))
[4.6588862e-15 5.1090889e-12 2.7894681e-10 4.1399378e-08 1.0000000e+00]
1.0000000416834387
6.总结(前面要知道,总结要记住)
1.Sigmoid函数一般出现在二分类问题中,如果不是二分类问题,别用!
2.ReLU函数是个万精油,哪种情况下都可以用,记住一句话,遇事不决,ReLU解决!
3.Swish比ReLU效果更优,可以用其来替换ReLU函数。
4.通常一个网络含有多层网络,激活函数可以混搭使用。
如果在二分类问题中,前面几层网络使用ReLU函数,最后一层建议使用Sigmoid函数;
如果在多分类问题中,前面几层网络使用ReLU函数,最后一层建议使用Softmax函数。
其他情况,遇事不决,ReLU解决!