深层神经网络
所谓深层神经网络,是指有多个hidden layer的神经网络,如下图所示,分别为logistic regression,1 hidden layer,2 hidden layers,5 hidden layers的神经网络:
深层神经网络的forward propagation和backward propagation
- forward propagation
首先定义深层神经网络的notation:
各层output为:a[i]
各层input为:z[i]
第0层的input,output均为a[0]
各层 hidden layer的激活函数为:g[i]()
各层的权重w[i]
各层的截距b[i]
上述几个notation具有如下的关系(forward propagation):
a[i] = g[i](z[i])
z[i+1]=w[i+1]a[i]+b[i+1] - backward propagation
现有一个一层神经网络:
第0层为input:a[0]
第1层为first hidden layer:z[1]=w[1]a[0]+b[1];a[1]=g[1](z[1]);
第2层为output:z[2]=a[2]=w[2]a[1]+b[2];cost function dz[2]=a[2]-y;
现推导backward propagation:
首先明确notation:将cost function记为 L;
dw=dL/dw,L在w处的导数;
db=dL/db,L在b处的导数;
dz=dL/dz,L在z处的导数;其中dz[2]=a[2]-y;
第二层w的导数dw[2]=(dL/dz[2])(dz[2]/dw[2])=(a[2]-y)(a[1])=dz[2]a[1]
第二层b的导数db[2]=(dL/dz[2])(dz[2]/db[2])=a[2]-y=dz[2]
第一层w的导数dw[1]=(dL/dz[2])(dz[2]/da[1])(da[1]/dz[1])(dz[1]/dw[1])=dz[2]w[2]g’[1](z[1])a[0]
第一层b的 导数db[1]=(dL/dz[2])(dz[2]/da[1])(da[1]/dz[1])(dz[1]/db[1])=dz[2]w[2]g’[1](z[1])
note that:上图右侧为backward propagation的矩阵形式。
搭建神经网络块
每个神经网络块包括一个input和一个output,在构建一个神经网络块时,我们需要运用forward propagation,和backward propagation,计算神经网络的w,b。
如上图所示:
在forward propagation中,输入a[0],初始化每一层的w[i],b[i],输出a[l]。
在backward propagation中,根据a[l]和y,输入da[l],输出每一层的da[i],dw[i],db[i],dz[i],并且通过gradient descent,以及dw[i],db[i],更新每一层的w[i],b[i]。
在上述forward propagation和backward propagation中,我们可以将forward propagation中的w[i],b[i],z[i]存储起来,以利于backward propagation中w,b的计算。
神经网络中的parameters和hyperparameters
运用神经网络的一些技巧
能够使神经网络运行速度加快的几个Python技巧
- vectorization:避免在神经网络中使用for循环
- broadcast:避免在神经网络中使用for循环
- 申明变量时,将变量初始化为(m,n)的形式,而不是(m,)形式
import numpy as np
a=np.random.randn(5,1) #正确申明方法
b=np.random.randn(5) #错误的申明方法
c=b.reshape(5,1) #纠正错误的方法
import numpy as np
np.sum(matrix,axis=1,keepdims=True) #确保将keepdims=True,以防止形成奇怪的数组shape:(n,)
激活函数选择
activation function
- sigmoid activation function
- tanh activation function
- ReLu activation function 和 Leaky ReLu activation function (rectify linear unit)
ReLu: a=max(0,z)
Leaky ReLu:a = max(0.01z,z)
comparision among activation functions
- 几乎在任何场景中,tanh都比sigmoid要好
- sigmoid is used only as output active fucntion in binary classification.
- 无论是tanh还是sigmoid,都有一个明显的缺陷,即当input无穷大或无穷小时,二者的导数都趋于0,这使得gradient descent进展缓慢,针对这一问题,可以采用ReLu或Leaky ReLu作为激活函数。ReLu中,当input<0时,其导数=0,Leaky ReLu中,当input<0时,其导数=0.01。而当input>0时,二者导数均为1。
- 一般情况下,当你不知道改用哪个active function时,1)首选ReLu,或,Leaky ReLu。或者,2)你可以使用cross-validation的方法,验证各个active function的优劣。
权重的初始化
- 不要将神经网络的权重初始化为0,this will lead to symmetry problem
在训练神经网络时,不应将各个layer的权重初始化为0。如果将w初始化为0,则hidden layer中的各个unit在每次的weight updating中将得到同样的权重,相当于每一层的hidden layer都在运行相同的function,这将使神经网络失去其原有的意义。 - 将神经网络的权重初始化为一些“比较小的随机数”
#例如:
import numpy as np
w = np.random.randn((2,2))*0.01
b=np.zeros((2,1)) #b不存在symmetry problem,因此可以b初始化为0
debug
当程序运行出现问题时,可以查看:
- if matrixes match each other
- check the dimentsion of matrix。如:matrix shape是否为(n,)的形式。