1、神经网络基础
1.1 从二分类问题定义神经网络
符号说明:
- 训练数据:
(x,y)={(x(1),y(1)),(x(2),y(2)),⋯,(x(m),y(m))},训练样本包含m个;
- 其中
x∈Rnx,表示样本
x包含
nx个特征;
-
y∈{0,1},目标值属于0、1类;
输入神经网络时样本数据的形状:
注:这里定义X的形状与机器学习中定义的不一样,机器学习中行是样本,列是特征;而神经网络定义的行是特征,列是样本。
1.2 Logistic Regression
神经网络中,Sigmoid函数是其中一种激活函数:
Sigmoid(z)=1+e−z1
常用于神经网络最后一层的激活函数进行分类:
y^=Sigmoid(wTx+b)=σ(wTx+b)
注:Sigmoid函数有个很重要的性质,一阶导数可以用自身表示:
σ′(z)=σ(z)(1−σ(z))
- 这里可以解释
梯度消失
的问题,当
z=0时,导数最大,但是导数最大为
σ′(0)=σ(0)(1−σ(0))=0.5(1−0.5)=0.25,这里导数仅为原函数值的0.25倍。
- 参数梯度下降公式的不断更新,
σ′(z)会变得越来越小,每次迭代参数更新的步伐越来越小,最终接近于0,产生梯度消失的现象。
1.3 损失函数
(1)Loss function
一般经验来说,使用平方错误(squared error)来衡量Loss Function:
L(y^,y)=21(y^−y)2
但是,对于logistic regression 来说,一般不适用平方错误来作为Loss Function,这是因为上面的平方错误损失函数一般是非凸函数(non-convex),其在使用低度下降算法的时候,容易得到局部最优解,而不是全局最优解。因此要选择凸函数。
逻辑回归的Loss Function:
L(y^,y)=−(ylogy^+(1−y)log(1−y^))
- 当
y=1时,
L(y^,y)=−logy^。如果
y^越接近1,
L(y^,y)≈0,表示预测效果越好;如果
y^越接近0,
L(y^,y)≈+∞,表示预测效果越差;
- 当
y=0时,
L(y^,y)=−log(1−y^)。如果
y^越接近0,
L(y^,y)≈0,表示预测效果越好;如果
y^越接近1,
L(y^,y)≈+∞,表示预测效果越差;
- 我们的目标是最小化样本点的损失Loss Function,损失函数是针对单个样本点的。
(2)Cost function
全部训练数据集的Loss function总和的平均值即为训练集的代价函数(Cost function)。
J(w,b)=m1i=1∑mL(y^(i),y(i))=−m1i=1∑m[y(i)logy^(i)+(1−y(i))log(1−y^(i))]
- Cost function是待求系数w和b的函数;
- 我们的目标就是迭代计算出最佳的w和b的值,最小化Cost function,让其尽可能地接近于0。
1.4 梯度下降法
用梯度下降法(Gradient Descent)算法来最小化Cost function,以计算出合适的w和b的值。
每次迭代更新的修正表达式:
w:=w−α∂w∂J(w,b)
b:=b−α∂b∂J(w,b)
在程序代码中,我们通常使用dw来表示
∂w∂J(w,b),用db来表示
∂b∂J(w,b)。
1.5 逻辑回归中的梯度下降法
对单个样本而言,逻辑回归Loss function表达式:
z=wTx+by^=a=σ(z)L(a,y)=−(ylog(a)+(1−y)log(1−a))
反向传播过程:
对da、dz求导:
da=∂a∂L=−ay+1−a1−ydz=∂z∂L=∂a∂L⋅∂z∂a=(−ay+1−a1−y)⋅a(1−a)=a−y
对
w1、w2和b进行求导:
db=∂b∂L=∂z∂L⋅∂b∂z=1⋅dz=a−y
梯度下降法:
w1:=w1−αdw1
w2:=w2−αdw2
b:=b−αdb
1.6 m个样本的梯度下降
(1)单个样本表示:
对m个样本来说,其Cost function表达式如下:
z(i)=wTx(i)+by^(i)=a(i)=σ(z(i))J(w,b)=m1i=1∑mL(y^(i),y(i))=−m1i=1∑m[y(i)logy^(i)+(1−y(i))log(1−y^(i))]
Cost function 关于w和b的偏导数可以写成所有样本点偏导数和的平均形式:
dw1=m1i=1∑mx1(i)(a(i)−y(i))
db=m1i=1∑m(a(i)−y(i))
(2)向量化表示:避免在程序中使用for循环,提高计算的速度。
- 输入矩阵X:
(nx,m)
- 权重矩阵w:
(nx,1)
- 偏置b:常数
- 输出矩阵Y:
(1,m)
所有m个样本的线性输出Z可以用矩阵表示:
Z=wTX+b
逻辑回归梯度下降输出向量化:
dZ对于m个样本,维度为(1,m),表示为:
dZ=A−Y
dw可表示为:
dw=m1X⋅dZT
db可以表示为:
db=m1i=1∑mdz(i)
2、浅层神经网络
2.1 神经网络表示
单隐层神经网络示意图:
由图中可以看出,层与层之间参数矩阵的规格大小:
- 输入层和隐藏层之间
- w[1]−>(4,3):前面的4是隐层神经元的个数,后面的3是输入层神经元的个数;
- b[1]−>(4,1):和隐藏层的神经元个数相同;
- 隐藏层和输出层之间
- w[1]−>(1,4):前面的1是输出层神经元的个数,后面的4是隐层神经元的个数;
- b[1]−>(1,1):和输出层的神经元个数相同;
由上面我们可以总结出,在神经网络中,我们以相邻两层为观测对象,前面一层作为输入,后面一层作为输出,两层之间的w参数矩阵大小为
(nout,nin),b参数矩阵大小为
(nout,1),这里是作为
z=wX+b的线性关系来说明的,在神经网络中,
w[i]=wT。
注:在逻辑回归中,一般我们都会用
(nin,nout)来表示参数大小,计算使用的公式为:
z=wTX+b,要注意这两者的区别。
单个结点示意图:
除输入层之外每层的计算输出示意图:
由图中可以看出,每个结点都对应这两个部分的运算,z运算和a运算。
使用向量化
去计算神经网络的输出:
关于向量化的解释:
2.2 神经网络的前向传播和后向传播:
前向传播和后向传播过程:
反向传播时梯度下降法的参数:
- 参数:
W[1],b[1],W[2],b[2];
- 输入层特征向量个数:
nx=n[0];
- 隐藏层神经元个数:
n[1];
- 输出层神经元个数:
n[2]=1;
-
W[1]的维度为
(n[1],n[0]),
b[1]的维度为
(n[1],1);
-
W[2]的维度为
(n[2],n[1]),
b[2]的维度为
(n[2],1);
下面为神经网络反向梯度下降公式(左)和其代码向量化(右):
2.3 神经网络的激活函数
几种常用的激活函数
g(x):
- sigmoid:
g(z)=1+e−z1
- 导数:
g′(z)=a(1−a)
- tanh:
g(z)=ez+e−zez−e−z
- 导数:
g′(z)=1−a2
- ReLU(修正线性单元):
g(z)=max(0,z)
- 导数:
g′(z)=⎩⎪⎨⎪⎧0,1,undefine(任意取值),if z < 0if z > 0if z = 0
- Leaky ReLU:
g(z)=max(0.01z,z)
- 导数:
g′(z)=⎩⎪⎨⎪⎧0.01,1,undefine(任意取值),if z < 0if z > 0if z = 0
激活函数的选择:
(1)sigmoid函数和tanh函数比较:
- 隐藏层:tanh函数的表现要好于sigmoid函数,因为tanh取值范围为[−1,+1],输出分布在0值的附近,均值为0,从隐藏层到输出层数据起到了
归一化
(均值为0)的效果。
- 输出层:对于二分类任务的输出取值为{0,1},故一般会选择sigmoid函数。
(2)然而sigmoid和tanh函数在当|z|很大的时候,梯度会很小,在依据梯度的算法中,更新在后期会变得很慢。在实际应用中,要使|z|尽可能的落在0值附近。
(3)ReLU弥补了前两者的缺陷,当z>0时,梯度始终为1,从而提高神经网络基于梯度算法的运算速度。然而当z<0时,梯度一直为0,但是实际的运用中,该缺陷的影响不是很大。
(4)Leaky ReLU保证在z<0的时候,梯度仍然不为0。
在选择激活函数的时候,如果在不知道该选什么的时候就选择ReLU,当然也没有固定答案,要依据实际问题在交叉验证集合中进行验证分析。
2.4 随机初始化的重要性
如果在初始时,两个隐藏神经元的参数设置为相同的大小,那么两个隐藏神经元对输出单元的影响也是相同的,通过反向梯度下降去进行计算的时候,会得到同样的梯度大小,所以在经过多次迭代后,两个隐藏层单位仍然是对称的。无论设置多少个隐藏单元,其最终的影响都是相同的,那么多个隐藏神经元就没有了意义。
在初始化的时候,WW参数要进行随机初始化,bb则不存在对称性的问题它可以设置为0。
以2个输入,2个隐藏神经元为例:
W = np.random.rand((2,2))* 0.01
b = np.zero((2,1))
这里我们将W的值乘以0.01是为了尽可能使得权重W初始化为较小的值,这是因为如果使用sigmoid函数或者tanh函数作为激活函数时,W比较小,则
Z=WX+b所得的值也比较小,处在0的附近,0点区域的附近梯度较大,能够大大提高算法的更新速度。而如果W设置的太大的话,得到的梯度较小,训练过程因此会变得很慢。
ReLU和Leaky ReLU作为激活函数时,不存在这种问题,因为在大于0的时候,梯度均为1。
3、深层神经网络
3.1 深层神经网络的表示
DNN结构示意图如图所示:
对于第
l层神经网络,单个样本其各个参数的矩阵维度为:
-
W[l]:(n[l],n[l−1])
-
b[l]:(n[l],1)
-
dW[l]:(n[l],n[l−1])
-
db[l]:(n[l],1)
-
Z[l]:(n[l],1)
-
A[l] =
Z[l]:(n[l],1)
3.2 为什么使用深层网络
人脸识别和语音识别:
对于人脸识别,神经网络的第一层从原始图片中提取人脸的轮廓和边缘,每个神经元学习到不同边缘的信息;网络的第二层将第一层学得的边缘信息组合起来,形成人脸的一些局部的特征,例如眼睛、嘴巴等;后面的几层逐步将上一层的特征组合起来,形成人脸的模样。随着神经网络层数的增加,特征也从原来的边缘逐步扩展为人脸的整体,由整体到局部,由简单到复杂。层数越多,那么模型学习的效果也就越精确。
对于语音识别,第一层神经网络可以学习到语言发音的一些音调,后面更深层次的网络可以检测到基本的音素,再到单词信息,逐渐加深可以学到短语、句子。
所以从上面的两个例子可以看出随着神经网络的深度加深,模型能学习到更加复杂的问题,功能也更加强大。
注:较早的前几层能学习一些低层次的简单特征(自动特征工程),后几层能把简单的特征结合起来去探测更加复杂的东西。(从简单到复杂)
3.3 前向和反向传播
(1)首先给定DNN的一些参数:
-
L:DNN的总层数;
-
n[l]:表示第
l层的包含的单元个数;
-
a[l]:表示第
l层激活函数的输出;
-
W[l]:表示第
l层的权重;
- 输入
x记为
a[0],输出
y^记为
a[L]。
(2)前向和反向传播的过程
(3)前向和反向传播的公式
前向传播 Forward propagation
Input:
a[l−1]
Output:
a[l],
cache(z[l])
- 公式:
z[l]=W[l]⋅a[l−1]+b[l]a[l]=g[l](z[l])
- 向量化:
Z[l]=W[l]⋅A[l−1]+b[l]A[l]=g[l](Z[l])
反向传播 Backward propagation
Input:
da[l]
Output:
da[l−1],
dW[l],
db[l]
- 公式:
dz[l]=da[l]∗g[l]′(z[l])dW[l]=dz[l]⋅a[l−1]db[l]=dz[l]da[l−1]=W[l]T⋅dz[l]
将
da[l−1]代入
dz[l],有:
dz[l]=W[l+1]T⋅dz[l+1]∗g[l]′(z[l])
- 向量化程序:
dZ[l]=dA[l]∗g[l]′(Z[l])dW[l]=m1dZ[l]⋅A[l−1]db[l]=m1np.sum(dZ[l],axis=1,keepdims=True)dA[l−1]=W[l]T⋅dZ[l]
3.4 参数和超参数
参数:
参数即是我们在过程中想要模型学习到的信息,
W[l],
b[l]。
超参数:
超参数即为控制参数的输出值的一些网络信息,也就是超参数的改变会导致最终得到的参数
W[l],
b[l]的改变。
举例:
学习速率:
α
迭代次数:
N
隐藏层的层数:
L
每一层的神经元个数:
n[1],n[2],⋯
激活函数
g(z)的选择
参考:
神经网络和深度学习 吴恩达
吴恩达Coursera深度学习课程 DeepLearning.ai 笔记