目录
1. 深度神经网络 vs 神经网络
如上图所示:
当数据量比较少的时候,传统机器学习的性能提升很快,甚至是优于基于神经网络的机器学习的。但是随着数据量的越来越大,传统机器学习的性能逐渐趋于平坦,而基于神经网络的机器学习的性能却越来越好。而且随着神经网路的规模越来越大,性能也是越来越好。
所以说是规模推动深度学习快速发展,不仅仅是神经网络的规模,还有数据的规模。当下,要想达到高性能,要么训练一个大的网络,要么有大量的训练数据。然而这个在一定程度上也会达到瓶颈,比如用光了所有数据,或者网络太大需要太长的训练时间。不过目前条件下,光是规模就可以促进深度学习前进一大步。
当数据量在Small Training set这个区间时,不同的算法性能是不同的。如果没有很大的数据集,那么手工提取出来的feature在很大程度上决定了算法的性能。比如SVM的性能可能就会优于神经网络的性能,这个性能更多的是依赖提取feature的能力和算法的细节。
但是随着数据量的增大以及计算能力的加强,神经网络的性能表现的越来越好。当然除了数据和计算力,算法的发展也增强了神经网络的性能,比如激活函数从sigmoid换成了ReLU,使得神经网络有了重大的突破,解决了sigmoid算法中存在的梯度消失的问题(梯度几乎为0时,学习的进度会非常得缓慢),而ReLU的梯度始终为1,梯度永远不会消失,这使得梯度下降算法的速度很快。
支持深度学习快速发展的三要素:
- Data
- Computation
- Algorithm
在上一篇文章中,https://www.zybuluo.com/hummingbird2018/note/1265140,介绍了最简单的一层神经网络,接下来循序渐进地介绍深层神经网络。
2. 单层隐藏层的神经网络
这是一个2层的神经网络,其中:输入层2个神经元(代表2个feature),1层隐藏层4个神经元,激活函数为tanh,输出层1个神经元,激活函数为sigmoid
2.1 激活函数
在神经网络中,目前经常使用的激活函数主要是以下几种:
- sigmoid::S曲线
a的范围在(0, 1)之间,一般当a>=0.5时认为输出为1,a<0.5时为0。
该激活函数在神经网络中基本不再使用,因为下面的tanh完全能够替换掉它,而且效果比它还要好。唯一使用sigmoid的场景就是当需要输出一个二分类的结果时,因为这时要求的输出为 0 ≤ y ≤ 1 0 \le y \le 1 0≤y≤1,正好是sigmoid的范围。
- tanh:双正切曲线
它和sigmoid的差别就在于做了纵向平移和比例放大,使得它能够通过原点,范围在(-1, 1)之间。之所以比sigmoid的效果好在于:经过该激活函数输出的数据平均值更加接近于0,而不是0.5,使得数据中心化,当作为下一层的输入数据进行计算时更加的简单。在之前的机器学习中也曾经讲过,作为输入数据时,一般要做的预处理动作就有scale normalization和mean normalization(zero mean),目的都是为了计算效果更好。
但这两种激活函数有一个共同的缺点:当Z越大或者越小时,a的值越接近1或者-1,变化的幅度越来越小,这就会导致斜率会变得很小,接近于0,这会使得梯度下降变得缓慢,最终导致梯度消失的严重问题。为解决此问题,产生了一个新的激活函数:ReLU
- ReLU:Rectified Linear Unit
当z<0时,a = 0;当z >= 0 时,a = 1,此时斜率永远为1,所以不会发生梯度消失的问题。ReLU现在已经被广泛地应用在神经网络上,所以如果你不确定该选用什么激活函数时,那么就选择ReLU。
当然ReLU也有一个缺点:就是当z为负数时,其导数为0,虽然这在实际应用中并不是什么大的问题,因为通常隐藏单元输出的z都会大于0。不过为了解决这个问题,有个改进的版本:Leaky ReLU
- Leaky ReLU
它和ReLU的区别在于当z为负数的时候有一个很小的斜率,比如0.01,公式为:
g ( z ) = m a x ( 0.01 z , z ) g(z) = max(0.01z, z) g(z)=max(0.01z,z)
2.2 为什么需要非线性的激活函数
激活函数的作用就是去线性,如果没有激活函数会怎么样?
Z [ 1 ] = W [ 1 ] X + b [ 1 ] Z^{[1]} = W^{[1]}X + b^{[1]} Z[1]=W[1]X+b[1]
A [ 1 ] = Z [ 1 ] A^{[1]} = Z^{[1]} A[1]=Z[1]
Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]} Z[2]=W[2]A[1]+b[2]
A [ 2 ] = Z [ 2 ] A^{[2]} = Z^{[2]} A[2]=Z[2]
Y = A [ 2 ] = W [ 2 ] ( W [ 1 ] X + b [ 1 ] ) + b [ 2 ] Y = A^{[2]} = W^{[2]}(W^{[1]}X + b^{[1]}) + b^{[2]} Y=A[2]=W[2](W[1]X+b[1])+b[2]
扩展开来仍然得到一个如下格式的结果:
Y = W ′ X + b ′ Y = W^{\prime} X + b^{\prime} Y=W