Welcome to MyBlog!
本文所有截图和文字均借鉴于:Coursera
1 如何设置你的训练集/开发集/测试集
在训练一个神经网络时, 你必须做出许多决定, 例如你的神经网络将会有多少层啊 并且每一层中包含多少个隐藏神经元啊, 学习速率是多少啊, 还有每一层你想用什么激活函数啊 当你开始一个新的应用时, 你几乎不可能一次性就正确地猜到上面提及的, 以及未提及的超参数的准确数值 因此在实际应用中 机器学习是一个**高度迭代的过程**。
机器学习的应用是相当反复的迭代的过程, 你只需要将这个循环进行许多次, 就有希望能为你的应用中的网络找出好的参数, 所以有一件事能决定你能多快地取得进展, 那就是你进行迭代过程时的效率, 而恰当地将你的数据集分为训练集, 开发集和测试集让你的迭代效率更高
1.1 比例
当样本个数只有100、1000、10000时,被广泛认为的最佳比例是60/20/20%。
但是在大数据时代,当你有100万个训练样本时,可能只需要1万个用作开发集和测试集就足够了。
1.2 确保开发集和测试集中的数据分布相同
你需要用开发集对许多不同的模型进行评估, 费尽全力改善模型在开发集上的性能, 如果开发集和测试集的数据分布相同就很方便, 但是因为深度学习算法对训练数据量需求巨大, 我能看到一种趋势是用各种有创意的办法, 比如爬取网页, 来获得比其它途径大得多的训练集, 即使这会带来一些代价, 也就是训练集的数据分布, 与开发集和测试集的数据分布不同, 但你只需要遵守这个经验法则, 你的算法进步速度就会更快
2 bias(偏差)和variance(方差)
2.1 偏差和方差的区别
偏差:预测值或者估计值期望与真实值期望之间的差距。
方差:预测结果的分布情况/分布范围/离散程度。
偏差:评价对象时单个模型,期望输出和真实标记的差别。
方差:评价对象时多个模型,表示多个模型差异程度。
以上图为例:
- 左上的模型偏差最大,右下的模型偏差最小;
- 左上的模型方差最小,右下的模型方差最大;
2.2 过拟合和欠拟合
高方差:你的训练集误差是1%,而对于开发集误差 为了便于讨论 我们假设是11% 在这个例子里 你的模型对训练集处理得非常好 但是相对来说,开发集处理得就有些不尽如人意 所以这可能是在处理训练集时过拟合了
高偏差:假设训练集的误差是15%,假设你的开发集误差是16%, 在这种情况下,我们假设人工识别误差是0% 因为人可以直接看到这些图片,并判断出这是否是一只猫, 所以看上去,这个算法在训练集上的表现并不尽如人意 如果它并未将训练集数据处理得很好 这就是欠拟合。
3 机器学习的基本准则
high bias: bigger network、train longer、更高级的优化算法、更换神经网络结构
high variance: more data、正则化?、更适合的神经网络结构
只要你能不断扩大所训练的网络的规模 只要你能不断获得更多数据 虽然这两点都不是永远成立的 但如果这两点是可能的 那扩大网络几乎总是能够 减小偏差而不增大方差 只要你用恰当的方式正则化的话 而获得更多数据几乎总是能够 减小方差而不增大偏差 所以归根结底 有了这两步以后 再加上能够选取不同的网络来训练 以及获取更多数据的能力 我们就有了能够且只单独削减偏差 或者能够并且单独削减方差 同时不会过多影响另一个指标的能力 我认为这就是诸多原因中的一个 它能够解释为何深度学习在监督学习中如此有用
4 regularization正则化
4.1 什么是L2正则化
在神经网络中 你有一个代价函数 它是你所有参数的函数 包括w[1] b[1]到w[L] b[L] 这里大写的L是神经网络的层数 因此 代价函数是m个训练样本上 的损失之和 至于正则化 再加上lambda/2m 乘以所有参数W的范数的平方之和 这里W是你的参数矩阵 这里矩阵范数的平方定义为 对于i和j 对矩阵中每一个元素的平方求和
L2正则化也被称为权重衰减(表现在目标函数/参数更新)
4.2 为什么正则化可以防止过拟合(减少方差问题)
如果不加此项,模型必定倾向于最小化损失函数J(θ)
,这么一来就很可能发生overfitting。引入该项后,如果模型过于复杂,该项的次数(degree)也更高,引发的惩罚(penalization)值也更大,由此抑制了模型的过度复杂化,λ也被称为惩罚因子。
λ过小,则对“防止过拟合”几乎无影响。λ过大,则使损失函数前半部分的权重大大降低,试想如果λ接近无限大,最终的结果是所有的θ都接近0,因此需要选择适当的λ。
举一个极端的例子,当lanbda非常大的时候,神经网络的许多神经节点将被弱化,看起来就像一个不容易过拟合的小型网络。
4.3 随机失活正则化(丢弃发dropout)
4.4 其他防止过拟合的方法
1 数据集扩充:比如水平翻转,随机裁剪、随机扭曲、随机放大来变化图片(廉价的方式)
2 早终止法:
5 标准化处理
如果你对左图的那种代价函数使用梯度下降法 那可能必须使用非常小的学习率 因为假如从这里开始 梯度下降法需要经历许多步 反复辗转 才能好不容易终于挪到这个最小值 而如果等值线更趋近于圆形 那无论从何开始 梯度下降法几乎都能直接朝向最小值而去 你可以在梯度下降中采用更长的步长 而无需像左图那样来回摇摆缓慢挪动 当然在实践中 w是一个高维向量 把它画在二维空间中可能无法正确传递出高维中的感觉 但大体上的感觉是你的代价函数会更圆 优化过程更容易进行 因为各种特征的尺度会比较接近
6 梯度 消失/爆发
当训练神经网络时我们会遇到一个问题 尤其是当训练层数非常多的神经网络时 这个问题就是梯度的消失和爆炸 它的意思是当你在训练一个深度神经网络的时候 损失函数的导数或者说斜率 有时会变得非常大 或者非常小甚至是呈指数级减小 这使训练变得很困难
针对此问题的**部分**解决方法:虽然不能完全解决它 但帮助很大 该方法就是更好 更细致地随机初始化你的神经网络
7 梯度检测
导数的正式定义 就是对于很小的𝜀 计算[f(𝜃+𝜀)-f(𝜃-𝜀)]/(2𝜃) 就是对于很小的𝜀 计算[f(𝜃+𝜀)-f(𝜃-𝜀)]/(2𝜃)
原因:对于一个非零的𝜀值 你可以证明这个近似的误差 在𝜀平方这个阶上 𝜀是个很小的数 如果𝜀是0.01 就像这里 那么𝜀平方就是0.0001 这个大O记号就表示误差就是某个常数乘以这个 这就是我们的近似误差 这个例子中的大O的常数恰好就是1 相比而言 如果我们用这边的另一个公式 误差就在𝜀这个阶上 当𝜀是一个小于1的数时 𝜀就比𝜀平方大很多 这也就是为什么 这个公式不如左边这个公式精确 这也就是为什么我们做梯度检验时采用双侧差值 你计算f(𝜃+𝜀)-f(𝜃-𝜀)再除以2𝜀 而不使用这个不够精确的单侧差值
怎么进行双侧差值梯度检测
从W1,B1,一直到,WL,bL 要实现梯度检查算法 首先要把你的所有参数 重新拼成一个巨大的参数向量θ 你要把W矩阵转化成一个向量 把所有的W矩阵都转化成向量 然后把他们首尾相接拼在一起 成为一个巨大的参数向量θ 之前代价函数J是所有W和b的函数 经过向量转化后它变成了θ的函数 W和b按照同样的顺序转化后 你也可以把dW[1],dB[1]等等参数都转化成 和θ的维度相同的向量dθ 和之前一样,把dW[1]转化成向量 db[1]已经是向量 把所有的dW矩阵转化成向量 记住dW[1]和W[1]的维度相同 db[1]和b[1]的维度相同 经过相同的矩阵转化和向量拼接之后 你就把所有的微分也转化成 一个参数向量dθ dθ和θ的维度一样
在实际中 我取ε为10的负7次方 这样 如果这个式子的结果 小于10的负7次方 那就认为计算正确 它表示你的微分近似是对的 因为(误差)很小 如果该式的结果在10的负5次方的量级的话 我会很仔细地检查一遍 有可能式子也是对的 但我会再三检查这个向量的每个分量 确定没有某个分量很大 如果某个分量很大的话 那么可能你的式子里有错误了 如果左面的式子在10的负3次方的量级的话 我觉得你一定要检查代码 它很可能有错误 它的结果应该远远小于10的负3次方 如果(某个分量)大于10的负3次方 我很担心你的代码有错误
梯度检测的使用原则如下:
- 不要在训练中使用梯度检查 而仅仅在调试时
- 如果一个算法没有通过梯度检测 你需要检查它的组成 检查每一个组成成分 尝试找出漏洞 我的意思是 如果d(θapprox)与dθ差距很大的话 我会这么做 检查不同的i值 看看哪些 d(θapprox)的值 与dθ的值差距最大
- 如果使用了正则化,别忘了你的正则项
- 梯度检验不能与随机失活一起使用,因为:因为在每一次的迭代中 随机失活(dropout)将随机消除 隐藏层单元的不同子集 在使用随机失活(dropout) 进行梯度下降的过程中 并不存在一个容易计算的代价函数J 随机失活(dropout)可以被视为 对于代价函数的优化 但是这个代价函数的定义是 在每一次迭代中 对所有 非常大的可消除节点集进行求和 所以这个代价函数是很难计算的 你只需要对代价函数进行抽样 在那些使用随机失活(dropout)的集合中 每次消除不同的随机集合 所以使用梯度检验来检查 包含了随机失活(dropout)的运算是很困难的
- 你对于梯度下降的使用是正确的 同时w和b在随机初始化的时候 是很接近0的数 但随着梯度下降的进行 w和b有所增大 也许你的反向传播算法 在w和b接近0的时候是正确的 但是当w和b变大的时候 算法精确度有所下降 所以虽然我不经常使用它 但是你可以尝试的一个方法是 在随机初始化的时候 运行梯度检验 然后训练网络一段时间 那么w和b 将会在0附近摇摆一段时间 即很小的随机初始值 在进行几次训练的迭代后 再运行梯度检验