Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization
Continenet :
- Setting up your Machine Learning Application
- Regularizing your Neural Network
- Setting up you optimization problem
1. Train/dev/test set
- 可能来自不同数据,但是要保证训练集和测试集处于同样的分布
test set是为了做无偏估计。 - 当你不需要做无偏估计的时候也可以不使用test set
2. Training Set Error & Dev Error
- 由二者判断模型是high bias or variance.(跟问题的最优误差比较 Bayes error)
3. Basic Recipe for Machine Learning
- 机器学习的一般流程:
高偏差:bigger network,train longer,NN archetechture
高方差:更多的数据,regularization正则化,NN archetechture
4.Overfitting 解决过拟合
4.1.Regularization
- Logistic Regression
fing w,b to minimize J(w,b):
J(w,b)=1m∑i=1mL(ŷ (i),y(i))+λ2m||w||x
L2 regularization: ||w||22=∑w2i
L1 regularization: ||w||1=∑|wi| - NN
J(w,b)=1m∑i=1mL(ŷ (i),y(i))+λ2m∑l=1L||w[l]||2F
Frobenius Norm: ||w[l]||2F=∑j=1∑i=1w[l]2i,j
weight decay: dw[l]=(fromBP)+λmw[l]
4.2.Why Regularization
- 使得多个w接近于零,减小网络复杂度
- 使得每个Z接近于零,由于激活函数在z接近于零时是线性的,所以整个网络趋向于线性
4.3.Dropout 随机失活
- Inverted dropout:not for testing
d3 = np.random.rand(a3.shape[0],a3.shape[1])<keep_prob#保存的概率
a3 = np.multiply(a3,d3)#过滤
a3 /=keep_prob#确保a3期望值不变
- 损失函数波动很大,可以关闭drop out运行代码,debug之后再打开drop out
4.4.Data Augmentation 数据扩展
- 图片镜像,翻转,扭曲,剪裁…
4.5.Early Stopping
- 画train/dev的损失曲线,在dev的损失开始上升时停止
- 缺点:减小偏差和减小方差两个过程是耦合的(非正交),难以单独调试
5.Gradient checking 梯度检验
dθ[i]approx=J(θ1,θ2...θi+ϵ,...)−J(θ1,θ2...θi−ϵ,...)2ϵ
check
||dθappro−dθ||2||dθappro||2+||dθ||2<10−5only deubg,不要再在训练的时候使用
- 若代价函数中使用了正则化,则gradient cheking时也要使用正则化的J
- 不要于drop out同时使用
6.Speeding Up 加速训练
6.1.Normalize Input正则化输入
- x=x−μσ2
- 对于dev要使用与training set同样的 μ , σ
6.2. 权重初始化
- 改善梯度消失和梯度爆炸问题
- 权重初始化后保证输入零均值,标准方差为1
- Relu: w[l]=np.random.randn(shape)∗(2n[l−1]‾‾‾‾‾‾‾√)
- tanh(Xavier Initilization):
w[l]=np.random.randn(shape)∗(1n[l−1]‾‾‾‾‾‾‾√)
6.3. mini-batch gradient descent
- 将很大的数据随机分为几个batch size,与历遍整个数据后更新一次相比,mini-batch是历遍一个mini batch size的数据后更新一步
6.4. 加速优化算法
6.4.1 指数加权平均 Exponentially weighted averages (移动平均)
- 已知去年每天的温度,对今年温度进行预测
- v0=0,v1=0.9v0+0.1θ1,vt=βvt−1+(1−β)θt
- vt=βvt+β(1−β)vt−1+β(1−β)2vt−2...+β(1−β)t−1v1) 所有系数加起来接近于1
- θ1 是去年今天的温度
- β 越大,越平缓
- vt≈过去11−β天的平均温度
- β=0.9:≈过去10天的平均温度
- β=0.98:≈过去50天的平均温度
6.4.2 偏差修正 bias correction
- 在指数加权平均的基础上 vt=vt1−βt
- 对初期数据修正比较大
6.4.3 Gradient Descent with Momentum 动量梯度下降算法
- 计算梯度的指数加权平均数,再用加权后的梯度更新变量
- Momentum
on iteration t:
- compute dw,db on the current mini-batch
-
vdw=βvdw+(1−β)dw
vdb=βvdb+(1−β)db - w=w−αvdw,b=b−αvdb
- β 通常选择0.9
- 实际使用时不需要偏差修正,因为10次迭代后初始影响就可以消除
6.4.4 RMSprop(root mean square prop)
-
sdw=β2sdw+(1−β2)dw2
sdb=β2sdb+(1−β2)db2
w=w−αdwsdw+ϵ‾‾‾‾‾‾‾√,b=b−αdbsdb+ϵ‾‾‾‾‾‾‾√,ϵ=10−8 - 可使用更大的学习速率二不容易发散
6.4.5 Adam optimization algorithm
- vdw=0,sdw=0,vdb=0,sdb=0
on iteration t:
- compute dw,db using mini-batch
vdw=β1vdw+(1−β)dw,vdb=β1vdb+(1−β1)db
sdw=β2sdw+(1−β2)dw2,sdb=β2+(1−β2)db2
vcorrecteddw=vdw/(1−βt1),vcorrecteddb=vdb/(1−βt1)
scorrecteddw=sdw/(1−βt2),scorrecteddb=sdb/(1−βt2) 偏差修正
-
w=w−αvcorrecteddw,scorrecteddw+ϵ‾‾‾‾‾‾‾‾‾‾‾√
b=b−αvcorrecteddb,scorrecteddb+ϵ‾‾‾‾‾‾‾‾‾‾‾√
- 超参数: α,β1(0.9),β2(0.999),ϵ(10−8)
6.4.6 Learning rate decay 学习速率衰减
α=11+decayrate∗epochnumber∗α0
α=0.95epochnum∗α0
α=kepochnumber‾‾‾‾‾‾‾‾‾‾‾‾√
6.4.7 .Batch Normalization
- 增加系统的鲁棒性,使神经网络对超参数的选择更加稳定,范围也更加广
- 由于每一个minibatch的方差和均值都不一样,所以增加了系统噪音,有一点正则化的效果。batch size增大的时候这种噪音会减弱
Batch Norm
Given z([l](i)) :
μ=1m∑iz(i)σ2=1m∑i(zi−μ)2
z(i)norm=z(i)−μσ2+ϵ‾‾‾‾‾‾√ 对 z[l] 的每一列进行归一化
ẑ (i)=γz(i)norm+β
γβ 也是要每步更新的- 对于测试集,使用训练集的均值和方差进行归一化
7.Local optimum局部最优解
- 高纬度空间并不太可能出现局部最优解,更多的是鞍点。对于鞍点,系统可以自动克服。
8.Tuning process 调参过程
- Hyperparameters:
α
β,hidden_units,mmini_batchsize,
layers,learning_rate_decay
β1,β2,ϵ - Try random values: don’t use a grid
- 在表现很好的多组超参数范围内重新密集的随机取点,选择更好的超参数
9.Softmax Classifier
- t=ez[l] ,c分类的话t有c个分量
输出每个种类的可能性 a[l]=t∑j=1ti
损失的度量 L(ŷ ,y)=−∑cj=iyjlogŷ j
损失函数 J=1m∑mi=1L(ŷ ,y)
10.Deep Learning frameworls
- kears
- pytorch
- tensorflow
#求使得cost最小的w
import tensroflow as tf
w = tf.Variable(0,dtype=tf.float)
cost = tf.add(tf.add(w**2,tf.multiply(-10,w)),25)
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
print(session.run(w))
#迭代一次
session.run(train)
print(session.run(w))
#迭代1000次
for i in range(1000):
session.run(train)
print(session.run(w))