1.神经网络概览
如图3.1,logistic回归模型的流程就是,输入特征x、参数w和参数b,然后算出z,再使用sigmoid函数算出a即是 ,然后计算损失函数L,这就是神经网络。可以把很多sigmoid单元堆叠起来构成一个神经网络,每个单元都对应一个z运算和a运算。用[1]表示第一层,[i]表示第i层,第i层的输出即为第i+1层输入,逐层计算z和a,最后计算L,当然也会有反向计算求导过程。
2.神经网络的表示
如图3.2,先看看一个隐藏层的情况,第0层为输入层,输出特征集;第1层为隐藏层,因为在训练过程中我们看不到(或者说不需要看到)隐藏层的值,所以称之为隐藏层;第2层为输出层,输出预测值 。每一层输出值称之为激活值a[i],一般不把输入层看成一个层,所以这是个双层神经网络。
3.计算神经网络的输出
神经网络输出的计算其实是同一步骤重复很多遍的过程。单隐藏层神经网络中,输入层输入特征x即(,,),接着第一层计算出(,,,)和(,,,),把传递给第二层,第二层重复第一层的步骤,把作为输入计算出和,最后得到预测值 =。假设输入特征x形状为(3,1),则形状为(4,3),形状为(4,1),形状为(4,1),形状为(1,1),形状为(1,1)。
4.多个样本的向量化
上面计算了一个输入样本的输出,下面用向量化方式计算多个输入样本的的输出。
如图3.6,描述了多个样本向量化过程,用上标(i)表示第几个样本。
5.向量化实现的解释
如图3.7,假设有3个样本,紫色代表第1个样本,绿色代表第2个样本,黄色代表3个样本,暂且忽略b,由X计算得到Z再利用广播机制加上b,计算结果和一个个样本计算是一致的。
6.激活函数
要搭建一个神经网络,可以在隐藏层选择使用什么激活函数,也可以在输出单元选择使用什么激活函数,这些可以根据情况选择,不同层激活函数可以不一样。在目前为止,我们一直用的都是sigmoid作为激活函数,但有时其他激活函数效果会更好。
如图3.8,=σ()改成=(),g代表非线性函数,并不一定是σ(sigmoid函数)。在使用sigmoid作为激活函数的场合,一般使用tanh函数代替,tanh函数表现往往比sigmoid函数更好。有一特例就是当输出必须是0< <1,则使用sigmoid函数,sigmoid函数值域是(0,1)。
sigmoid函数和tanh函数都有共同不足地方,当z特别大或者特别小时,函数的斜率接近0,这样会导致梯度下降算法变得非常慢。而Relu函数就不会有这问题,当z<0函数斜率为0,当z>0函数斜率为1,当z=0时斜率不存在,但实践中取值到这一点概率不大,我们也可以给这一点的斜率手动赋值为0或1。
选择激活函数有一些经验法则:
1.如果是二分类,输出为0< <1,则选sigmoid函数作为输出层激活函数,其他地方使用Relu函数作为激活函数。
2.Relu函数是激活函数默认选择,如果隐藏层不知道选哪个作为激活函数,就选Relu函数。因为Relu函数没有斜率接近0的情况,不会减慢梯度下降速度。
3.有人担心Relu函数当z<0时斜率为0会影响梯度下降,实际会有足够多的隐藏单元使z>0,对于大多数样本的训练还是挺快的。
4.也可以使用leaky Relu函数,这样就不会有斜率为0情况,但使用的比较少。
tanh函数比sigmoid函数优越,是因为sigmoid函数优化路径容易出现zigzag现象。
在logistic回归模型中,z=x+b,a=g(z),L=L(a,y),则dL/dw=dL/da * da/dw=dL/dw * z,由于sigmoid函数值大于0,所以每个节点的dL/dw方向相同,则会导致如图3.10的zigzag现象(红色箭头),导致梯度下降算法缓慢。
7.为什么需要非线性激活函数
如图3.11,把非线性激活函数换成线性激活函数,这时神经网络只是把输入线性组合再输出,多个隐藏层和一个隐藏层没什么区别。所以非线性激活函数可以记录每一层的状态,这样神经网络才能计算出有趣的函数。
8.神经网络的梯度下降法
如图3.12,假设是双层神经网络,则正向过程为
=X+,
=(),
=+,
=(),
反向过程为
=-Y,
=1/m* ,
=1/m* np.sum(dZ[2],axis=1,keepdims=True),
=* (),
=1/m* ,
=1/m *np.sum(,axis=1,keepdims=True)。
9.随机初始化
训练神经网络时,随机初始化权重w非常重要,如果将神经网络所有权重w都初始化为0或者都一样,那么梯度下降算法将完全无效。
如图3.13,参数都初始化为一样,那么=,dw也相等,两个单元都做一样的事,相当于一个单元,所以不允许权重w初始化为一样,偏置可以一样或者为0。
如图3.14,权重随机初始化后应该乘于0.01(或者其他值),避免权重过大,避免梯度过小,影响神经网络梯度下降。