【深度学习 - 吴恩达】02 优化深度神经网络
本文为吴恩达 Deep Learning 笔记
深度学习的实用层面
概念
训练 / 验证 / 测试:
Training Set 训练集
Development Set 验证集
Test Set 测试集
偏差 / 方差:
Bias 偏差
Variance 方差
Underfitting 欠拟合
Overfitting 过拟合
Optimal Error / Bayes Error 理想误差 / 贝叶斯误差
-
对于猫的识别,假设理想误差为 ,则:
High Bias Low Bias & Low Variance High Variance High Bias & High Variance 训练集误差 测试集误差
机器学习的基本方法:
- 高方差 (High Variance):过拟合,增加训练样本数据,进行正则化,选择其他更复杂的神经网络模型。
- 高偏差 (High Bias):欠拟合,增加神经网络的隐藏层个数、神经元个数,延长训练时间,选择其它更复杂的神经网络模型。
正则化
正则化:
Regularization 正则化
L1 Regularization L1 正则化
L2 Regularization L2 正则化
Regularization Parameter 正则化参数
Frobenius Norm Frobenius 范数
Weight Decay 权重下降
-
对于逻辑回归:
-
L2 正则化:
-
L1 正则化:
-
其中 是超参数。
-
与 L2 正则化相比,L1 正则化得到的 更加稀疏,即很多 为零值,节约存储空间。
-
然而,L1 正则化在解决高方差 (High Variance) 方面比 L2 正则化并不更具优势。而且 L1 的在微分求导方面比较复杂,所以一般 L2 更加常用。
-
-
对于深层神经网络:
- 其中 是 Frobenius 范数。
-
由于加入了正则化项,梯度下降算法中的 计算表达式需要做如下修改:
丢弃法正则化:
Dropout Regularization 丢弃法
Inverted Dropout Technique 反向随机失活技术
- 丢弃法是指在深度学习网络的训练过程中,对于每层的神经元,按照一定的概率将其暂时从网络中丢弃。也就是说,每次训练时,每一层都有部分神经元不工作,起到简化复杂网络模型的效果,从而避免发生过拟合。
dl = np.random.rand(al.shape[0], al.shape[1]) < keep_prob # keep_prob 是要保留的神经元比例
al = np.multiply(al, dl)
al /= keep_prob # 使下一层神经元的输入值尽量保持不变
- 对于 个样本,单次迭代训练时,随机删除掉隐藏层一定数量的神经元,在删除后的剩下的神经元上正向和反向更新权重 和常数项 。
- 下一次迭代中,再恢复之前删除的神经元,重新随机删除一定数量的神经元,进行正向和反向更新 和 ,不断重复上述过程,直至迭代训练完成。
- 训练结束后,在测试和实际应用模型时,不需要进行随机删减神经元,所有的神经元都在工作。
理解丢弃法:
- 不同隐藏层的系数
keep_prob
可以不同。 - 神经元越多的隐藏层,
keep_prob
可以设置得小一些;神经元越少的隐藏层,keep_prob
可以设置的大一些。
其他正则化方法:
Data Augmentation 数据扩充
Early Stopping 早停法
- 数据增强:对已有的图片进行水平翻转、垂直翻转、任意角度旋转、缩放或扩大等。
- 早停法:一个神经网络模型随着迭代训练次数增加,训练集代价一般是单调减小的,而测试集代价先减后增。训练次数过多时,模型会对训练样本拟合的越来越好,但是对验证集拟合效果逐渐变差,即发生了过拟合。因此,可以通过训练集代价和测试集代价随着迭代次数的变化趋势,选择合适的迭代次数。
输入
标准化输入:
Normalizing 标准化
-
标准化:将原始数据减去其均值 ,再除以方差
-
训练集和测试集都要进行标准化操作。
梯度
梯度消失和梯度爆炸:
Vanishing Gradients 梯度消失
Exploding Gradients 梯度爆炸
- 当训练一个层数非常多的神经网络时,计算得到的梯度可能非常小或非常大。
神经网络的权重初始化:
-
这是改善梯度消失和梯度爆炸的一种方法。
-
如果激活函数是 :
w[l] = np.random.randn(n[l], n[l-1]) * np.sqrt(1 / n[l-1])
-
如果激活函数是 :
w[l] = np.random.randn(n[l], n[l-1]) * np.sqrt(2 / n[l-1])
-
其他初始化方法:
w[l] = np.random.randn(n[l], n[l-1]) * np.sqrt(2 / n[l-1] * n[l])
梯度的数值逼近:
- 函数 在 点的梯度可以表示为:
梯度检验:
-
将代价函数 表示为 。
-
由 计算 :
-
由 得 。
-
-
由反向传播 得到 。
-
计算 和 的欧式距离比较二者相似度。
关于梯度检验的注记:
- 不要在整个训练过程中都进行梯度检查,仅仅作为 debug 使用。
- 如果梯度检查出现错误,找到对应出错的梯度,检查其推导是否出现错误。
- 注意不要忽略正则化项,计算近似梯度的时候要包括进去。
- 梯度检查时关闭 Dropout,检查完毕后再打开 Dropout。
- 随机初始化时运行梯度检查,经过一些训练后再进行梯度检查(不常用)。
优化算法
Mini-batch
Mini-batch 梯度下降:
Batch Gradient Descent 批梯度下降法
Mini-batch Gradient Descent Mini-batch 梯度下降法
-
如果样本数量 很大,例如达到百万数量级,训练速度往往会很慢,因为每次迭代都要对所有样本进行进行求和运算和矩阵运算。
-
我们可以把 个训练样本分成若干个子集,称为 Mini-batches,这样每个子集包含的数据量就小了,然后每次在单一子集上进行神经网络训练,速度就会大大提高。这种梯度下降算法叫做 Mini-batch 梯度下降法。
-
符号 , :第 组 Mini-batch。
-
流程:
for t in range(T): Forward Propagation Compute Cost Function Backward Propagation W := W − alpha * dW b := b − alpha * db
- 对于 Mini-batch 梯度下降法,一个 epoch 会进行 T 次梯度下降。
- Mini-batch 可以进行多次 epoch,每次迭代,最好将总体训练数据重新打乱、重新分成 T 组。
理解 Mini-batch 梯度下降:
Stochastic Gradient Descent 随机梯度下降
- 使用 Batch Gradient Descent,随着迭代次数增加,代价函数是不断减小的;使用 Mini-batch Gradient Descent,随着在不同的 Mini-batch 上迭代训练,其代价不是单调下降,而是受类似噪音的影响,出现振荡,但整体的趋势是下降的。
- 当 Mini-batch 的大小为 时,即为 Batch Gradient Descent;当 Mini-batch 的大小为 时,即为 Stochastic gradient descent。Mini-batch 的大小推荐设置为 。
- Mini-batch 最终会在最小值附近来回波动,难以真正达到最小值处,而且在数值处理上不能使用向量化的方法来提高运算速度。
指数加权平均
指数加权平均:
Exponentially Weighted Averages 指数加权平均
- 公式:值决定了指数加权平均的天数,近似表示为:例如 表示将前 天进行指数加权平均。
理解指数加权平均:
v = 0
while (true):
get next theta
v := beta * v + (1 - beta) * theta
指数加权平均的参数修正:
-
开始时我们设置 ,所以初始值会相对小一些,直到后面受前面的影响渐渐变小,趋于正常。
-
可以在每次计算完 时,作如下处理:
其他优化算法
动量梯度下降:
Gradient Descent With Momentum 动量梯度下降
-
在每次训练时,对梯度进行指数加权平均处理,然后用得到的梯度值更新权重 和常数项 。
-
公式:
-
超参数:、。
RMSprop:
Root Mean Square Prop (RMSprop) 均方根传递
-
公式:
-
为了避免 RMSprop 算法中分母为零,通常可以在分母增加一个极小的常数 。
Adam 优化算法:
Adaptive Moment Estimation 自适应矩阵估计
-
结合了动量梯度下降算法和 RMSprop 算法。
-
公式:
-
超参数:、、、。
学习率衰减:
Learning Rate Decay 学习率衰减
-
随着迭代次数增加,令学习因子 逐渐减小。
-
公式:
- 、 是可调参数, 是训练次数, 是 Mini-batch 数量。
局部最优化
局部最优化问题:
Local Optima 局部最优化
Saddle Point 鞍点
Plateau 停滞区
- 大部分梯度为零的 "最优点" 并不是这些凹槽处,而是马鞍状的鞍点 (Saddle Point)。
- 梯度为零并不能保证都是极小值 (Convex),也有可能是极大值 (Concave)。
- 类似马鞍状的停滞区 (Plateaus) 会降低神经网络学习速度,但是由于随机扰动,梯度一般能够离开鞍点 (Saddle Point),继续前进,只是在停滞区 (Plateaus) 上花费了太多时间。
总结
-
"+" 表示损失的最小值。
-
梯度下降 (Gradient Descent) 与随机梯度下降 (Stochastic Gradient Descent, SGD):
- 梯度下降:
X = data_input Y = labels parameters = initialize_parameters(layers_dims) for i in range(0, num_iterations): a, caches = forward_propagation(X, parameters) cost = compute_cost(a, Y) grads = backward_propagation(a, caches, parameters) parameters = update_parameters(parameters, grads)
- 随机梯度下降:
X = data_input Y = labels parameters = initialize_parameters(layers_dims) for i in range(0, num_iterations): for j in range(0, m): a, caches = forward_propagation(X[:,j], parameters) cost = compute_cost(a, Y[:,j]) grads = backward_propagation(a, caches, parameters) parameters = update_parameters(parameters, grads)
- 对于随机梯度下降,在更新梯度之前,只使用 1 个训练样例。
- 当训练集大时,随机梯度下降可以更新的更快,但是这些参数会向最小值摆动而不是平稳地收敛。
-
小批量梯度下降 (Mini-batch):
- 如果既不使用整个训练集,也不使用一个训练示例,来执行每次更新,则通常会得到更快的结果。
- 小批量梯度下降通常会胜过梯度下降或随机梯度下降,尤其是训练集较大时。
-
动量梯度下降 (Gradient Descent With Momentum):
- 传统的梯度下降在梯度下降过程中,振荡较大,每一点处的梯度只与当前方向有关,产生类似折线的效果,前进缓慢。
- 动量梯度下降对梯度进行指数加权平均,使当前梯度不仅与当前方向有关,还与之前的方向有关。这样处理让梯度前进方向更加平滑,减少振荡,能够更快地到达最小值处。
- 如果动量梯度下降的参数 ,则它变为没有冲量的标准梯度下降。 越大,更新越平滑,我们对过去的梯度的考虑也更多。
-
RMSprop:
- 对于 和 ,如果哪个方向振荡大,就减小该方向的更新速度,从而减小振荡。
-
Adam:
- 结合了动量梯度下降和 RMSProp 的优点。
超参数 批标准化 编程框架
超参数调试
调试过程:
- 深度神经网络需要调试的超参数包括:
- 学习因子 :通常来说是需要重点调试的超参数。
- 动量梯度下降因子 :通常来说重要程度仅次于 。
- Adam 算法参数:、、。
- 神经网络层数。
- 各隐藏层神经元个数:通常来说重要程度仅次于 。
- 学习因子下降参数 。
- 批量训练样本包含的样本个数 :通常来说重要程度仅次于 。
- 通常做法:
- 随机化选择参数,尽可能地得到更多种参数组合。
- 为得到更精确的最佳参数,放大表现较好的区域,对选定的区域进行由粗到细的采样。
为超参数选择合适的范围:
-
对于某些超参数,如神经网络层数、各隐藏层神经元个数,取值只能是正整数,可以进行随机均匀采样。
-
对于另一些参数,如学习因子 :
-
设待调范围为 ,如果随机均匀采样,则 的采样点分布在 ,但是 的最佳取值更可能出现在 。
-
因此可以采用取对数的方法,线性区间是 ,对数区间是 :
m = np.log10(a) n = np.log10(b) r = np.random.rand() r = m + (n - m) * r r = np.power(10, r)
-
-
除 外, 也不能随机均匀采样,因为 越接近 ,则对 的影响越大。
超参数训练的实践:
Babysitting One Model 只对一个模型进行训练
Training Many Models In Parallel 对多个模型同时进行训练
批标准化
标准化网络中的激活函数:
Batch Normalization 批标准化
-
批标准化可以让调试超参数更加简单,让模型可接受的超参数范围更大。
-
在《标准化输入》一节对输入数据进行标准化,同样,可以对 层的输入,即 或 标准化:
- 是单个 Mini-batch 包含样本个数。
- 是为了防止分母为 。
-
上式使得 均值为 ,方差为 ,但是实际并不希望这样,于是:
- 和 同 和 一样是可以通过梯度下降等算法求得的参数。
- 从激活函数的角度来讲,如果 的均值为 ,处于激活函数的线性区域,不利于训练好的非线性神经网络。
将 Batch Norm 应用于神经网络:
-
整体流程:
-
在 BN 中,参数 可以删去,需要使用梯度下降求的参数只有 、 和 。
Batch Norm 为什么凑效:
Covariate Shift 列分布差异
- Batch Norm 减少了各层 、 之间的耦合性,让各层更加独立。
- Batch Norm 起到了轻微正则化的作用。
Batch Norm 在测试集上的使用:
- 在训练时 和 是通过单个 Mini-batch 中的 个样本求得的,测试时,如果只有一个样本,求其均值和方差是没有意义的,这就要对 和 进行估计。
- 方法一:将所有训练集放入最终的神经网络模型中,将每个隐藏层计算得到的 和 直接作为测试过程的 和 来使用。实际应用中一般不使用这种方法。
- 方法二:对于第 层隐藏层,考虑所有 Mini-batch 在该隐藏层下的 和 ,然后用指数加权平均的方式来预测得到当前单个样本的 和 。
多分类
Softmax 回归:
-
一般使用 Softmax 回归处理多分类问题,对于一个长度为 的任意实数向量,Softmax 可以把它压缩为一个长度为 的、取值在 区间的实数矢量,且矢量中各元素之和为 ,因此 Softmax 的输出可以作为概率。
-
代表种类个数。
-
神经网络输出层有 个神经元,每个神经元的输出 依次对应属于该类的概率。
-
所有的 组成 , 维度为 。
训练一个 Softmax 分类器:
- 对于 的多分类,损失函数为:代价函数为:输出层反向传播的计算:
编程框架
编程框架:
- PaddlePaddle / Tensorflow / Torch
Tensorflow:
import numpy as np
import tensorflow as tf
cofficients = np.array([[1.],[-10.],[25.]])
w = tf.Variable(0,dtype=tf.float32)
x = tf.placeholder(tf.float32,[3,1])
cost = x[0][0]*w**2 + x[1][0]*w + x[2][0]
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
print(session.run(w))
for i in range(1000):
session.run(train, feed_dict=(x:coefficients))
print(session.run(w))
'''
# 另一种写法
with tf.Session() as session:
session.run(init)
print(session.run(w))
'''
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性