3.TensorFlow激活函数使用
激活函数activation function 运行时激活神经网络中某一部分神经元,将激活信息向后传入下一层的神经网络。神经网络之所以能解决非线性问题(入语音、图像识别),本质上就是激活函数加入了非线性因素,弥补了线性模型的表达力,把“激活的神经元的特征”通过函数保留并映射到下一层。
因为神经网络的数学基础是处处可微的,所以选取的激活函数要能保证数据输入与输出也是可微的。
激活函数不会更改输入数据的维度,也就是输入和输出的维度是相同的。TensorFlow中有如下激活函数,这里包括平滑的非线性的激活函数,如sigmoid、tanh、elu、softplus、softsign,也包括连续但不是处处可微的函数relu、relu6、crelu、relu_x,以及随机正则化函数dropout:
tf.nn.relu()
tf.nn.sigmoid()
tf.nn.tanh()
tf.nn.elu()
tf.nn.bias_add()
tf.nn.crelu()
tf.nn.relu6()
tf.nn.softplus()
tf.nn.softsign()
tf.nn.dropout()#防止过拟合,用来舍弃某些神经元
上述激活函数的输入均为要计算的x(一个张量),输出均为x数据类型相同的张量。常见的激活函数有sigmoid、tanh、relu、softplus这4种。
1、sigmoid函数。
这是传统神经网络中最常用的激活函数之一(另一个是tanh)
![这里写图片描述](https://upload.wikimedia.org/wikipedia/commons/thumb/8/88/Logistic-curve.svg/320px-Logistic-curve.svg.png)
sigmoid函数有点在于,它的映射在(0,1)内,单调连续,非常适合用作输出层,并且求导比较容易。但是,它也有缺点,因为软饱和性,一旦输入落入饱和区, f′(x) f ′ ( x ) 就会变得接近于0,很容易产生梯度消失。
import tensorflow as tf
a = tf.constant([[1.0,2.0],[1.0,2.0],[1.0,2.0]])
sess = tf.Session()
print(sess.run(tf.sigmoid(a)))
输出:
[[ 0.7310586 0.88079703]
[ 0.7310586 0.88079703]
[ 0.7310586 0.88079703]]
2、tanh函数
tanh函数也具有软饱和性。因为它的输出以0为中心,收敛速度比sigmoid要快。但是仍无法解决梯度消失的问题。
3、relu函数
relu函数是目前最受欢迎的激活函数。softplus可以看作是ReLU的平滑版本。relu定义为 f(x)=max(x,0) f ( x ) = m a x ( x , 0 ) 。softplus定义为 f(x)=log(1+exp(x)) f ( x ) = l o g ( 1 + e x p ( x ) ) 。
relu在x<0时硬饱和。由于x>0时导数为1,所以,relu能够在x>0时保持梯度部衰减,从而缓解梯度消失问题,还能够更快地收敛,并提供了神经网络的稀疏表达能力。但是,随着训练的进行,部分输入会落到硬饱和区,导致对应的权重无法更新,称为“神经元死亡”。
import tensorflow as tf
a = tf.constant([-1.0,2.0])
with tf.Session() as sess:
b = tf.nn.relu(a)
print(sess.run(b))
输出:
[ 0. 2.]
除了relu,TensorFlow还定义了relu6,也就是定义在min(max(feature,0),6)的tf.nn.relu6(features, name=None)。
以及crelu,tf.nn.crelu(features, name=None)。