tensorflow中常用的激活函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_29957455/article/details/81841278

激活函数(activation function)运行时激活神经网络中某一部分神经元,将激活神经元的信息输入到下一层神经网络中。神经网络之所以能处理非线性问题,这归功于激活函数的非线性表达能力。激活函数需要满足数据的输入和输出都是可微的,因为在进行反向传播的时候,需要对激活函数求导。

在TensorFlow中也内置了许多的激活函数,安装好TensorFlow之后可以在tensorflow-->python-->ops-->nn.py文件中看到激活函数

接下来主要介绍一些常用的激活函数如:sigmoid、tanh、relu、dropout等。

1、sigmoid激活函数

sigmoid函数也被称为S型函数,它可以将整个实数区间映射到(0,1)区间,因此经常被用来计算概率,它也是在传统神经网络中被经常使用的一种激活函数。

    x = tf.constant([[-1,-2],[3,4],[5,6]],dtype=tf.float32)
    sess = tf.Session()
    print(sess.run(tf.sigmoid(x)))

sigmoid激活函数的优点:输出的映射区间(0,1)内单调连续,非常适合用作输出层,并且比较容易求导。

sigmoid激活函数的缺点:它具有软饱和性,即当输入x趋向于无穷的时候,它的导数会趋于0,导致很容易产生梯度消失。

  • log_sigmoid函数:对sigmoid函数求log,它将整个实数区间映射到了(负无穷,0)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

if __name__ == "__main__":
    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.log_sigmoid(x))
    print(y)
    plt.plot(np.arange(-10,10),y)
    plt.show()

2、tanh激活函数

tanh是双曲正切函数,它将整个实数区间映射到了(-1,1),tanh函数也具有软饱和性。它的输出是以0为中心,tanh的收敛速度比sigmoid要快,由于存在软饱和性,所以tanh也存在梯度消失的问题。

    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.tanh(x))
    print(y)
    plt.plot(np.arange(-10,10),y)
    plt.show()

3、relu激活函数

relu激活函数现在是最受欢迎的激活函数,经常被使用在神经网络中。relu函数的定义:f(x)=max(x,0)

    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.nn.relu(x))
    print(y)
    plt.plot(np.arange(-10,10),y)
    plt.show()

relu函数在x<0时,输出始终为0。由于x>0时,relu函数的导数为1,所以relu函数能够在x>0时保持梯度不断衰减,从而缓解梯度消失的问题,还能加快收敛速度,还能是神经网络具有稀疏性表达能力,这也是relu激活函数能够被使用在深层神经网络中的原因。由于当x<0时,relu函数的导数为0,导致对应的权重无法更新,这样的神经元被称为"神经元死亡"。

在TensorFlow中还包括了relu函数的扩展函数如:relu6和crelu,除此之外还有leaky relu、PRelu、RRelu等。

  • relu6激活函数:定义min(max(features,0),6),也就是说它的取值区间被限定在了[0,6]之间。
    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.nn.relu6(x))
    print(y)
    plt.plot(np.arange(-10,10),y)
    plt.show()

  • crelu激活函数:定义为[relu(x),relu(-x)]相对于relu(x),crelu的输出会增加一倍。
    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.nn.crelu(x))
    print(y)

  • softplus激活函数:定义为log((e^x)+1),被称为平滑的relu。
    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.nn.softplus(x))
    print(y)
    plt.plot(np.arange(-10,10),y)
    plt.show()

  • leak_relu激活函数:leak_relu激活函数会给x<0,一个斜率,而不是将所有x<0都输出0,默认斜率是0.2,x>0的部分仍然输出是x,即斜率为1,保持不变。
    x = tf.constant(np.arange(-10,10),dtype=tf.float32)
    sess = tf.Session()
    y = sess.run(tf.nn.leaky_relu(x,alpha=0.2))
    print(y)
    plt.plot(np.arange(-10,10),y)
    plt.show()

4、dropout函数

dropout函数会以一个概率为keep_prob来决定神经元是否被抑制。如果被抑制,该神经元输出为0,如果不被抑制则该神经元的输出为输入的1/keep_probbe倍,每个神经元是否会被抑制是相互独立的。神经元是否被抑制还可以通过调节noise_shape来调节,当noise_shape[i] == shape(x)[i],x中的元素是相互独立的。如果shape(x)=[k,l,m,n](k表示数据的个数,l表示数据的行数,m表示数据的列,n表示通道),当noise_shape=[k,1,1,n],表示数据的个数与通道是相互独立的,但是与数据的行和列是有关联的,即要么都为0,要么都为输入的1/keep_prob倍。

    x = tf.constant(np.array([np.arange(-5,5)]),dtype=tf.float32)
    sess = tf.Session()
    #元素之间互不干扰
    y = sess.run(tf.nn.dropout(x,keep_prob=0.5))
    print(y)
    #元素之间互不干扰
    y = sess.run(tf.nn.dropout(x,keep_prob=0.5,noise_shape=[1,10]))
    print(y)
    #元素之间存在关联
    y = sess.run(tf.nn.dropout(x,keep_prob=0.5,noise_shape=[1]))
    print(y)

猜你喜欢

转载自blog.csdn.net/sinat_29957455/article/details/81841278