欢迎来到这门课程 这门课程将从实际应用的角度介绍深度学习
也许你现在已经学会了如何实现一个神经网络
本周我们将学习 在实际应用中如何使你的神经网络高效工作
本周我们将学习⏎在实际应用中如何使你的神经网络高效工作
这些方法包括超参数调整，数据准备
再到如何确保你的优化算法运行得足够快
以使得你的学习算法能在合理的时间内完成学习任务
在第一周我们首先要介绍一些机器学习问题,
然后我们将讨论正则化
我们也会介绍一些小技巧
这些技巧能够确保你能正确地实现你的神经网络
那我们开始吧
在你考虑如何设置你的训练集/开发集/测试集时
如果能够做出一个好的选择将会帮助你快速地
建立一个高性能的神经网络
在训练一个神经网络时 你必须做出许多决定
例如你的神经网络将会有多少层啊
并且每一层中包含多少个隐藏神经元啊
学习速率是多少啊
还有每一层你想用什么激活函数啊
当你开始一个新的应用时
你几乎不可能一次性就正确地猜到上面提及的
以及未提及的超参数的准确数值
因此在实际应用中 机器学习是一个高度迭代的过程
在这个过程中 你经常以一个想法为起点
例如你想建立一个具有一定层数
一定数量的隐藏神经元 或许是基于某个特定数据集的或者满足其他的需求神经网络
然后你只要将你的想法转换为代码 并运行你的代码来尝试实现它
在你运行并且实验之后 你会得到一个结果
这个结果会告诉你这个特定的网络 或者说这个特定的配置执行得好不好
然后根据这个结果
你可能会改进你的想法 并改变你的选择
而且你也许会为了尝试找出一个越来越好的神经网络 而不断迭代
如今深度学习在许多领域获得成功
从自然语言处理到计算机视觉到
语音识别再到许多基于结构化数据的应用
结构化数据包括很多东西 包括广告 网页搜索
而网页搜索不只包括搜索引擎 还包括例如购物网站等
所有的那些 想要在你于搜索栏中输入关键词后
返回高质量搜索结果的网站
再到计算机安全 后勤物流 比如计算出应该让司机
在何处装卸货物 再到其他许多方面
所以我现在能看到 一个经验丰富的自然语言处理研究员
尝试去做一些计算机视觉相关的研究
或者是一个在语音识别方面 经验丰富的研究员可能会
开始尝试去做一些与广告相关的研究
亦或是具有安全背景的人去尝试做物流相关的研究
我能看到从一个研究领域 或应用领域中的直觉
通常是并不能直接套用到其它的领域的
最好的选择可能取决于你所拥有的数据量
输入数据的特征个数 也取决于你的计算机配置
比如你是在GPU上训练还是在CPU上训练
以及GPU和CPU和具体配置是怎样的 还有很多其它因素
所以我认为对很多应用来说 想猜准超参数是几乎不可能的
即使是经验非常丰富的深度学习从业者都发现
想一次就猜中最优的超参数是几乎不可能的
所以目前 机器学习的应用是相当反复的 迭代的过程
你只需要将这个循环进行许多次
就有希望能为你的应用中的网络找出好的参数
所以有一件事能决定你能多快地取得进展
那就是你进行迭代过程时的效率
而恰当地将你的数据集分为训练集 开发集和测试集
就能让你的迭代效率更高
假设这是你的训练数据 我们把它画成一个大矩形
那么传统的做法是你可能会从所有数据中
取出一部分用作训练集
然后再留出一部分作为hold-out交叉验证集
这个数据集有时也称为开发集
为了简洁 我就把它称为"dev set" 不过
这些不同的术语大致指代的是同一个东西
再接下来你可能会从最后取出一部分用作测试集
整个工作流程是首先你不停地用训练集来训练你的算法
然后用你的开发集或说hold-out交叉验证集来测试
许多不同的模型里哪一个在开发集上效果最好
当这个过程进行的时间够长之后
你可能想评估一下你最终的训练结果
你可以用测试集对结果中最好的模型进行评估
这样以使得评估算法性能时不引入偏差
在上一个时代的机器学习中 通常的分割法是
训练集和测试集分别占整体数据70%和30%
也就是人们说的 70/30训练测试分割
如果你明确地设定了开发集 那比例可能是60/20/20%
也就是测试集占60% 开发集20% 测试集20%
数年以前这个比例被广泛认为是
机器学习中的最佳方法
如果你一共只有100个样本
也许1000个样本 甚至到1万个样本时
这些比例作为最佳选择都是合理的
但是在这个大数据的时代 趋势可能会变化
你可能有多达100万个训练样本 而开发集
和测试集在总体数据中所占的比例就变小了
这是因为 回想开发集存在的意义是用来
测试不同的算法并确定哪种最好
所以开发集只要足够大到
能够用来在评估两种不同的算法
或是十种不同的算法时快速选出较好的一种
达成这个目标可能不需要多达20%的数据
所以如果你有100万个训练样本
可能开发集只要1万个样本就足够了
足够用来评估两种算法中哪一种更好
与开发集相似 测试集的主要功能是
对训练好的分类器的性能 给出可信度较高的评估
同样如果你可能有100万个样本 但是只要1万个
就足够评估单个分类器的性能
能够对其性能给出比较准确的估计了
以此为例 如果你有100万个样本
而只需要1万个用作开发集 1万个用作测试集
那么1万个只是100万个的百分之一
所以你的比例就是98/1/1%
我还看见过一些应用
这些应用中样本可能多于100万个
分割比率可能会变成99.5/0.25/0.25%
或者开发集占0.4% 测试集占0.1%
所以总结起来 当设定机器学习问题时
我通常将数据分为训练集 开发集和测试集
如果数据集比较小 也许就可以采用传统的分割比率
但如果数据集大了很多 那也可以使开发集
和测试集远小于总数据20% 甚至远少于10%
更具体的确定开发集和测试集大小的准则
我们将在这门专项课程后面的时间中讲解
当前的深度学习中还有一个趋势是
有越来越多的人的训练集与测试集的数据分布不匹配
假设说你在构建一个应用 允许用户上传大量图片
你的目标是找出猫的图片再展示给用户
也许因为你的用户都是爱猫之人
你的训练集可能来自网上下载的猫的图片
而开发集和测试集则包含用户用应用上传的图片
所以 一边是你的训练集可能有很多从网上爬取的图片
另一边是 开发集和测试集中有许多用户上传的图片
你会发现许多网页上的图片都是高分辨率
专业制作过 构图也很漂亮的猫的图片
而用户上传的图则相对比较模糊
分辨率低 用手机在更加随意的情况下拍摄的
所以这可能就造成两种不同的分布
在这种情况下我建议的经验法则是
确保开发集和测试集中的数据分布相同
我们也会详细讲解这个准则 原因是
你需要用开发集对许多不同的模型进行评估
费尽全力改善模型在开发集上的性能
如果开发集和测试集的数据分布相同就很方便
但是因为深度学习算法对训练数据量需求巨大
我能看到一种趋势是用各种有创意的办法
比如爬取网页
来获得比其它途径大得多的训练集
即使这会带来一些代价 也就是训练集的数据分布
与开发集和测试集的数据分布不同
但你只需要遵守这个经验法则
你的算法进步速度就会更快
在这门专项课程稍后的时间内
我也会对这条经验法则进行更详细的解释
最后 即使没有测试集也许也是可以的
回想一下 测试集的目的是给你一个无偏估计
来评价你最终所选取的网络的性能
但如果你不需要无偏的估计的话
没有测试集也许也没有问题
所以当你只有开发集而没有测试集的时候
你所做的就是用训练集尝试不同的模型结构
然后用开发集去评估它们 根据结果进一步迭代
并尝试得到一个好的模型
因为你的模型拟合了开发集中的数据
所以开发集不能给你无偏的估计
但如果你不需要无偏估计的话也许也完全无妨
在机器学习的世界中如果你只有训练集
和开发集 而没有单独的测试集的话
大多数人会将训练集就称为训练集
而把开发集称为测试集
但是它们实际上做的事情是
把测试集当成了hold-out交叉验证集
这种提法对术语的使用可能并不完全准确
因为测试集上会发生过拟合现象
所以如果一个团队告诉你说只有训练集和测试集
我会小心 想他们是否其实只有训练集和开发集
因为他们的模型是在测试集上过拟合
从文化角度看 想改变团队的用语可能比较难
不能让所有人都把训练和测试集称为训练和开发集
即使从我的角度认为 把它们称为训练集
和开发集 在用语上是更准确的
况且如果不需要模型性能的无偏估计的话
这样的做法也是可以接受的
所以建立好训练 开发 测试集 你会迭代得更快
而且你还能更高效地测量算法存在的偏差和方差
然后就能更高效的选用适当的方法来改进算法
我们将在下一个视频中讨论这个话题