激活函数
到目前为止,我们使用的激活函数全部都是σ σ 函数,然而这并不一定是最好的函数,有时其他可选的函数效果也很好,下面我们来介绍一下其他的函数。
如图所示,我们在这里使用σ σ 函数作为激活函数。我们现在使用g(z(x)),作为更一般的可以使用的函数。我们这里介绍一下tanhx,是双曲正切函数。tanhx,实际上在数学上是σ σ 函数经过平移之后的结果。tanhx相比于σ σ 函数更好的一点,就是他介于-1到1之间,平均值为0。而σ σ 函数的平均值为0.5。这实际上可以让下层的学习更方便一些。因为tanhx的平均值为0,所以几乎在任何场景下,他的结果都比σ σ 函数更好,但是有一个例外是在输出的预测值y^,因为我们希望输出的预测值介于0和1之间,而不是-1和1之间。在这里σ σ 函数要效果好很多。这时我们应该使用σ σ 函数作为输出层。
不过这两个函数也有一个缺点,从图像中我们可以看到,当z很大或者很小的时候,z的变化量接近于0,这在于我们求梯度的时候效果非常糟糕,会拖慢学习进度。
我们还有一个ReLU函数,为的就是应对这个问题,通常情况下我们都会使ReLU函数作为神经网络的激活函数,如果你不知道选什么函数作为激活函数,一般就选择ReLU函数。不过ReLU函数有一个缺点,就是如果z,是负数的时候,那么导数为0。在实践中使用ReLU函数,相比于tanh函数和σ σ 函数而言,学习效率会高很多,因为他没有斜率接近于0的时候。
最后,我们总结一下,如图所示:
深度学习的一个特点就是在建立神经网络时,可以有很多不同的选择,比如隐藏单元、激活函数,还有如何初始化权重。
为什么需要非线性激活函数
为什么神经网络必须要用非线性的函数呢,我们这里来解释一下:
如图所示,如果我们舍去激活函数,或者干脆就让激活函数就等于z本身,而不做一些非线性处理,在图的右侧我们可以看出,最后的结果是
a[2]=w‘x+b‘ a [ 2 ] = w ‘ x + b ‘
依旧是线性的。
如果你使用线性激活函数,那么神经网络不过是把输入经过线性组合之后再输出。对于这种情况来说,有激活函数和没有激活函数都没有办法改变线性性,无论是有多少的隐藏层也做不到。不引入非线性性,则永远只能在线性性里面打转。
神经网络的梯度下降法
下面我们介绍一下如何用梯度下降法来处理单隐层神经网络。
如图所示,左侧是正向传播的计算流程,右侧是反向传播的计算流程。右侧我们有一个语句:
np.sum(dz, axis=1, keepdims=True )
这个命令中axis=1表示的是要水平相加求和,keepdims=True表示的是防止python输出古怪的秩为1的数组,保证输出的是矩阵。
还有一个公式:
dz=wTdz∗g‘(z) d z = w T d z ∗ g ‘ ( z )
其中
g‘(z)
g
‘
(
z
)
表示的是隐藏层激活函数的导数,注意这里我们所不同的是乘号两边两个矩阵逐个元素相乘
输出层的公式:
dz=A−Y d z = A − Y
假设的是用sigmod函数进行一个二元分类。