2018年9月版本
Week 5
训练/开发/测试数据集 Train / Dev / Test
-
提高模型设计的迭代效率
-
使用训练集训练模型
-
使用开发集测试模型,查看哪一个模型或算法在开发集上表现最好
-
用测试集进行最终的结果评估,避免开发时使用测试集造成偏差
-
由于开发集和测试集的基本目的在于快速的得出结论,在大数据时代,这二者在整个数据集中占有的比重就应当非常小了,因此合理的分割比例应该大致为98:1:1(百万级数据)
-
应当确保后二者的数据分布基本相同
-
在不需要无偏估计的情况下,没有测试集也是被允许的,这个时候就是在进行模型或算法的性能比较等等
偏差和方差 Bias & Variance
- 高偏差(High Bias),导致数据无法很好地被拟合,称为欠拟合
- 高方差(High Variance),导致数据被过分拟合,称为过拟合
- 人工对数据集的处理误差,称为理想误差(optimal error)或者贝叶斯误差(Bayes Error)
- 对于一个模型,评定其能力有两个误差:
- 训练集误差可以判断该模型是否发生高偏差
- 开发集误差(和训练集误差相比较)可以判断该模型是否发生高方差
机器学习的基本原则 Basic Recipe for ML
-
算法是否有高偏差(训练集表现):尝试一个更大的网络,延长训练时间,尝试更好的架构
-
算法是否有高方差(开发集表现):取得更多数据,正则化,寻找更好的架构
-
对深度学习,可以使用分别单独降低偏差和方差的方法,而不必担心二者之间的平衡关系,在监督学习中表现优异
正则化 Regularization
- 有助于防止数据过拟合
- 逻辑回归 J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∣ ∣ w ∣ ∣ 2 2 ∣ ∣ w ∣ ∣ 2 2 = ∑ j = 1 n x w j 2 = w T w ( 欧 几 里 得 范 数 ) J(w,b)=\frac{1}{m}\sum\limits_{i=1}^{m}L(\hat y^{(i)}, y^{(i)})+\frac{\lambda}{2m}||w||_2^2 \quad ||w||_2^2=\sum\limits_{j=1}^{n_x}w_j^2=w^Tw(欧几里得范数) J(w,b)=m1i=1∑mL(y^(i),y(i))+2mλ∣∣w∣∣22∣∣w∣∣22=j=1∑nxwj2=wTw(欧几里得范数)
- 上述内容称之为L2正则化(因为使用了w的L2范数)
- 还有一种L1正则化,即使用L1范数,有正则化项 λ m ∑ j = 1 n x ∣ w j ∣ = λ m ∣ ∣ w ∣ ∣ 1 \frac{\lambda}{m}\sum\limits_{j=1}^{n_x}|w_j|=\frac{\lambda}{m}||w||_1 mλj=1∑nx∣wj∣=mλ∣∣w∣∣1
- 使用L1正则化,会导致权重矩阵变得稀疏
- λ称为正则化系数,应挑选最佳的系数,保持参数的L2范数较小以避免过拟合
- 神经网络 J ( W [ 1 ] , b [ 1 ] , W [ 2 ] , b [ 2 ] , … , W [ l ] , b [ l ] ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ l = 1 L ∣ ∣ W [ l ] ∣ ∣ F 2 J(W^{[1]},b^{[1]},W^{[2]},b^{[2]},\ldots,W^{[l]},b^{[l]})=\frac{1}{m}\sum\limits_{i=1}^{m}L(\hat y^{(i)},y^{(i)})+\frac{\lambda}{2m}\sum\limits_{l=1}^{L}||W^{[l]}||^2_F J(W[1],b[1],W[2],b[2],…,W[l],b[l])=m1i=1∑mL(y^(i),y(i))+2mλl=1∑L∣∣W[l]∣∣F2
- ∣ ∣ W [ l ] ∣ ∣ 2 = ∑ i = 1 n [ l ] ∑ j = 1 n [ l − 1 ] ( w i j [ l ] ) 2 ||W^{[l]}||^2=\sum\limits_{i=1}^{n^{[l]}}\sum\limits_{j=1}^{n^{[l-1]}}(w^{[l]}_{ij})^2 ∣∣W[l]∣∣2=i=1∑n[l]j=1∑n[l−1](wij[l])2,称之为弗罗贝尼乌斯范数(Frobenius Norm)
- L2正则化又称权重衰减(其效果会让权重变小一些)
- 当正则化系数较大时,会使得整个权重变得很小,因此整个网络产生的结果更加倾向于线性回归,因此更加不容易过拟合
随机失活正则化 Dropout Regularization
- 每一个实例进入网络,针对每一层设置的随机概率值,使该层的该概率下的一部分节点失活,从而每一个实例作为输入时训练的都是不一样的,比原始网络更小的一个模型
- 实现方法:反向随机失活(Inverted Dropout)
- 生成随机矩阵,要求随机值小于该层的keep-prob(每个节点有keep-prob几率被保留),取值0或1
- (以三层网络为例)有随机矩阵 d 3 = n p . r a n d o m . r a n d ( a 3. s h a p e [ 0 ] , a 3. s h a p e [ 1 ] ) < k e e p _ p r o b d3=np.random.rand(a3.shape[0],a3.shape[1])<keep\_prob d3=np.random.rand(a3.shape[0],a3.shape[1])<keep_prob
- a 3 = n p . n u l t i p l y ( a 3 , d 3 ) a3 = np.nultiply(a3,d3) a3=np.nultiply(a3,d3)
- a 3 / = k e e p _ p r o b a3 /= keep\_prob a3/=keep_prob放大a3以消除削减节点造成的值的减少(稳定期望不变)
- 上一步简化了神经网络的测试部分,因为其减少了可能引入的缩放问题
- 测试阶段进行预测
- 测试时不要使用dropout,否则会增加噪声
- 也可以多次随机失活取均值
- 测试过程中不需要额外的缩放参数
- dropout的基本思路:不依赖于某一个特征,确保整体效果,保证影响传播到尽可能多的权重点
- 和L2类似,dropout可以用于收缩权值和防止过拟合
- 方案1:对于容易发生过拟合的层,采用更小的留存率(有较多的超参数)
- 方案2:对于一部分层使用相同留存率的dropout,一些层完全不使用
- 缺点:使J变得不明确
其他正则化方法
- 数据增强(Data Augmentation):扩增数据集,可以从既有数据集本身进行修改生成新的数据集
- 早终止法(Early Stopping):分别画出梯度下降和开发集误差两条线,然后寻找最佳的状态点,即最小的开发集误差值(提前终止训练而不是等到J收敛),缺点是无法分开解决“最优化J”和“防止过拟合”这两个问题,使整个问题变得十分复杂
输入归一化 Normalizing Inputs
- 减去均值 μ = 1 m ∑ i = 1 m x ( i ) x : = x − μ \mu = \frac{1}{m}\sum\limits_{i=1}^{m}x^{(i)} \quad x:=x-\mu μ=m1i=1∑mx(i)x:=x−μ
- 归一化 σ 2 = 1 m ∑ i = 1 m x ( i ) 2 x : = x σ 2 \sigma^2=\frac{1}{m}\sum\limits_{i=1}^{m}x^{(i)2} \quad x:=\frac{x}{\sigma^2} σ2=m1i=1∑mx(i)2x:=σ2x
- 需要对训练集和测试集使用同样的均值和方差
- 让各个特征的数值分布更加均匀,有利于梯度下降过程
梯度消失和梯度爆炸 Vanishing / Exploding Gradients
- 在训练深度较大的网络时,可能会出现代价函数的导数变得非常小或者非常大的情况
- 对于一个很深的网络,略大于1的权重可能造成结果指数级的增长,而略小于1的权重可能造成结果指数级的减小
深度网络的权重初始化 Weight Initialization
- 随着特征数量增加,我们更加希望权重更小,使得加和结果不会变得特别大
- 初始化时,让 w i = 1 / n w_i=1/n wi=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(\frac{1}{n^{[l-1]}}) W[l]=np.random.randn(shape)∗np.sqrt(n[l−1]1)
- 对使用ReLU的层,使用2/n效果更好
- Xavier方法:对tanh函数,使用 1 n [ l − 1 ] \sqrt{\frac{1}{n^{[l-1]}}} n[l−1]1
- Yoshua Bengio方法,使用 2 n [ l − 1 ] + n [ l ] \sqrt{\frac{2}{n^{[l-1]}+n^{[l]}}} n[l−1]+n[l]2
梯度检查 Gradient Checking
数值计算梯度
- 双侧差值求近似导数 f ( x + ϵ ) − f ( x − ϵ ) 2 ϵ \frac{f(x+\epsilon)-f(x-\epsilon)}{2\epsilon} 2ϵf(x+ϵ)−f(x−ϵ)
梯度检查
- 将所有的参数 W [ 1 ] , b [ 1 ] , W [ 2 ] , b [ 2 ] , … , W [ l ] , b [ l ] W^{[1]},b^{[1]},W^{[2]},b^{[2]},\ldots,W^{[l]},b^{[l]} W[1],b[1],W[2],b[2],…,W[l],b[l]拼成一个巨大的参数向量θ
- 同理,将所有的导数值 d W [ 1 ] , d b [ 1 ] , d W [ 2 ] , d b [ 2 ] , … , d W [ l ] , d b [ l ] dW^{[1]},db^{[1]},dW^{[2]},db^{[2]},\ldots,dW^{[l]},db^{[l]} dW[1],db[1],dW[2],db[2],…,dW[l],db[l]拼成一个巨大的导数值向量dθ
- 验证问题:
d
θ
是
不
是
J
(
θ
)
的
导
数
d\theta是不是J(\theta)的导数
dθ是不是J(θ)的导数
- 对θ的每一个i分量
θ
i
\theta_i
θi:
- d θ a p p r o x [ i ] = J ( θ 1 , θ 2 , … , θ i + ϵ , l d o t s ) − J ( θ 1 , θ 2 , … , θ i − ϵ , l d o t s ) 2 ϵ d\theta_{approx}[i]=\frac{J(\theta_1,\theta_2,\ldots,\theta_i+\epsilon,ldots)-J(\theta_1,\theta_2,\ldots,\theta_i-\epsilon,ldots)}{2\epsilon} dθapprox[i]=2ϵJ(θ1,θ2,…,θi+ϵ,ldots)−J(θ1,θ2,…,θi−ϵ,ldots)
- 应当有 d θ a p p r o x [ i ] ≈ d θ [ i ] d\theta_{approx}[i] \approx d\theta[i] dθapprox[i]≈dθ[i]
- 检查欧式距离 ∣ ∣ d θ a p p r o x − d θ ∣ ∣ 2 ∣ ∣ d θ a p p r o x ∣ ∣ 2 + ∣ ∣ d θ ∣ ∣ 2 \frac{||d\theta_{approx}-d\theta||_2}{||d\theta_{approx}||_2+||d\theta||_2} ∣∣dθapprox∣∣2+∣∣dθ∣∣2∣∣dθapprox−dθ∣∣2是否不超过ε的数量级
- 对θ的每一个i分量
θ
i
\theta_i
θi:
使用注意
- 不要在训练中使用,只用于调试
- 出现问题时,检查究竟是哪一个分量出了问题(相差极大)
- 注意在求梯度时进行正则化
- 不可以用于随机失活法(先关闭dropout,检查确认无误后再打开)
- 可能存在一种情况,即随着梯度下降,w和b的值可能会变大,导致梯度下降算法精确度出问题,因此应在在初始化时检查,在运行一段时间后再进行检查