1. 激活函数简述
激活函数是向神经网络中引入非线性因素,通过激活函数神经网络就可以拟合各种曲线。激活函数主要分为饱和激活函数(Saturated Neurons)和非饱和函数(One-sided Saturations)。Sigmoid和Tanh是饱和激活函数,而ReLU以及其变种为非饱和激活函数。非饱和激活函数主要有如下优势:
- 非饱和激活函数可以解决梯度消失问题。
- 非饱和激活函数可以加速收敛。
2.激活函数特点
一般来说,在神经元中,激活函数是很重要的一部分,为了增强网络的表示能力和学习能力,神经网络的激活函数都是非线性的,通常具有以下几点性质:
- 连续并可导(允许少数点上不可导),可导的激活函数可以直接利用数值优化的方法来学习网络参数;
- 激活函数及其导数要尽可能简单一些,太复杂不利于提高网络计算率;
- 激活函数的导函数值域要在一个合适的区间内,不能太大也不能太小,否则会影响训练的效率和稳定性。
3. 相关疑问
- 什么是激活函数,为什么需要激活函数?
激活函数是在神经网络层间输入与输出之间的一种函数变换,目的是为了加入非线性因素,增强模型的表达能力。
- 了解那些激活函数以及应用?回答主要分两类(饱和/非饱和),以及应用场景等。有时候可能特定到具体经典模型,比如LSTM用到Tanh,Transfromer中用到的ReLU,Bert中的GeLU,YOLO的Leaky ReLU等。
- 梯度消失与梯度爆炸现象与原因以及解决办法?参看梯度消失与梯度爆炸部分。
- ReLU激活函数为什么会出现死神经元,解决办法?
除上文提到输入为负值时,ReLU的梯度为0造成神经元死亡。还有Learning rate太高导致在训练过程中参数更新太大 。
解决办法主要有:1.优化参数。 2.避免将learning rate设置太大,或者使用Adam等自动调节learning rate的方法。3.更换激活函数。
4. python绘制激活函数图像
import matplotlib.pyplot as plt import numpy as np x = np.linspace(-10,10) ##### 绘制sigmoid图像 fig = plt.figure() y_sigmoid = 1/(1+np.exp(-x)) ax = fig.add_subplot(321) ax.plot(x,y_sigmoid,color='blue') ax.grid() ax.set_title('(a) Sigmoid') ax.spines['right'].set_color('none') # 去除右边界线 ax.spines['top'].set_color('none') # 去除上边界线 ax.spines['bottom'].set_position(('data',0)) ax.spines['left'].set_position(('data',0)) ##### 绘制Tanh图像 ax = fig.add_subplot(322) y_tanh = (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x)) ax.plot(x,y_tanh,color='blue') ax.grid() ax.set_title('(b) Tanh') ax.spines['right'].set_color('none') # 去除右边界线 ax.spines['top'].set_color('none') # 去除上边界线 ax.spines['bottom'].set_position(('data',0)) ax.spines['left'].set_position(('data',0)) ##### 绘制Relu图像 ax = fig.add_subplot(323) y_relu = np.array([0*item if item<0 else item for item in x ]) ax.plot(x,y_relu,color='darkviolet') ax.grid() ax.set_title('(c) ReLu') ax.spines['right'].set_color('none') # 去除右边界线 ax.spines['top'].set_color('none') # 去除上边界线 ax.spines['bottom'].set_position(('data',0)) ax.spines['left'].set_position(('data',0)) ##### 绘制Leaky Relu图像 ax = fig.add_subplot(324) y_relu = np.array([0.2*item if item<0 else item for item in x ]) ax.plot(x,y_relu,color='darkviolet') ax.grid() ax.set_title('(d) Leaky Relu') ax.spines['right'].set_color('none') # 去除右边界线 ax.spines['top'].set_color('none') # 去除上边界线 ax.spines['bottom'].set_position(('data',0)) ax.spines['left'].set_position(('data',0)) ##### 绘制ELU图像 ax = fig.add_subplot(325) y_elu = np.array([2.0*(np.exp(item)-1) if item<0 else item for item in x ]) ax.plot(x,y_elu,color='darkviolet') ax.grid() ax.set_title('(d) ELU alpha=2.0') ax.spines['right'].set_color('none') # 去除右边界线 ax.spines['top'].set_color('none') # 去除上边界线 ax.spines['bottom'].set_position(('data',0)) ax.spines['left'].set_position(('data',0)) ax = fig.add_subplot(326) y_sigmoid_dev = y_sigmoid*(1-y_sigmoid) ax.plot(x,y_sigmoid_dev,color='green') ax.grid() ax.set_title('(e) Sigmoid Dev') ax.spines['right'].set_color('none') # 去除右边界线 ax.spines['top'].set_color('none') # 去除上边界线 ax.spines['bottom'].set_position(('data',0)) ax.spines['left'].set_position(('data',0)) plt.tight_layout() plt.savefig('Activation.png') plt.show()