1、神经网络概览
什么是神经网络?如下图:
神经网络的结构与逻辑回归类似,只是神经网络的层数比逻辑回归多一层,多出来的中间那层称为隐藏层或中间层。从计算上来看,神经网络的正向传播和反向传播比logistic回归多了一次重复的计算。引入新的标签:方括号上标[i]表示当前所处的层数;圆括号上标(i)表示第i个样本。
2、神经网络表示
下面我们讲解只有一个隐藏层的神经网络,这是一张神经网络结构图:
现在把隐藏层输出记为a^[1],上标从0开始。用下标表示第几个神经元,注意下标从1开始。例如a^[1]_1表示隐藏层第1个神经元(节点)。在python中,隐藏层有4个神经元就可以写成下面矩阵的形式:
当我们在计算网络的层数时,不算输入层。关于隐藏层对应的权重W^[i]和常数项b^[i]维度问题,总结:第i层的权重W^[i]维度的行等于i层神经元的个数,列等于i-1层神经元的个数;第i层常数项b^[i]的行等于第i层神经元的个数,列始终为1。
3、计算神经网络的输出
两层神经网络可以看成是逻辑回归再重复计算一次。如下图所示,逻辑回归的正向计算可以分解成计算z和a的两部分:
下面的圆圈代表了回归计算的两个步骤,神经网络重复计算这些步骤很多次:
对于两层神经网络,从输入层到隐藏层对应一次逻辑回归运算;从隐藏层到输出层对应一次逻辑回归运算。每层计算时,要注意对应的上标和下标,一般我们记上标方括号表示layer,下标表示第几个神经元。例如a^[l]_i表示第l层的第i个神经元。注意,i从1开始,l从0开始。
上述每个节点的计算都对应着一次逻辑运算的过程,分别由计算z和a两部分组成。
4、激活函数
在隐藏层和输出层可以选择激活函数,目前为止我们用的是sigma激活函数,但有时其他函数效果要好的多。我们看一些可供选择的函数。不同的激活函数有各自的优点。
sigmoid函数-(0,1)
tanh函数(双曲正切函数)-(-1,1)
-
-
此激活函数的平均值更接近0,类似数据中心化的效果,使数据平均值接近0,这实际让下一层的学习更方便一点。
-
sigmoid函数和tanh函数都有一个缺点,如果z非常大或非常小时,那么导数的梯度(函数的斜率)可能就很小,接近0,这样会拖慢梯度下降算法。
-
ReLU函数(修正线性单元)-机器学习最受欢迎的工具
-
-
在选择激活函数时有一些经验法则,如果你的输出是0和1(二元分类),那么sigmoid函数很适合作为输出层的激活函数,然后其他所有单元都用ReLU函数,这是今天大多数人都在用的。
-
ReLU的缺点是当z为负时,导数为0,但还有一个版本,带泄露的ReLU。
-
Leaky ReLU函数(泄露的ReLU)
-
-
为什么是0.01,可以把它设成学习函数的另一个参数,根据实际效果进行改动
-
总结:
-
sigmoid函数除非用于在二元分类的输出层,不然绝对不要用,或者几乎从来不用。
-
tanh函数几乎在所有场合都更优越。
-
最常用的默认激活函数是ReLU,如果你不确定用哪个,你就用这个,或者也可以试试带泄漏的ReLU。
深度学习的一个特点是在建立神经网络时经常有很多不同的选择,比如隐藏单元数、激活函数,还有如何初始化权重。当不确定哪种激活函数最有效时,可以先试试在保留交叉验证数据集上或者开发集上跑,看看哪个参数效果好,就用哪个。
5、随机初始化
当你训练神经网络时,随机初始化权重很重要,对于logistic回归,可以将群组初始化为零,但如果神经网络的各参数数组全部初始化为0,再使用梯度下降算法,那会完全无效。
一般做法是将W进行随机初始化(b可初始化为零)。python里可以使用如下语句进行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# 0.01怎么来的?实际上我们通常把权重矩阵初始化成非常小非常小的随机值,因为如果使用tanh函数或sigmoid激活函数,
# 权重太大是计算出来的值可能落在平缓部分,梯度的斜率非常小,意味着梯度下降法会非常慢,学习过程也会非常慢。