改善深度神经网络:超参数调试、正则化以及优化——实践方面(2-1)

1.测试集

在配置训练、验证和测试数据集的过程中做出正确决策会更高效的创建神经网络

在机器学习中,经常将样本分为训练集、验证集和测试集三部分。对于早期的机器学习的数据而言,经常使用 70%/30% 来划分验证集和测试集或者使用 60%/20%/20% 来划分训练集、验证集和测试集。

在大数据时代中,假如有1000000个数据,那么验证集就不需要太大,有10000条验证数据或者10000条测试数据就够了,即占到总量的10%以下

举个例子:

假如需要做一个应用程序,分辨出用户上传的图片上含有猫的照片。
训练集:网页抓取,专业处理,分辨率高,这会导致训练集和验证集不是同一个分布
测试集:用户随机拍的,模糊,分辨率低

需要注意:验证集和测试集的数据来自同一分布。

  1. 偏差/方差

深度学习的误差很少权衡偏差和方差,总是分别考虑:

high bias:第1种情况,如果给这个数据集拟合一条直线,可能得到一个逻辑回归拟合,但并不能很好的拟合该数据集,即偏差高,为“欠拟合”。

high variance:第3种情况,如果拟合了一个很复杂的分类器,比如用了深度神经网络,可能很好的把数据即分类了,但是这种分类器方差较高,数据过度拟合。

**just right:**第2种情况,复杂度适中,数据拟合适度,称为适度拟合。

这里写图片描述

理解偏差和误差还可以通过训练集误差和验证集误差来评判:

**情况1:**假设训练集误差为 1%,验证集误差为11%,训练集设置较好,而验证集设置较差,过度拟合了训练集,高方差。

**情况2:**训练集误差为15%,而验证集误差为16%,而人的错误率几乎为0%,这个数据拟合不高,则为欠拟合,即偏差高。

**情况3:**训练集误差为15%,而验证集误差则更大,为30%,这种情况下,算法偏差高,方差也高。

**情况4:**训练集误差为0.5%,验证集误差为1%,偏差和方差都很低。

以上情况都是基于最优误差为0%(即基本误差很小)和训练集、验证数据来自同一分布前提下的。但是如果一张图片很模糊,人眼分辨误差为15%,那最后我们判断的思路就要换一下了。

这里写图片描述

算法偏差过高——选择新的算法,比如含有更多隐层或者隐藏单元的网格(解决掉偏差问题是最基础的,如果网络够大,通常可以很好的拟合训练集)—— 检查方差有没有问题(如果方差太大,搜集更多的数据)——直至找到一个偏差和方差都很小的框架

在深度学习中,可以通过构建大的神经网络减小偏差而不影响方差,可以通过大量的数据减小方差而不影响误差,所以不用去权衡方差与偏差的关系。

3.L2正则表达式正则化(Regularization)

如果怀疑神经网络过度拟合了数据,即存在高方差问题,那么最先想到的方法可能是正则化或者准备更多的数据。

m i n w , b J ( w , b ) \underset{w,b}{min}J(w,b) w,bminJ(w,b) (通过优化w,b来减少代价函数)

具体一点,我们有:

J ( w , b ) = 1 m ∑ i = 1 m L ( y ∧ ( i ) , y ( i ) ) + λ 2 m ∥ w ∥ 2 2 J(w,b)=\frac{1}{m}\sum_{i=1}^{m}L(\overset{\wedge}{y}^{(i)},y^{(i)})+\frac{\lambda }{2m}\left \| w \right \|^{2}_{2} J(w,b)=m1i=1mL(y(i),y(i))+2mλw22

其中,m代表的是样本的数量, λ \lambda λ是正则化参数(这也是一个超级参数), ∥ w ∥ 2 2 = ∑ j = 1 n x w j 2 = w T w \left \| w \right \|^{2}_{2} = \sum_{j=1}^{n_{x}} w_{j}^{2}=w^{T}w w22=j=1nxwj2=wTw,这个称为L2正则表达式,只加w而不加a是因为w通常是一个高维参数矢量,已经可以表达高偏差问题了,w里有很多参数,基本上涵盖了所有参数,而不是b。

当然也有L1 表达式(regularization),可直接将 ∣ ∣ w ∣ ∣ 2 2 ||w || _{2}^{2} w22换成||w||,公式为 ∣ ∣ w ∣ ∣ 1 = ∑ j = 1 n x w j ||w || _{1}= \sum_{j=1}^{n_{x}} w_{j} w1=j=1nxwj

如果使用使用L1 正则表达式,则W会是个稀疏矩阵,即W向量中有很多0,尽管变稀疏了,但是却没有压缩内存,所以在训练模型的时候,更多的是使用L2正则化。

对于神经网络而言, J ( w [ 1 ] , b [ 1 ] , . . . , w l ] , b [ l ] ) = 1 m ∑ i = 1 m L ( y ∧ ( i ) , y l ) = λ 2 m ∑ l = 1 L ∣ ∣ w l ∣ ∣ F 2 J(w^{[1]},b^{[1]},...,w^{l]},b^{[l]})=\frac{1}{m}\sum_{i=1}^{m}L(\overset{\wedge}{y}^{(i)},y^{l})=\frac{\lambda}{2m}\sum_{l=1}^{L}||w^{l}||_{F}^{2} J(w[1],b[1],...,wl],b[l])=m1i=1mL(y(i),yl)=2mλl=1LwlF2

其中, w : ( n [ l − 1 ] , n [ l ] ) w:(n^{[l-1]},n^{[l]}) w:(n[l1],n[l]),这里l-1指的是隐藏单元的数量(我觉得这里是指下一层隐含层),n[l]表示l层单元的数量, ∣ ∣ w l ∣ ∣ F 2 = ∑ i = 1 n [ l − 1 ] ∑ j = 1 n [ l ] ( w i j [ l ] ) 2 ||w^{l}||_{F}^{2}=\sum_{i=1}^{n^{[l-1]}}\sum_{j=1}^{n^{[l]}}(w_{ij}^{[l]})^{2} wlF2=i=1n[l1]j=1n[l](wij[l])2,这里是指的该矩阵范数被称作“费罗 贝尼乌斯范数”,即矩阵每个元素的平方和。

正则化表达式主要是通过设置 λ \lambda λ来降低w的权重,从而实现对过拟合的调整

这里写图片描述

通过L2调整的方式:
对于矩阵W的导数,我们有dW[l]=(from back propagation)+ λ m W [ l ] \frac{\lambda}{m} W^{[l]} mλW[l]
则对于新的更新迭代的下一轮W,我们有
W [ l ] : = W [ l ] − α d W [ l ] W^{[l]}:=W^{[l]}-\alpha dW^{[l]} W[l]:=W[l]αdW[l]

则有 W [ l ] : = W [ l ] − α λ m W [ l ] − α ( f r o m b a c k p r o p a g a t i o n ) W^{[l]} :=W^{[l]}-\alpha \frac{\lambda}{m} W^{[l]}-\alpha (from back propagation) W[l]:=W[l]αmλW[l]α(frombackpropagation)

由于在梯度下降的时候,权重系数乘了一个比1小的系数,所以在每次迭代更新的时候,都会使得W这个权重变小,在不断迭代的过程中对权重进行衰减,所以也成为“权重衰减”。因为相应的把权重W给降低了,则输出的z=Wx+b 较小,如果是tanh函数,那么在接近0的时候呈线性,而不是复杂的非线性高方差拟合。

Python代码实现:

如何在代价函数的基础上增加惩罚项(forward propagation):

def compute_cost_with_regularization(A3,Y,parameters,lambd):
    
    ''''  
    Arguments:A3-post-activation,output of forward propagation,of shape
    Y-"true" labels vector,of shape
    parameters-python dictionary containing parameters of the model
    lambd-hyper paramter lambd是超参数
    Returns:
    cost-vaule of the regularized loss function
    
    '''' 
    m=Y.shape[1]   # if Y is the matrix 1 by m,and then Y.shape[1] is equal to m 
    W1=parameters["W1"]  #这里假设是3层神经网络,这里为第一层的权重
    W2=parameters["W2"] 
    W3=parameters["W3"]
    
    cross_entropy_cost=compute_cost(A3,Y) #This gives you the cross-enteropy part of the cost,假设已经计算出了代价函数 
    
    L2_regularization_cost = (1/m)*(lambd/w)*(np.sum(np.square(W1))+np.sum(np.square(W2))+np.sum(np.square(W3)))  #惩罚项,L2范数
    
    cost function = cross_entropy_cost+L2_regularization_cost
    
    return cost 

Back propagation(反向传播):

def backward_propogation_with_regularization(X,Y,cache,lambd):
    ''''
    X-input dataset,of shape(input size,number of examples)
    Y-"true"label vector,of shape(output size,number of example)
    cache-cache output from forward_propagation()
    lambd-regularization hyperparameter,scalar 
    
    Returns:
    gradients-A dictionary with the gradients with respect to each parameter,activation and pre-activation variables
    
    ''''
    m=X.shape[1]  
    (Z1,A1,W1,b1,Z2,A2,W2,b2,Z3,A3,W3,b3)=cache
    
    dZ3=A3-Y
    dW3=1./m*np.dot(dZ3,A2.T)+(lambd/m)*W3
    db3=1./m*np.sum(dZ3,axis=1,keepdims=True)
    
    dA2=np.dot(W3.T,dZ3)
    dZ2=np.multiply(dA2,np.int64(A2>0)#对激活函数进行求导,multiply是对应值相乘,这里应该是ReLU函数
    dW2=1./m*np.dot(dZ2,A1.T)+(lambd/m)*W2
    db2=1./m*np.sum(dZ2,axis=1,keepdims=True)
    
    dA1=np.dot(W2.T,dZ2)
    dZ1=np.multiply(dA1,np.int64(A1>0))
    dW1=1./m*np.dot(dZ1,A1.T)+(lambd/m)*W1
    db1=1./m*np.sum(dZ1,axis=1,keepdims=True)
    
    gradients={"dZ3":dZ3,"dW3":dW3,"db3:":db3,"dZ2":dZ3,"dW2":dW3,"db2:":db3,"dZ1":dZ1,"dW1":dW1,"db1:":db1}  #创建梯度下降的字典
    
    return gradients

4.Dropout 正则化

当我们训练以下的神经网络的时候,出现了过拟合,dropout 会遍历网络的每一层,并设置消除神经网络中节点的概率,假设网络中的每个节点都以抛硬币的方式设置概率,保留和消除的概率都是0.5,设置完节点概率后,就会消除一些节点,然后用back propagation进行训练。

这里写图片描述

反向随机失活(inverted dropout)
处于完整性来考虑,我们用一个三层(l=3)网络来举例说明,说明如何在某一层中实施dropout,首先要定义向量d,d3表示一个三层的
dropout 向量,看是否d3=np.random.rand(a3.shape[0],a3.shape[1]) (创建一个维数与a3相同的矩阵)<keep-prob(是个数字,上个示例中它是0.5,本例中设为0.8,表示保存某个隐藏单元的概率,则消除任意一个隐藏单元的概率为0.2)

d3=np.random.rand(a3.shape[0],a3.shape[1])  #d3是一个布尔数组
a3=np.multiply(a3,d3)   将矩阵d3和a3矩阵对应元素相乘,作用是过滤掉d3中所有等于0的元素
a3 /= keep-prob #当我们删除a3中一些神经元的时候,为了使得z^[4]=w^[4]a^[3]+b^[4],那么我们需要修正或者弥补我们所需的那20%,从而使得a3的期望值不会改变,只是减少了网络的节点。

这里写图片描述

5.其他正则化方法

扩充(augment)训练数据来解决过拟合
如图,可以通过水平翻转、剪裁图片来增加训练集,虽然数据没那么多,
但是减少了扩张数据的代价。对于数字,还可以通过扭曲来增加训练集。

这里写图片描述

6.正则化输入

归一化输入需要俩个步骤:1.零均值化 (就是把数据集的散点移动到坐标轴附近,1图到2图) 2.归一化方差(下图的x1的方差比x2的方差要大得多,2图到3图,x1和x2的方差都为1)
这里写图片描述

如果需要用方差和均值来调整训练集数据,那么需要用相同的u和 σ 2 \sigma^{2} σ2来归一化测试集,而不是在训练集和测试集上分别预估u和 σ 2 \sigma^{2} σ2,因为我们希望的是,训练集和测试集都是通过相同u和 σ 2 \sigma^{2} σ2定义的相同数据转换,其中u和 σ 2 \sigma^{2} σ2是由训练集数据计算得来的。

为什么要归一化输入特征?
如下图,代价函数归一化之前和之后,归一化前,狭长型,归一化后,均匀许多。如果在归一化之前的图进行梯度下降,那么学习率需要很小,狭长型的那边需要迭代很多次。如果在归一化之后的,学习率和迭代步长可以较大,迭代次数也可以变小。

这里写图片描述

如果输入的特征取值范围相差很大,那么归一化起重要作用。如果相差不大,那么归一化特征就不是很重要了。

7.梯度消失和梯度爆炸

也就是说,当训练深度网络时,导数或坡度有时候会变得非常大。举个例子,假如我们有l层神经网络,输入特征为x[x1,x2],权重为 w [ l ] w^{[l]} w[l],设 b [ l ] b^{[l]} b[l]=0,激活函数g(z)=z,则有:

y ∧ = w [ l ] w [ l − 1 ] ⋯ w 1 x \overset{\wedge}{y}=w^{[l]}w^{[l-1]}\cdots w^{1}x y=w[l]w[l1]w1x

设权重 w [ l ] = [ 1.5 0 0 1.5 ] w^{[l]}=\begin{bmatrix} 1.5 &amp; 0 \\ 0 &amp; 1.5 \end{bmatrix} w[l]=[1.5001.5] >0(1.5倍个单位矩阵),则
y ∧ = 1. 5 l x \overset{\wedge}{y}=1.5^{l}x y=1.5lx,直接呈爆炸性增长,若w<1,则为爆炸性递减。

8.神经网络的权重初始化

先举一个神经元初始化的例子,单个神经元可能有4个输入特征,从X1到X4,经过激活函数a=g(z),最终得到 y ∧ \overset{\wedge}{y} y,则得到: z = w 1 x 1 + w 2 x 2 + ⋯ + w n x n z=w_{1}x_{1}+w_{2}x_{2}+\cdots +w_{n}x_{n} z=w1x1+w2x2++wnxn,为了预防z值过大或者过小,当n越大的时候,我们希望的是w[i]越小,最合理的方法就是设置w[i]=1/n (n为神经元的输入特征数量)

则有公式: W [ l ] = n p . r a n d o m . r a n d n ( s h a p e ) ∗ n p . s q r t ( 1 / n [ l − 1 ] ) W^{[l]}=np.random.randn(shape)*np.sqrt(1/n^{[l-1]}) W[l]=np.random.randn(shape)np.sqrt(1/n[l1])

其中W为l层的权重矩阵,shape为矩阵的维数,其中sqrt表示平方根

对于其他变体函数,针对不同激活函数而言:
1.对于tanh 激活函数,则乘以 1 n l − 1 \sqrt{\frac{1}{n^{l-1}}} nl11 ,被称为Xavier 初始化,有些作者也习惯使用 2 n [ l − 1 ] + n [ l ] \sqrt{\frac{2}{n^{[l-1]}+n^{[l]}}} n[l1]+n[l]2

2.对于ReLU 激活函数(最常用),则乘以 2 n l − 1 \sqrt{\frac{2}{n^{l-1}}} nl12

9.梯度的数值逼近

在实施back propagation时,有一个测试叫作梯度检验,它的作用是确保backpropagation正确实施,需要逐渐实现梯度检验。

假设有一个函数为 f ( θ ) = θ 3 f(\theta)=\theta^{3} f(θ)=θ3,在 θ \theta θ右边取 θ + ε \theta+\varepsilon θ+ε,在左边取 θ − ε \theta-\varepsilon θε,设取值分别为1,1.01,0.99,则 ε = 0.01 \varepsilon =0.01 ε=0.01,如下图:
这里写图片描述

上图可得,较大的三角形的高比值更接近于 ε \varepsilon ε 的导数,得到的是一个双边公差,期望值为:

3 θ 2 = g ( θ ) ≈ f ( θ + ε ) − f ( θ + ε ) 2 ε 3\theta^{2}=g(\theta)\approx \frac{f(\theta+\varepsilon )-f(\theta+\varepsilon )}{2\varepsilon } 3θ2=g(θ)2εf(θ+ε)f(θ+ε) (可自行代入数据感受下)

如果只考虑到单边误差,即 f ( θ + ε ) − f ( θ ) ε \frac{f(\theta+\varepsilon )-f(\theta )}{\varepsilon } εf(θ+ε)f(θ) 或者 f ( θ ) − f ( θ − ε ) ε \frac{f(\theta)-f(\theta-\varepsilon)}{\varepsilon } εf(θ)f(θε),误差会更大。

所以,用双边误差的方法更逼近导数,更加精确。
这里写图片描述

10.梯度检验

假如有 W [ 1 ] , b [ 1 ] , ⋯ &ThinSpace; , W [ l ] , b [ l ] W^{[1]},b^{[1]},\cdots ,W^{[l]},b^{[l]} W[1],b[1],,W[l],b[l],把所有的W矩阵都换成向量之后,做连接运算(得到一个巨型向量 θ \theta θ

紧接着,我们有
d W [ 1 ] , d b [ 1 ] , ⋯ &ThinSpace; , d W [ 1 ] , d b [ l ] dW^{[1]},db^{[1]},\cdots,dW^{[1]},db^{[l]} dW[1],db[1],,dW[1],db[l],用来初始化大向量 d θ d\theta dθ

J ( θ ) = J ( θ 1 , θ 2 , ⋯ &ThinSpace; , θ n ) J(\theta)=J(\theta_{1},\theta_{2},\cdots,\theta_{n}) J(θ)=J(θ1,θ2,,θn)

则我们有:

∂ J ( θ ) ∂ θ 1 = J ( θ 1 + ε , θ 2 , ⋯ &ThinSpace; , θ n ) − J ( θ 1 − ε , θ 2 , ⋯ &ThinSpace; , θ n ) 2 ε \frac{\partial J(\theta)}{\partial \theta _{1}}=\frac{J(\theta_{1}+\varepsilon,\theta_{2},\cdots,\theta_{n})-J(\theta_{1}-\varepsilon,\theta_{2},\cdots,\theta_{n})}{2\varepsilon } θ1J(θ)=2εJ(θ1+ε,θ2,,θn)J(θ1ε,θ2,,θn)
⋮ \vdots
∂ J ( θ ) ∂ θ n = J ( θ 1 , θ 2 , ⋯ &ThinSpace; , θ n + ε ) − J ( θ 1 , θ 2 , ⋯ &ThinSpace; , θ n − ε ) 2 ε \frac{\partial J(\theta)}{\partial\theta _{n}}=\frac{J(\theta_{1},\theta_{2},\cdots,\theta_{n}+\varepsilon)-J(\theta_{1},\theta_{2},\cdots,\theta_{n}-\varepsilon)}{2\varepsilon } θnJ(θ)=2εJ(θ1,θ2,,θn+ε)J(θ1,θ2,,θnε)

上面求出的 ∂ J ( θ ) ∂ θ n \frac{\partial J(\theta)}{\partial\theta _{n}} θnJ(θ)只是近似值,我们要判断的就是这个近似值 ∂ J ( θ ) ∂ θ n \frac{\partial J(\theta)}{\partial\theta _{n}} θnJ(θ) ∂ J ( θ ) ∂ θ n t r u e \frac{\partial J(\theta)}{\partial\theta _{n}}_{true} θnJ(θ)true 真实值是否等同,则我们只需要检验其向量的差值:

∣ ∣ ∂ J ( θ ) ∂ θ n − ∂ J ( θ ) ∂ θ n t r u e ∣ ∣ 2 ||\frac{\partial J(\theta)}{\partial\theta _{n}}-\frac{\partial J(\theta)}{\partial\theta _{n}}_{true}||_{2} θnJ(θ)θnJ(θ)true2 再除以俩者的和

如果我们的 ε \varepsilon ε 取值是10(-7),当求出来的距离是10(-5)或者10^(-3),那么就要小心了,可能程序有bug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值