第五课 深度学习的实践层面
1.1 训练、验证、测试集(Train/Dev/Test sets)
总结一下,在机器学习中,我们通常将样本分成训练集(60%),验证集(20%)和测试集(20%)三部分,数据集规模相对较小,适用传统的划分比例,数据集规模较大的,验证集和测试集要小于数据总量的 20%或 10%.若两类数据不同(例如一个是网页抓取到的数据图片,一个是现实中的测试集和验证集),但要确保验证集和测试集的数据来自同一分布。
通常没有测试集也不要紧
1.2 偏差,方差(Bias/Variance)
高偏差:欠拟合
高方差:过拟合
如下图所示,图1为高偏差,图3为高方差
解释上图:对于训练集误差和测试集误差:
高方差 | 高偏差 | 高方差&高偏差 | 低方差&低偏差 | |
---|---|---|---|---|
训练集误差 | 1% | 15% | 15% | 0.5% |
验证集误差 | 11% | 16% | 30% | 1% |
通过上图,我们可以根据训练集算法产生的误差和验证集上验证算法产生的误差来确定算法是否存在高偏差或者高方差,进而根据算法的偏差和方差情况来进行一些工作。
1.3 机器学习基础
解决高方差(过拟合)问题:
1.获得更多的训练样本
2.减少特征的数量
3.尝试增加正则化程度$\lambda$
解决高偏差(欠拟合)问题:
1.增加特征的数量
2.增加多项式特征
3.减少正则化程度$\lambda$
1.4 正则化(Regularization)
正则化通常用L1正则化和L2正则化,如下:
$$ L_1正则化:\frac{\lambda}{2m}\sum_{j=1}^{n_x}|w_j|=\frac{\lambda}{2m}||w||\\ L_2正则化:\frac{\lambda}{2m}\sum_{j=1}^{n_x}|w_j|^{2}=\frac{\lambda}{2m}||w||^{2}=\frac{\lambda}{2m}w^Tw $$
逻辑回归正则化公式如下:
$$ J(w,b)=\frac{1}{m}\sum_{i=1}^{m}L(\widehat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m}||w||^{2} $$
对于神经网络的正则化公式如下:
$$ J(W^{[1]},b^{[1]},...,W^{[L]},b^{[L]})=\frac{1}{m}\sum_{i=1}^{m}L(\widehat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m}\sum_{l=1}^{L}||w||^{2}_F $$
最后的范数$||w||^{2}_F$被称为弗罗贝尼乌斯范数,用下标F标注,表示一个矩阵中所有元素的平方和。
梯度下降:
$$ W^{[l]}:=(1-\frac{\alpha\lambda}{m})W^{[l]}-\alpha(from backprop) $$
与之前的梯度相比增加了$\frac{\alpha\lambda}{m}$项,因此L2正则化有时候被称为"权重衰减"。
1.5 为什么正则化有利于防止过拟合?
对于直观解释,
$$ W^{[l]}:=(1-\frac{\alpha\lambda}{m})W^{[l]}-\alpha(from backprop)\\ Z^{[l]}=W^{[l]}a^{[l-1]}+b^{[l]} $$
如果参数$\lambda$增大,也就是增加正则化参数,根据上面式子,$W^{[l]}$会减少,进而$Z^{[l]}$会减少,如下图,对于双曲激活函数来说,响应的值就会停留在线性部分,进而就很好的改善了过拟合现象。
1.6 dropout 正则化(随机失活)
主要思路:随机消除消除某些隐藏单元节点。
反向随机失活(Inverted dropout):
用第三层(l=3)网络进行举例:
首先定义向量$d^{[3]}$表示一个第三层的dropout向量:
d3 = np.random.rand(a3.shape[0],a3.shape[1])
看其是否小于keep-prob,这里设其为0.8,它表示保留某个隐藏单元的概率。其作用是生成随机矩阵,随机矩阵中元素为1的概率是0.8,元素为0的概率是0.2.
因此我们可以得到第三层的激活函数为:
a3=np.multiply(a3,d3)或a3*=d3
这样就达到了随机消除隐层单元的目的。
对a3进一步计算:
a3/=keep-prob
反向随机失活(Inverted dropout)最后需要除以keep-prob,确保$a^{[3]}$期望值不变(这块有点疑问)。
在测试集上并不使用dropout。
1.7 理解dropout(Understanding Dropout)
dropout的缺点就是代价函数无法被定义,因此在使用中应先令keep-prob的值为1,运行代码确保代价函数单调递减之后在设置drop函数。
对于神经网络的每一层来说,根据每层的过拟合程度大小来选择合适的keep-prob,如果过拟合程度较大,则选择较小的keep-prob,相反则选择较大的。
1.8 其他正则化方法
1.数据扩增
如对原始图像进行旋转,放大,裁剪等操作后添加到新的数据集。
2.early stopping
同时绘制训练误差和验证集误差,验证集误差会有一个先下降在上升的过程,直接取验证集误差的最低点然后停止训练。
缺点:过早停止训练会停止优化代价函数$J$,使得代价函数的值可能不够小。
优点:只运行一次梯度下降就可以找出较小的$w$值,中间值和较大值而不用再尝试正则化。
1.9 归一化输入(Normalizing inputs)
加速训练神经网络的一个方法:归一化输入
分两步完成:
第一步:去中心化
$$ \mu=\frac{1}{m}\sum_{i=1}^{m}x^{(i)}\\ x^{(i)}=x^{(i)}-\mu $$
移动训练集直到完成零均值化。
第二步:归一化方差
$$ \sigma^2=\frac{1}{m}\sum_{i=1}^{m}(x^{(i)})^2\\ x^{(i)}/=\sigma^2 $$
第二步的$x^{(i)}$是第一步计算之后的。
注:如果输入特征属于不同范围,比如一些特征值处于0-1,而另外一些特征值属于1-1000,则就非常需要归一化,而对于相似范围内的特征,归一化不是十分重要。
1.10 梯度消失/梯度爆炸
当神经网络层数较多或者选择权重可能会导致梯度消失/梯度爆炸,成指数级增加或减少。
1.11 神经网络的权重初始化
通常对于权重的设置:
对于Relu激活函数,权重初始化为:
$$ w^{[l]}=np.random.randn(shape)*np.sqrt(\frac{2}{n^{[l-1]}}) $$
其中$n^{l-1}$是喂给第l层神经单元的数量。
对于tanh函数,权重初始化为:
$$ w^{[l]}=np.random.randn(shape)*np.sqrt(\frac{1}{n^{[l-1]}}) $$
也有初始化为如下公式:
$$ w^{[l]}=np.random.randn(shape)*np.sqrt(\frac{2}{n^{[l-1]}+n^{[l]}}) $$
1.12 梯度的数值逼近(Numerical approximation of gradients)
双边误差的结果更准确,可以使用双边误差来判断别人给你的函数$g(\theta)$是否正确实现了对函数$f$的偏导数。可以使用这个方法来检验反向传播是否可以正确实施。
1.13 梯度检验(Gradient checking)
个人理解大概过程:通过双边误差法计算出来$dW$和$db$与梯度下降计算出来的$dW$和$db$做比较,如果两者相差在$10^{-7}$,则说明梯度下降是正确的。若发现两者相差较大的值,则说明程序存在bug
1.14 梯度检验应用的注意事项(Gradient Checking Implementation Notes)
1.不要在训练过程中使用梯度检验,它用于调试;
2.算法的梯度检验证明如果失败,检查每一项找出bug;
3.实时梯度检验时候需要使用正则化;
4.梯度检验不能与dropout同时使用;
5.在随机初始化过程中,运行梯度下降,再训练网络。如果随机初始化值比较小,反复训练网络之后,再重新运行梯度检验。
本周结束,明天继续fire!!!