神经网络和深度学习

ee>简单涉及神经网络的前向传播、反向传播以及如何训练神经网络参数等基础内容,对神经网络先有个大致了解。



关于神经网络(Neural Network)

神经网络种类:
- CNN卷积神经网络(Convolution Neural Network):在图像领域经常用到;
- RNN递归神经网络(Recurrent Neural Network):对于序列数据,如音频,常使用RNN;

由于语言,不论英语还是汉字字母,或者是单词,都是逐个出现的,所以语言是最自然的序列数据。因此常使用更复杂的RNNs。

结构化数据和非结构化数据:
- 结构化数据:意味着数据的基本数据库,有专门的数据告诉你相关的信息。
- 非结构化数据:如音频或想要识别的图像或文本中的内容。可能是图像中的像素值或文本中的单个单词。

**函数:
最初神经网络常使用Sigmoid函数最为**函数,但Sigmoid函数具有一个很明显的弊端,即在函数取值的两端,斜率非常小,这在使用梯度下降进行反向传播的时候会导致梯度会非常接近0,学习的速率会变得非常缓慢,参数更新很慢。
所以,为了改善这个问题,人们使用一个叫做Relu的函数(修正线性单元):
1. Relu的梯度对所有输入为负值的都为0,所以梯度不会趋向于逐渐减小到0;
2. 在大于0的部分,Relu函数的梯度始终为1;

这样,就能使梯度下降算法运行的更快;

神经网络基础(Basics of Neural Nerwork)

二分类

一般输入神经网络的图片是由RGB三层不同值的矩阵组成的(如64*64*3),在使用神经网络对图片进行二分类操作时,往往将这三层矩阵的值展开放入一个列向量中(从第一层的第一行开始…)

神经网络和深度学习

如图所示,输入x是一个(nx,1)维的向量;
当输入一个很大的样本集的时候,比如有m个样本,则此时,输入x就变成了一个(nx,m)维的矩阵。
使用Python 的X.shape 可以查看矩阵的规模,即 X.shape=nx,m)

逻辑回归

在前向传播过程中,要对一个输入特征向量X(nx维向量)做出预测。
- 我们使用W作为逻辑回归的参数,它与输入特征向量x的维度相同,(也被称为特征权重)。
- b作为偏差,是一个实数。

所以首先做一个线性变换:y^=wTx+b
但是,对于二分类问题来说,仅仅线性变化并不能解决问题,我们需要一个介于0-1之间的预测值来对分类做出预测,因此,在这个基础上,可以再应用非线性**函数来讲函数转换维非线性函数,如

Sigmoid函数:

Sigmoid=11+ez

常将前面的先行函数部分作为z,即z=wTx+b作为非线性函数的输入;

逻辑回归的代价函数和梯度下降

为了训练逻辑回归模型的参数w和参数b,我们需要构建一个代价函数来计算得到的预测值与真实值之间的差距,从而通过动态调整参数w和b来降低这个差值;

前面知道模型的前向传播过程为:

z=wx+by^=a=σ(z)=11+ez

所以定义逻辑回归中损失函数(Loss Function): L(y^,y)

L(y^,y)=ylog(y^)(1y)log(1y^)

  • y=1时,损失函数L=log(y^),若要损失函数L尽可能小,则预测值y^就要尽可能大,因为sigmoid函数取值[0,1],所以预测值y^则会无限接近1。
  • y=0时,损失函数L=log(1y^),若要损失函数L尽可能小,则预测值y^就要尽可能小,因为sigmoid函数取值[0,1],所以预测值y^则会无限接近0。

损失函数适用于计算单个训练样本,所以定义一个代价函数(cost function)来计算m个样本的总代价:

J(w,b)=1mi=1m(y(i)logy^(i)(1y(i))log(1y^(i)))

所以在使用梯度下降法进行反向传播时,只需找到合适的w和b,将代价函数J总代价降到最低即可。

神经网络和深度学习

代价函数j(w,b)是一个凸函数,像个碗一样的。我们可以首先通过随机初始化参数w和b,然后不断地超函数的最低点移动,即不断向着函数梯度下降的方向移动(找最小值点),不断地迭代这个过程,
假定只有一个参数w,则通过梯度下降不断迭代来更新w参数:

w:=adJ(w)dw

:=
a

在逻辑回归中,代价函数J(w,b)有两个参数,所以在梯度下降过程中:

w:=waJ(w,b)wb:=baJ(w,b)b

总结:
前向传播:

z=w1x1+w2x2+by^=a=σ(z)=11+ezL(y^,y)=ylog(y^)(1y)log(1y^)J(w,b)=1mimL(y^(i),y(i))

梯度下降法更新 w,b :

w:=waJ(w,b)wb:=baJ(w,b)b

反向传播:损失函数L对预测值 a 求导:

dLdz=ay

进而,由链式求导法则:

dw1=1mimx1(i)(a(i)y(i))dw2=1mimx2(i)(a(i)y(i))db=1mim(a(i)y(i))

向量化以及Python广播

代码中使用for循环是一种非常低效的做法,所以将神经网络中各部分向量化,然后使用python的科学计算库来进行计算将极大程度上提升模型的计算速度,提升效率。
神经网络中常用的numpy语句:

Z=np.dot(w.T,X)+bdw=np.zeros(nx,1)nx×1

A.reshape(x,y)x×y

np.ones((n,n))n×n1

np.arange(n)1×n.reshape((n,1))n×1

在这里面,W.T是指W的转置;
而后面的+b,b是一个实数,当向量加上一个实数时,python会自动把这个实数b扩展成为一个1×m的行向量,这就是Python中的广播。

广播:当两个数组的后缘维度的轴长度相等或其中一方轴长为1,则认为是广播兼容,广播会在缺失的维度和轴长为1的维度上进行。
神经网络和深度学习

那么,再去掉for循环后,就可以使用python numpy来计算神经网络中向量化后的数据了:
前向传播:

Z=wTX+b=np.dot(w.T,X)+bA=σ(Z)

反向传播:

dZ=AYdw=1mXdzTdb=1mnp.sum(dZ)w:=wadwb:=badb

这样就实现了在不适用for循环的基础上实现前向传播和反向传播;
建议:一次迭代就进行依次梯度下降。

浅层与深层神经网络

向量化即将各层的单元排列在一起,作为一个矩阵来进行运算;
神经网络和深度学习
其中W的维度时W(×)

**函数:
神经网络和深度学习

除了Sigmoid以外,还有tanhReluLeakyRelu可作为**函数

优缺点比较:
- Sigmoid函数:在z轴方向特别大或特别小的时候,导数梯度或斜率会变得非常小,最后接近0,导致梯度下降速度缓慢,常用于二分类问题;
- tanh函数:(双曲正切函数)因为函数值域为(-1,1),其均值更接近0(sigmoid为0.5)。
- Relu函数:(修正线性单元函数),z是负值时,导数等于0;z>0时导数为1;不会产生梯度弥散问题。

为什么要使用非线性**函数:
去掉神经网络中的非线性**函数后,直接令a[1]=z[1],这个被称为线性**函数(也称恒等激励函数),他们就是把输入值线性组合后再进行输出。那么无论神经网络中有多少层,一直再用线性**函数,输出层用sigmoid函数,那么这个模型的复杂度和没有任何隐藏层的标准Logistic回归是一样的。(即可以去掉所有隐藏层,他们没有意义了)

随机初始化参数:
训练神经网络的时候,权重随机初始化非常重要,但如果把权重都初始化为0,那么梯度下降将不会起任何作用。即如果W全为0的话,那么隐含单元就会完全一样,他们完全对称。
所以初始化参数时:
- 应该令W[1]=np.random.randn(2,2),高斯分布,然后再乘上一个很小的数(如0.01),把他们初始化为很小的随机数。
- b则没有限制,可以直接初始化为0;

如:

W[1]=np.random.randn(2,2)0.01b[1]=np.zeros((2,1))W[1]=np.random.randn(2,2)0.01

核对矩阵的维数:

1w;2b1;3b[l]:(n[l],1);4z[l],a[l]:(n[l],1);5dw[l]w[l]db[l]b[l]wbzax

参数和超参数:
什么是超参数
算法中的学习率 a,梯度下降法循环的数量,隐藏层数目L ,隐藏层单元数n[l],**函数的选择,这些都是超参数。
神经网络和深度学习

IdeaCodeExperimentIdea 循环,尝试不同参数,实现模型,然后迭代,观察损失函数的值变化情况。