激活函数:如果不用激活函数,每一层的输出都是上一层的线性组合,从而导致整个神经网络的输出为神经网络输入的线性组合,无法逼近任意函数。
1. sigmoid:数据压缩到[0,1]之间
问题:1)饱和的神经元导致梯度消失,输入非常大(10)或非常小(-10)时,其梯度接近于0,导致信息丢失,难以训练
2)输出不是以0为均值
3)指数运算计算量大,且梯度反传,求导设计除法(问题不大)
2. tanh: 数据压缩到[-1,1]之间
优点:与sigmoid相比,tanh是0均值
问题:1)与Sigmoid一样, 饱和的神经元导致梯度消失
3. ReLU: max(0, x)
优点:1)计算高效 ,没有饱和及梯度消失问题
2)由于Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
3)收敛速度比sigmoid/tanh快6倍
缺点:1)函数输出是非零中心
2)在负区间,当饱和时,梯度会消失。网络中多达10%到20%的部分是一些挂了的ReLU单元,大多数使用ReLU的网络都有这个问题。
4. Leaky-ReLU、P-ReLU:会解决ReLU挂掉的问题
5. ELU
优点: 所有ReLU的优点 ,不会死, 输出接近0均值
缺点:计算量大,需要指数运算
6. Maxout(x):优点:泛化ReLU和Leaky ReLU;不会饱和,梯度不会消失。缺点:由于需要多训练了几组参数,网络的效率也大大降低了。
关于0中心:当输入神经元的数值始终为正时,链式求导再乘以权值W,这时结果会要么全部是正数,要么全部是负数。这意味着所有关于w的梯度全为正值或者全为负值,那么它们就会总是朝着同一个方向移动。这样就会使得梯度只朝着正向或者负向更新,效率低见下图。
插图来自于:https://zhuanlan.zhihu.com/p/25110450
详细可参考:https://liam.page/2018/04/17/zero-centered-active-function/
实际选择:
神经网络训练过程
1. 数据预处理:实际操作可参考https://www.cnblogs.com/34fj/p/9036369.html
1)均值减法(中心化/零均值化):是指变量减去它的均值(避免输入数据都是正的,梯度更新效率低)
2)归一化(标准化):是指数值减去均值,再除以标准差。注意,这里指的是预处理时进行归一化操作。在深度学习不常用,通常只需要中心化。 而在网络训练中,我们通常会加入batch normalization操作。
通过中心化和标准化处理,最终得到均值为0,标准差为1的服从标准正态分布的数据。可以取消由于量纲不同、自身变异或者数值相差较大所引起的误差。
3)PCA
4)Whitening
机器学习中,常用的预处理操作除了中心化和归一化,还有PCA和白化(whitening)。前者对数据进行降维,后者对数据进行方差处理。简单来讲,PCA就是通过抛弃携带信息量较少的维度对数据进行降维处理,从而加速机器学习进程。白化是为了降低图像中相邻像素之间的相关性(冗余的);更正式的说,我们希望通过白化过程使得学习算法的输入具有如下性质:(i)特征之间相关性较低;(ii)所有特征具有相同的方差。参考:https://www.cnblogs.com/Ponys/p/3428270.html
2. 权重初始化
使用0进行权重初始化(X):输入数据后,每个神经元做相同的操作,输出相同的数值并得到相同的梯度,因此它们会用相同的方式更新权重。
选取较小的随机数:W = 0.01 * np.random.randn(D,H)。其中randn函数是基于零均值和标准差的一个高斯分布来生成随机数的。不适用于更深的网络。因为在更深的网络中,层的输出会趋近0,梯度也会变成0,权重将不会更新,网络就不会学习。
选取较大的随机数:当激活函数为tanh,sigmoid等等,该方法会导致饱和,使得梯度消失(变为0),权重将不会更新。
Xavier初始化:来自论文[Glorot et al.,2010]。该方式是一种合理的初始化方法。如果有较少的输入,将除以较小的数,从而得到较大的权重。如果有很多的输入,想要更小的权重,以便让它在输出中得到相同的传播。
神经网络模型中的参数权重W是不能全部初始化为零的,
参数b可以全部初始化为零,并不会影响神经网络训练效果。
-->解决方法也很简单,就是将W进行随机初始化(b可初始化为零)。
W_1 = np.random.randn((2,2))*0.01
b_1 = np.zero((2,1))
W_2 = np.random.randn((1,2))*0.01
b_2 = 0
这里我们将W1和W2矩阵乘以0.01的目的是尽量使得权重W初始化比较小的值。之所以让W比较小,是因为如果使用sigmoid函数或者tanh函数作为激活函数的话,W比较小,得到的|z|也比较小(靠近零点),而零点区域的梯度比较大,这样能大大提高梯度下降算法的更新速度,尽快找到全局最优解。如果W较大,得到的|z|也比较大,附近曲线平缓,梯度较小,训练过程会慢很多。
当然,如果激活函数是ReLU或者Leaky ReLU函数,则不需要考虑这个问题。但是,如果输出层是sigmoid函数,则对应的权重W最好初始化到比较小的值。
参考:https://blog.csdn.net/KKALL1314/article/details/104138540