训练集:用来训练
验证集:用来找出最好模型
测试集:无偏评估算法的运行状态(没有也不要紧)
小数据时代:70%训练30%测试/60%训练20%训练20%测试
大数据时代:99%(或者更多)训练1%验证%1%测试
尽量保证验证集和测试集来自同一分布(网页抓取:牺牲了这一点来获取大量数据)
没有测试集:这时验证集常常被称作测试集
两者的平衡很少考虑
欠拟合:高偏差(训练集误差高)
过拟合:高方差(训练集误差远小于验证集)
解决高偏差:增大网络规模
解决高方差:使用更多数据、正则化
一箭双雕:更合适的神经网络框架
L2正则化:
为什么不正则化b?
w是高维向量,几乎涵盖所有参数,已经可以表达问题,但b只是一个数字。当然正则化b也没问题。
L1正则化:
会使得w变得稀疏(有很多0分量),但并没有降低太多存储内存
实际实现:
研究梯度下降迭代中W的变化,发现它总会因为正则化变得更小(λ越大这个效果越明显),此即“权重衰减”
权重减小了,消除了一些隐藏单元的影响,使得网络变简单,深度却很大。这使得状态更偏向高偏差状态
双曲正切函数中,W变小使得Z变小,从而函数接近线性部分,即网络变简单了一些
dropout(随机失活):
算法遍历网络中的的每一层,设置消除每个节点的概率,最后得到一个规模更小的网络。对于每个样本,使用的最终网络情况并不相同。
实施方法(反向随机失活,以第三层为例):
首先随机生成d向量:
d3 = np.random.rand(a3.shape[0],a3.shape[1])
然后观察它是否小于keep-prob量(表示保留一个节点的概率,这是一个多维量,不同层对应的数值并不相同),大于就丢弃(记为0),小于就保留(记为1)
将d与a相乘来传递保留信息:
a3 =np.multiply(a3,d3)
最后,向外拓展a3:
a3/=keep-prob
这是因为以上操作后,a3平均减少了1-keep-prob,我们现在为了让下一层的z4期望不变,需要作出调整。
注意在测试阶段不要使用dropout,这里我们不希望结果是随机的,因而dropout会带来干扰。
直观理解:
一些神经元被删除,而最后我们让a倍增,这相当于把对单一特征的依赖降低,而均匀地稍稍提高对所有特征的依赖,相当于减少了数据的方差,也就应对了过拟合。
注意keep-prob量:
再次强调这是多维量,对于规模大的W的层数,其值应设为更小的值,反之亦反。
dropout的缺点:
代价函数J不再被明确定义,每次迭代之后一些节点不见了,它将不再能准确评估性能。
其他减少过拟合的方法:
第一,数据扩增
如水平翻转图片、合理裁剪图片、合理扭曲图片
第二,early stopping
梯度下降过程中,绘制验证集上误差的变化图像,在它达到可以接受的极小点的时候直接停止训练。一开始初始化的W通常较小,运行过程中他会逐渐变大,early stopping让他在不在非常大的时候就停下了,一定程度上防止过拟合,但代价是J可能不够小。
第三,正交化
在之后的课程中讲解。
第一步,零均值化
第二步,归一化方差,注意x此时已经零均值化了
归一化之前,J的图像可能非常扁平狭长,梯度下降可能需要一个很小的学习率才能达到极小。而归一化后不需要,这加快了梯度下降的过程。
直观理解,W会在每一层之间累乘,在相当深的网络中,这会导致W最后接近0(梯度消失)或者无穷大(梯度爆炸)。
一般设置:
激活函数是ReLu时:
梯度检验:
有的时候不能保证反向传播的细节都是正确的,需要用双边公差代数逼近当前计算的梯度来检验一下
对于函数f(θ):
ε足够小时=严格成立,可以用这个式子来检验细节
第一步,将矩阵W转化为一个向量,与b连接,记为θ,作为J的参数。类似的得到dθ。
第二步,计算估计值
第三步,计算一个比率以进行检查
若接近10^(-7),那没有问题。若接近10^(-5),或许有问题,进行检查。若接近10^(-3),就或许有bug了。
第一,训练中不要用梯度检验,太慢了
第二,如果出了问题,要检查所有项
第三,检验时注意包含正则项
第四,不要和dropout一起使用,J的定义不明确
第五,有这样一种罕见的情况:
w和b接近0时,梯度下降的实施是正确的,而变大后越来越不准确。需要在随机初始化时建议,训练一段时间后再检验。